Introdução
Esta API permite criar documentos de venda no XD ERP.
- Criação automática de clientes (com NIF)
- Suporte a "Consumidor Final" (sem NIF)
- Idempotência através de
externalRefúnico - Validação completa de dados antes do processamento
- Suporte a múltiplas linhas de produtos por documento
Endpoint Principal
Content-Type: application/json
Autenticação: API Key via header X-API-Key
Como Obter API Key
A API Key é fornecida pela equipa Brainit após configuração inicial. Entre em contacto através de:
- Email: webmaster@brainit.pt
Campos do Documento
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
docTypeId |
integer | Obrigatório | ID do tipo de documento (ver tabela abaixo) |
serieId |
integer | Obrigatório | ID da série do documento. Definido pela configuração do XD. Solicitar à equipa Brainit o ID correto para sua integração. |
userId |
integer | Obrigatório | ID do utilizador/vendedor no XD que criará o documento. Será fornecido pela equipa Brainit durante a configuração. |
paymentType |
integer | Obrigatório | ID do tipo de pagamento (1=Numerário, 2=MB, 3=Cartão, etc.) |
externalRef |
string | Opcional | Referência externa ÚNICA do pedido (ex: ID da encomenda no seu sistema). Usado para idempotência - se enviar o mesmo externalRef duas vezes, evita duplicação de documentos. Máximo: 50 caracteres |
observations |
string | Opcional | Observações do documento (aparece no PDF). Máximo: 4000 caracteres |
dueDate |
datetime | Opcional | Data de vencimento (formato ISO 8601: YYYY-MM-DDTHH:mm:ss) |
integrationTag |
string | Opcional | Tag de identificação da integração (ex: "WOOCOMMERCE", "AUTO21"). Usado para rastreabilidade e criação automática de clientes |
- Deve ser único para cada pedido
- Se enviar a mesma
externalRefduas vezes, o sistema pode detectar duplicação - Recomendado usar:
[SISTEMA]-[ID](ex: "WC-12345", "AUTO21-5678") - Útil para sincronizar estados entre o seu sistema e o XD
Objeto Cliente
O objeto cliente determina como o cliente será tratado no sistema:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
keyId |
string | Opcional | KeyId do cliente existente no XD. Se fornecido, ignora todos os outros campos e usa os dados do cliente já registado. |
vat |
string | Opcional | Se vazio/null: usa "Consumidor Final" (KeyId=0) Se preenchido: procura cliente existente ou cria novo (se tiver integrationTag) |
name |
string | Obrigatório | Nome do cliente (aparece no documento PDF) |
contactEmail |
string | Opcional | Email do cliente |
phone |
string | Opcional | Telefone do cliente |
address |
string | Opcional | Morada completa |
city |
string | Opcional | Cidade |
postalCode |
string | Opcional | Código postal (formato: 4700-123) |
country |
string | Opcional | Código do país (ISO 2 letras, padrão: PT) |
Quando o campo vat está vazio ou null, o sistema:
- Usa o cliente especial "Consumidor Final" (KeyId=0)
- Preserva os dados fornecidos (nome, email, morada) no documento
- Não cria um novo cliente na base de dados
- Os dados aparecem corretamente no PDF gerado
Linhas do Documento
Array de produtos/serviços do documento (campo lines):
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
reference |
string | Obrigatório | Referência/KeyId do artigo no XD (deve existir previamente no sistema) |
description |
string | Opcional | Descrição personalizada (substitui a descrição padrão do artigo) |
quantity |
decimal | Obrigatório | Quantidade (deve ser > 0) |
unitPrice |
decimal | Obrigatório | Preço unitário (deve ser >= 0) |
taxId |
integer | Opcional | ID da taxa de IVA. Se omitido, usa a taxa padrão configurada no artigo (Tax1) |
discountPercentage |
decimal | Opcional | Percentagem de desconto (0-100) |
Exemplos de Utilização
Cliente COM NIF - Cria/Atualiza Cliente
Quando fornece vat, o sistema procura o cliente. Se não existir e tiver integrationTag, cria automaticamente.
{
"cliente": {
"vat": "PT123456789",
"name": "João Silva",
"contactEmail": "joao@example.com",
"phone": "912345678",
"address": "Rua das Flores, 123",
"city": "Braga",
"postalCode": "4700-123",
"country": "PT"
},
"lines": [
{
"reference": "CAR001",
"description": "Mercedes Classe A 180d",
"quantity": 1,
"unitPrice": 28500.00,
"taxId": 1
}
],
"document": {
"docTypeId": 64,
"serieId": 1,
"userId": 1,
"paymentType": 1,
"observations": "Veículo com garantia de 2 anos. Matrícula: AB-12-CD. Chassi: WDD1234567890",
"dueDate": "2024-12-31T23:59:59"
},
"externalRef": "AUTO21-12345",
"integrationTag": "AUTO21"
}
Consumidor Final - SEM NIF
Para clientes sem NIF, o sistema usa "Consumidor Final" mas preserva os dados no documento.
- Não polui a base de dados com clientes sem NIF
- Dados do cliente aparecem corretamente no PDF
- Ideal para vendas pontuais
{
"cliente": {
"vat": null,
"name": "Maria Costa",
"contactEmail": "maria@example.com",
"phone": "933444555",
"address": "Av. Central, 45",
"city": "Porto",
"postalCode": "4000-123"
},
"lines": [
{
"reference": "PROD001",
"quantity": 2,
"unitPrice": 15.50
}
],
"document": {
"docTypeId": 12,
"serieId": 1,
"userId": 1,
"paymentType": 1
},
"externalRef": "WC-67890"
}
Cliente Existente - Usar KeyId
Se já conhece o KeyId do cliente no XD, use apenas esse campo.
{
"cliente": {
"keyId": "CLI001"
},
"lines": [
{
"reference": "SERV001",
"description": "Revisão Completa",
"quantity": 1,
"unitPrice": 120.00,
"taxId": 3
}
],
"document": {
"docTypeId": 1,
"serieId": 1,
"userId": 1,
"paymentType": 2,
"dueDate": "2024-12-31T23:59:59"
},
"externalRef": "SRV-2024-001"
}
Exemplo Mínimo - Apenas Obrigatórios
Versão minimalista com apenas os campos obrigatórios.
{
"cliente": {
"name": "Cliente Teste"
},
"lines": [
{
"reference": "PROD001",
"quantity": 1,
"unitPrice": 10.00
}
],
"document": {
"docTypeId": 12,
"serieId": 1,
"userId": 1,
"paymentType": 1
}
}
✅ Respostas da API
Sucesso (HTTP 200)
{
"success": true,
"document": "NE A/1",
"message": "Pedido criado com sucesso",
"clientId": "auto21-integration",
"integrationTag": "AUTO21"
}
Erro de Validação (HTTP 400)
{
"success": false,
"message": "Validação falhou",
"errors": [
"Campo 'cliente' é obrigatório",
"Linha 1: quantidade deve ser maior que 0"
]
}
Erro de Autenticação (HTTP 401)
{
"error": "unauthorized",
"message": "API Key obrigatória no header X-API-Key",
"timestamp": "2024-02-16T20:00:00Z"
}
Erro Interno (HTTP 500)
{
"success": false,
"error": "Artigo 'PROD999' não existe no XD"
}
Códigos de Erro Comuns
| HTTP | Erro | Solução |
|---|---|---|
| 401 | API Key missing / inválida | Verificar se o header X-API-Key está presente e correto |
| 400 | Documento sem linhas | Incluir pelo menos 1 linha no array lines |
| 400 | Campo 'cliente.name' é obrigatório | Preencher o campo name do cliente |
| 400 | Artigo 'XXX' não existe | Verificar se a reference existe no XD. Contactar suporte para listar artigos disponíveis |
| 400 | Cliente com VAT 'XXX' não existe | Adicionar integrationTag para permitir criação automática do cliente |
| 400 | Linha X: quantidade deve ser maior que 0 | Garantir que quantity é um valor positivo |
| 500 | Erro ao gravar documento | Erro interno do servidor. Contactar suporte com o externalRef do pedido |
Tipos de Documento
Valores possíveis para o campo docTypeId:
| ID | Tipo | Descrição | Uso Recomendado |
|---|---|---|---|
| 1 | Fatura | Documento fiscal com IVA | Vendas com exigência de fatura |
| 12 | Nota de Encomenda | Documento pré-venda (não fiscal) | Orçamentos, encomendas pendentes |
| 64 | Encomenda | Encomenda de cliente | Pedidos de produtos/serviços |
Endpoint de Compras
Content-Type: application/json
Autenticação: API Key via header X-API-Key
- O
docTypeIddeve ser sempre 15 (Fatura Fornecedor) - O fornecedor deve existir previamente no XD — não há criação automática
- Os artigos devem existir previamente no XD — não há criação automática
- O campo raiz é
fornecedorem vez decliente
Objeto Fornecedor
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
keyId |
string | Obrigatório | KeyId do fornecedor existente no XD. O fornecedor deve existir — não é criado automaticamente. |
name |
string | Opcional | Nome do fornecedor (apenas informativo — os dados reais vêm do XD) |
Campos do Documento (Compra)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
docTypeId |
integer | Obrigatório | Valor fixo: 15 (Fatura Fornecedor). Qualquer outro valor será rejeitado. |
serieId |
integer | Obrigatório | ID da série do documento de compra. Fornecido pela equipa Brainit. |
userId |
integer | Obrigatório | ID do utilizador no XD que registará a compra. |
paymentType |
integer | Obrigatório | ID do tipo de pagamento (1=Numerário, 2=MB, 3=Cartão, etc.) |
dueDate |
datetime | Opcional | Data de vencimento da fatura do fornecedor (ISO 8601: YYYY-MM-DDTHH:mm:ss) |
observations |
string | Opcional | Observações internas do documento |
externalRef |
string | Opcional | Referência externa única (ex: número da fatura do fornecedor). Usado para idempotência. |
Linhas do Documento (Compra)
Idênticas às orders, mas os artigos têm obrigatoriamente de existir no XD:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
reference |
string | Obrigatório | KeyId do artigo no XD. Deve existir previamente — não é criado automaticamente. |
description |
string | Opcional | Descrição personalizada da linha |
quantity |
decimal | Obrigatório | Quantidade (deve ser > 0) |
unitPrice |
decimal | Obrigatório | Preço de custo unitário (deve ser >= 0) |
taxId |
integer | Opcional | ID da taxa de IVA. Se omitido, usa a taxa padrão do artigo (Tax1) |
Exemplos de Utilização
Compra Simples
Fornecedor e artigos existentes no XD. Registo direto da fatura.
{
"fornecedor": {
"KeyId": "AUTO21",
"name": "AUTO21",
"contactEmail": "geral@auto21.pt"
},
"lines": [
{
"reference": "CAR001",
"description": "Mercedes Classe C180d",
"quantity": 1,
"unitPrice": 7500.00,
"taxId": 2
}
],
"document": {
"docTypeId": 15,
"serieId": 1,
"userId": 1,
"paymentType": 1,
"observations": "Veículo com garantia de 3 anos. Matrícula: CC-12-CD. Chassi: WDD1234567890"
},
"externalRef": "AUTO215-20260102"
}
Compra com Data de Vencimento
Fatura a pagamento a 30 dias com observações internas.
{
"fornecedor": {
"KeyId": "AUTO21",
"name": "AUTO21",
"contactEmail": "geral@auto21.pt"
},
"lines": [
{
"reference": "CAR001",
"description": "Mercedes Classe C180d",
"quantity": 1,
"unitPrice": 7500.00,
"taxId": 2
}
],
"document": {
"docTypeId": 15,
"serieId": 1,
"userId": 1,
"paymentType": 9,
"observations": "Veículo com garantia de 3 anos. Matrícula: CC-12-CD. Chassi: WDD1234567890",
"dueDate": "2026-03-31T23:59:59"
},
"externalRef": "AUTO215-20260101"
}
Resposta de Sucesso (HTTP 200)
{
"success": true,
"document": "FTF 1/8",
"message": "Purchase criada com sucesso",
"clientId": "erp-integration",
"integrationTag": "ERP"
}
Erros Específicos de Compras
DocTypeId inválido (HTTP 400):
{
"success": false,
"message": "DocTypeId '51' inválido para purchases. Valor permitido: 15 (Fatura Fornecedor)."
}
Fornecedor não existe (HTTP 500):
{
"success": false,
"error": "Fornecedor não existe no XD"
}
Artigo não existe (HTTP 500):
{
"success": false,
"error": "Artigo 'AUTO13321' não existe no XD"
}
Códigos de Erro Específicos de Compras
| HTTP | Erro | Solução |
|---|---|---|
| 400 | DocTypeId inválido para purchases | Usar obrigatoriamente docTypeId: 15 |
| 500 | Fornecedor não existe no XD | Verificar o keyId do fornecedor. Ao contrário das orders, o fornecedor não é criado automaticamente. |
| 500 | Artigo 'XXX' não existe no XD | Verificar a reference do artigo. Ao contrário das orders, os artigos não são criados automaticamente. |
| 500 | Erro ao gravar compra | Erro interno. Contactar suporte com o externalRef e timestamp da requisição. |
Configuração Inicial
Antes de começar a usar a API, necessita obter os seguintes dados da equipa Brainit:
Dados Fornecidos pela Brainit
- API Key - Chave de autenticação única para sua integração
- userId - ID do utilizador XD que criará os documentos
- serieId - ID da série de documentos a utilizar
- Lista de Artigos - Referências (KeyIds) dos produtos/serviços disponíveis
- Tipos de Documento - IDs dos tipos de documento configurados
- URL Base - Endereço do servidor da API
- Nunca partilhe sua API Key publicamente
- Armazene a API Key de forma segura (variáveis de ambiente, cofres de segredos)
- Use HTTPS em todas as requisições
- Implemente rate limiting no seu lado para evitar sobrecarga
📞 Suporte
Para questões técnicas, configuração ou problemas:
- 📧 Email: webmaster@brainit.pt
- 🕐 Horário: Segunda a Sexta, 9h00 - 18h00
Ao contactar o suporte, forneça sempre:
- O valor do campo
externalRefdo pedido problemático - Código de erro HTTP recebido
- Timestamp aproximado da requisição
- Mensagem de erro completa