Pular para o conteúdo

API e integrações (CRM, Make, n8n)

Conecte seu CRM ou seu ERP ao Sattotal por meio de chaves de API: sincronize clientes e fornecedores de forma automática e segura

A API do Sattotal permite que outro programa — seu CRM, seu ERP, Make, n8n, Zapier ou um script seu — leia e crie clientes e fornecedores na sua organização sem que ninguém precise importar um CSV à mão. Ela é controlada por chaves de API que o administrador cria em Configurações → API, cada uma com nome próprio e com permissões por recurso, e que podem ser revogadas a qualquer momento. Aqui você encontra o que ela faz, como criar a chave, como chamar a API e como montar uma sincronização com o Make passo a passo.

Conecte seu CRM e suas automações

Qualquer ferramenta capaz de fazer uma requisição HTTP (Make, n8n, Zapier, seu próprio CRM ou ERP) pode ler, criar e atualizar clientes e fornecedores.

Chaves com nome e permissões

Uma chave por integração e, dentro de cada chave, uma permissão por recurso: você pode dar leitura de fornecedores sem dar escrita de clientes. Até 10 chaves ativas por organização.

Sincronização incremental

Com o parâmetro actualizadoDesde só são trazidos os clientes ou fornecedores que mudaram desde a última execução: ideal para um cenário que roda a cada poucos minutos.

Segura por padrão

A chave é mostrada uma única vez e guardada criptografada de forma irreversível. Cada chave só acessa os dados da própria organização e é revogada na hora.

Quem pode usá-la

As chaves são criadas e revogadas pelos administradores da organização. A API está incluída nos planos pagos (Basic, Pro e Enterprise) e durante o período de teste; no plano gratuito a tela mostra um cadeado com a opção de mudar de plano. Uma chave sempre age em nome da organização, não de uma pessoa: ela não herda as permissões de nenhum técnico nem aparece como usuário na equipe.

Como criar uma chave

1

Entre em Configurações → API

No menu lateral, Configurações, cartão «API». Você verá a lista de chaves da sua organização (ativas e revogadas) e um cartão «Como conectar» com a URL base e um exemplo.

2

Clique em «Nova chave»

Dê a ela um nome que identifique a integração («CRM da loja», «Make», «n8n»). Assim, se um dia precisar revogá-la, você saberá qual é.

3

Escolha as permissões

Marque os recursos de que a integração precisar — Clientes, Fornecedores ou os dois — e, para cada um, escolha «Somente leitura» (consultar) ou «Leitura e escrita» (consultar, criar, atualizar e arquivar). Um recurso não marcado é um recurso ao qual a chave não chega. Escolha o mínimo necessário.

4

Copie a chave e guarde na sua ferramenta

A chave completa (começa com sat_) é mostrada uma única vez. Copie com o botão e cole no Make, no n8n ou no seu CRM. Se você a perder, não dá para recuperar: revogue e crie outra.

Configurações → API: lista de chaves e chave recém-criada

CRM Make

sat_Ab3k…x9Zq

Revogar

n8n

sat_Qm7t…p2Lk

Revogada

Chave criada

sat_Ab3k9Zq2Xv8Lp1Mn4Rt7Wy0Cd5Fg6Hj3Kl8Sx9ZqCopiar

Esta é a única vez que você verá a chave completa. Se perdê-la, revogue e crie outra.

Permissões de uma chave

Somente leitura

Pode listar e consultar esse recurso. Qualquer tentativa de criar, alterar ou arquivar recebe um erro 403 com o código PERMISO_DENEGADO e a permissão que está faltando.

Leitura e escrita

Além de consultar, pode criar, atualizar e arquivar nesse recurso. É a permissão de que uma sincronização bidirecional precisa.

As permissões são por recurso

As permissões são por recurso, e isso já apareceu na prática: ao acrescentar os fornecedores, as chaves que já existiam — todas de clientes — NÃO ganharam acesso a eles. Foi preciso marcar. O mesmo valerá para qualquer recurso acrescentado depois: uma integração nunca vê mais do que você concedeu.

Como se autenticar

Envie a chave em cada requisição, de servidor para servidor, no cabeçalho Authorization: Bearer sat_…. Se a sua ferramenta não permitir cabeçalhos de autorização, ela também é aceita no cabeçalho x-api-key. A URL base é a do seu Sattotal seguida de /api/v1 (ela está pronta para copiar na tela de Configurações → API).

GET /api/v1/me
Authorization: Bearer sat_Ab3k9…x9Zq

A API não tem CORS de propósito: ela foi pensada para servidores e ferramentas de automação, não para páginas web nem apps que rodem no navegador dos seus clientes. Uma chave nunca deve chegar a um navegador.

O que dá para fazer (endpoints)

Todas as respostas têm o formato success + data (e pagination nas listagens). Um cliente você pode pedir pelo id ou pelo código (CLI-0007); um fornecedor, só pelo id.

MétodoRotaO que fazPermissão
GET/meDevolve a sua organização e a chave com a qual você está chamando. Use para «testar a conexão» no Make ou no n8n.Qualquer
GET/clientesLista paginada de clientes. Filtros: busqueda, tipo, activo e actualizadoDesde. Sem activo, devolve também os arquivados.Leitura
POST/clientesCria um cliente com as mesmas regras do formulário (identificador fiscal conforme o seu país, sem duplicar identificador fiscal nem e-mail).Escrita
GET/clientes/{id}Devolve um cliente pelo id ou pelo código.Leitura
PATCH/clientes/{id}Atualiza somente os campos enviados. PUT é aceito como sinônimo.Escrita
DELETE/clientes/{id}Arquiva o cliente (activo = false). Não apaga nada e pode ser repetido sem erro.Escrita
GET/proveedoresLista paginada de fornecedores. Filtros: busqueda, activo, tipoProveedor, codigo e actualizadoDesde. Sem activo, devolve também os arquivados.Leitura
POST/proveedoresCria um fornecedor. Só o nome é obrigatório. Se já existir um com o mesmo identificador fiscal ou o mesmo nome, responde 409 com o id do existente.Escrita
GET/proveedores/{id}Devolve um fornecedor pelo id. Aqui o código NÃO serve: veja o aviso mais abaixo.Leitura
PATCH/proveedores/{id}Atualiza somente os campos enviados. A lista de contatos é substituída por inteiro. PUT é aceito como sinônimo.Escrita
DELETE/proveedores/{id}Arquiva o fornecedor (activo = false). Não apaga nada e pode ser repetido sem erro.Escrita
GET/reparacionesLista paginada de ordens, da entrada mais recente para a mais antiga. Filtros: cliente, estado, entradaDesde, entradaHasta e actualizadoDesde.Leitura
GET/reparaciones/{id}Retorna uma ordem pelo id ou pelo número da ordem.Leitura
GET/clientes/{id}/reparacionesAs ordens de um cliente (pelo id ou código dele), com os mesmos filtros.Leitura
GET/clientes/{id}/resumenResumo da atividade do cliente: quantas ordens ele tem (no total, abertas e por status), quanto já foi orçado para ele e quando veio pela última vez.Leitura

Campos do cliente

Os campos são os mesmos da ficha do cliente: nombre e tipo (particular ou empresa) são obrigatórios; nif_cif, apellidos, razonSocial, email, telefono, telefonoSecundario, direccion (calle, numero, piso, codigoPostal, localidad, provincia, pais) e notas são opcionais. O identificador fiscal é salvo em maiúsculas e o e-mail em minúsculas. Na resposta todas as chaves estão sempre presentes, com null quando não há valor, para que o mapeamento de campos na sua ferramenta não quebre. Atenção ao nome: nombre é o primeiro nome (ou o nome fantasia, se for empresa) e o sobrenome vai à parte, em apellidos, no plural.

Campos que a API não reconhece

Se o corpo trouxer uma chave que não existe (por exemplo firstName em vez de nombre, ou apellido no singular em vez de apellidos), a requisição não é recusada, mas esse dado não é salvo. Para não passar despercebido, a resposta ao criar e editar clientes inclui avisos.camposIgnorados com a lista dessas chaves; as do endereço levam o caminho, como direccion.ciudad. Se aparecer, revise o mapeamento de campos da sua integração. Os campos que a própria API devolve (id, codigo, createdAt…) não geram aviso, então você pode ler um cliente, alterá-lo e enviá-lo de volta inteiro.

POST /api/v1/clientes
{ "firstName": "Daniel", "nombre": "Florea", "tipo": "particular" }

201 Created
{
  "success": true,
  "data": { "nombre": "Florea", "apellidos": null, … },
  "avisos": { "camposIgnorados": ["firstName"] }
}

Exemplo: criar um cliente

Requisição

POST /api/v1/clientes
Authorization: Bearer sat_Ab3k9…x9Zq
Content-Type: application/json

{
  "nombre": "Daniel",
  "apellidos": "Florea",
  "tipo": "empresa",
  "razonSocial": "Assista Tech SRL",
  "nif_cif": "RO12345678",
  "codigoPersonalizado": "801",
  "email": "daniel@example.com",
  "telefono": "+40 700 000 000",
  "direccion": { "localidad": "București", "pais": "RO" }
}

Resposta (201)

{
  "success": true,
  "data": {
    "id": "64b0…0001",
    "codigo": "CLI-0042",
    "codigoPersonalizado": "801",
    "codigoVisible": "801",
    "tipo": "empresa",
    "nombre": "Daniel",
    "apellidos": "Florea",
    "razonSocial": "Assista Tech SRL",
    "nif_cif": "RO12345678",
    "email": "daniel@example.com",
    "activo": true,
    "createdAt": "2026-09-18T10:00:00.000Z",
    "updatedAt": "2026-09-18T10:00:00.000Z"
  }
}

Fornecedores

Além dos clientes, a API expõe o catálogo de fornecedores: os mesmos cinco endpoints, os mesmos códigos de erro e a mesma sincronização incremental. É só o catálogo: as compras e as notas fiscais de fornecedor continuam onde já estão, no seu ERP ou no Sattotal.

Campos do fornecedor

Só nombre é obrigatório. Opcionais: codigo, cif, email, telefono, telefonoSecundario, web, direccion (em uma única linha, não é um objeto como em clientes), ciudad, provincia, codigoPostal, pais, contactos, tipoProveedor (general, producto, servicio, logistica ou otro), formaPago, plazoPago (em dias; 0 é à vista), cuentaCliente e notas. Cada contato leva nombre —obrigatório—, cargo, telefono, email e notas; os contatos não têm identificador próprio.

Como os contatos são atualizados

A lista que você envia SUBSTITUI a que havia. Se enviar uma lista vazia, todos os contatos são apagados; se não enviar a chave (ou enviar null), eles ficam como estavam. É o que permite ler um fornecedor, mudar um campo e devolvê-lo inteiro sem efeitos estranhos.

Requisição

POST /api/v1/proveedores
Authorization: Bearer sat_Ab3k9…x9Zq
Content-Type: application/json

{
  "nombre": "Distribuciones Norte",
  "cif": "B12345678",
  "tipoProveedor": "producto",
  "plazoPago": 30,
  "cuentaCliente": "C-4471",
  "contactos": [
    { "nombre": "Ana Ruiz", "cargo": "Ventas", "email": "ana@norte.es" }
  ]
}

Resposta (201)

{
  "success": true,
  "data": {
    "id": "64b0…0009",
    "codigo": "PROV-004",
    "nombre": "Distribuciones Norte",
    "cif": "B12345678",
    "tipoProveedor": "producto",
    "plazoPago": 30,
    "cuentaCliente": "C-4471",
    "contactos": [
      { "nombre": "Ana Ruiz", "cargo": "Ventas",
        "telefono": null, "email": "ana@norte.es", "notas": null }
    ],
    "excluidoRecargoEquivalencia": false,
    "activo": true,
    "createdAt": "2026-09-19T08:00:00.000Z",
    "updatedAt": "2026-09-19T08:00:00.000Z"
  }
}

Os dados bancários não saem pela API

O IBAN e as contas bancárias do fornecedor não são devolvidos nem aceitos, de propósito: se uma chave vazasse, não serviria para a fraude de troca de conta, a mais comum com fornecedores. O que sai é cuentaCliente, que é o SEU número de cliente naquele fornecedor e com o qual um ERP concilia as compras.

O acréscimo de equivalência é somente de leitura

O campo excluidoRecargoEquivalencia é devolvido e você pode reenviá-lo com o mesmo valor (para poder devolver o objeto inteiro), mas alterá-lo pela API responde 400: ele decide se as suas compras naquele fornecedor levam o acréscimo, ou seja, mexe na base de cálculo das suas notas fiscais de compra. Muda-se na ficha do fornecedor. Fora da Espanha não tem nenhum efeito.

O código de fornecedor não localiza

Ao contrário do de cliente, o código do fornecedor (PROV-004) não é único: pode se repetir até dentro da sua própria oficina. Por isso GET /proveedores/{id} só aceita o id. Se o seu ERP guarda apenas o código, use o filtro da listagem: GET /proveedores?codigo=PROV-004, que devolve todos os que combinarem e você decide.

Ordens de serviço (somente leitura)

A API também permite consultar as ordens de serviço: número da ordem, status, datas, o aparelho (tipo, marca, modelo, número de série, IMEI) e o orçamento. É somente leitura: as ordens continuam sendo criadas e mudando de status no Sattotal, onde se assinam o comprovante de entrada e a entrega. A chave precisa do recurso Reparos marcado; chaves de clientes ou fornecedores não chegam a elas.

Campos da ordem

Cada ordem traz numeroFicha, estado, prioridad, ubicacion, averiaDeclarada, diagnostico, as datas do ciclo (entrada, início e fim do diagnóstico e do reparo, aviso ao cliente, entrega e ultimoCambioEstado, quando passou para o status atual), um resumo do cliente (id, codigo, codigoVisible, nombre, apellidos, razonSocial), o aparelho (id, codigo, tipo, marca, modelo, numeroSerie, imei, color), o orçamento (numero, total, estado, fechaEnvio e fechaRespuesta, ou null se não houver), o técnico responsável (só o nome) e plazoEntregaEstimado, o prazo informado ao cliente no comprovante de entrada. Notas internas, assinaturas, fotos, documentos e senhas do aparelho nunca são retornados.

Requisição

GET /api/v1/clientes/CLI-0042/reparaciones?estado=reparado
Authorization: Bearer sat_Ab3k9…x9Zq

Resposta (201)

{
  "success": true,
  "data": [{
    "id": "64b0…0042",
    "numeroFicha": "ORD-2026-0042",
    "estado": "reparado",
    "prioridad": "normal",
    "averiaDeclarada": "No carga",
    "diagnostico": "Conector de carga dañado",
    "fechas": {
      "entrada": "2026-09-20T09:00:00.000Z",
      "finReparacion": "2026-09-22T17:30:00.000Z",
      "entrega": null
    },
    "cliente": { "id": "64b0…0001", "codigoVisible": "801", "nombre": "Daniel" },
    "dispositivo": {
      "tipo": "movil", "marca": "Apple", "modelo": "iPhone 13",
      "numeroSerie": "F2LXX0000", "imei": "356789012345678"
    },
    "presupuesto": { "numero": "PRES-2026-0010", "total": 89.9, "estado": "aprobado" },
    "tecnico": { "nombre": "Andrei Popescu" },
    "plazoEntregaEstimado": "3 días laborables"
  }],
  "pagination": { "total": 1, "page": 1, "limit": 25, "totalPages": 1 }
}

Encontrar o cliente pelo número que está ligando

Se o seu CRM ou o seu PABX abre a ficha do cliente quando entra uma ligação, use GET /clientes?telefono=<número>. A busca é feita no telefone principal e no secundário e ignora como o número está escrito: espaços, hífens, parênteses, o código internacional do seu país (+55 ou 0055) e o 0 inicial. Assim, “(11) 91234-5678” encontra um cliente salvo como “+55 11 91234 5678”. São necessários pelo menos 6 dígitos.

Resumo do cliente para o seu CRM

GET /clientes/{id}/resumen retorna em uma única chamada o que um CRM costuma mostrar na ficha do cliente: totalReparaciones, reparacionesAbiertas (o aparelho ainda está na assistência), porEstado, totalPresupuestado e totalPresupuestosAprobados (na moeda da assistência, que vem em moneda), primeraReparacion, ultimaReparacion e ultimaActividad (a última alteração em qualquer uma das ordens dele). Precisa do recurso Reparos, assim como as ordens.

Requisição

GET /api/v1/clientes?telefono=0722 123 456
→ { "data": [{ "id": "64b0…0001", "codigoVisible": "801", "telefono": "+40 722 123 456", … }] }

GET /api/v1/clientes/801/resumen
{
  "success": true,
  "data": {
    "cliente": { "id": "64b0…0001", "codigoVisible": "801" },
    "moneda": "RON",
    "totalReparaciones": 7,
    "reparacionesAbiertas": 1,
    "porEstado": { "entregado": 6, "en_reparacion": 1 },
    "totalPresupuestosAprobados": 1240.5,
    "ultimaReparacion": "2026-10-02T09:15:00.000Z",
    "ultimaActividad": "2026-10-06T16:40:00.000Z",
    …
  }
}

Sincronizar só o que mudou

Não é preciso trazer tudo em cada execução. Guarde na sua ferramenta a data e a hora da última execução e peça apenas os clientes ou fornecedores modificados desde então com o parâmetro actualizadoDesde. A resposta vem ordenada por data de modificação crescente e com um desempate estável, então você pode paginá-la sem pular registros. Os arquivados também aparecem (com activo = false), para que seu CRM possa refletir o arquivamento.

GET /api/v1/clientes?actualizadoDesde=2026-09-18T10:00:00Z&limit=100&page=1
Authorization: Bearer sat_Ab3k9…x9Zq
1

Primeira execução

Percorra GET /clientes com limit=100 e page=1, 2, 3… até totalPages se esgotar. Guarde a hora de início.

2

Execuções seguintes

Peça GET /clientes?actualizadoDesde=<hora guardada> e processe só o que chegar. Guarde de novo a hora de início desta execução.

3

Vincule, não duplique

Guarde o id do Sattotal junto ao registro do seu CRM. Se ao criar você receber um 409 DUPLICADO, a resposta traz existenteId: vincule esse em vez de criar outro.

Paginação e busca

As listagens aceitam page (a partir de 1) e limit (25 por padrão, 100 no máximo; se pedir mais, é cortado para 100). O campo busqueda procura em nome, sobrenome, razão social, identificador fiscal, e-mail, código e telefone.

Códigos de erro e o que fazer

Todas as respostas de erro trazem success: false, um texto explicativo e um code estável, pensado para decidir por programa. Estes são os que você pode receber:

NO_AUTORIZADO

A chave está faltando, tem um formato que não é o nosso ou não existe. Confira o cabeçalho Authorization.

CLAVE_REVOCADA

A chave era válida, mas um administrador a revogou. Crie uma nova em Configurações → API e atualize na sua ferramenta.

PLAN_REQUERIDO

A organização está no plano gratuito. A API volta a funcionar ao mudar para um plano pago.

PERMISO_DENEGADO

A chave não tem a permissão necessária para essa operação. A resposta indica em ambitoRequerido qual está faltando: crie uma chave com essa permissão.

NO_ENCONTRADO

Não há nenhum cliente nem fornecedor com esse id na sua organização. Os de outras organizações nunca ficam visíveis, e não se distingue «não existe» de «não é seu».

DUPLICADO

Já existe um registro com esse dado: identificador fiscal ou e-mail em clientes; identificador fiscal, nome ou código em fornecedores. A resposta traz campo e existenteId para que você possa vinculá-lo em vez de criar outro.

VALIDACION

Algum campo não passa na validação (ou o JSON está mal formado). Em details vêm o campo e o motivo, igual ao formulário.

IDENTIFICADOR_FISCAL_REQUERIDO

Esse cliente precisa de identificador fiscal: no seu país ele é obrigatório para o tipo de cliente enviado (por exemplo, sempre para empresas).

RATE_LIMIT

Requisições demais. Aguarde os segundos indicados no cabeçalho Retry-After e tente de novo.

API_DESACTIVADA

A API está desativada temporariamente para manutenção. Tente de novo mais tarde.

Limites

120 requisições por minuto por chave (mais do que suficiente para uma sincronização periódica; freia um loop acidental). 10 chaves ativas por organização. As listagens devolvem no máximo 100 registros por página. Se a organização estiver no plano gratuito com a cota mensal esgotada, o cadastro de clientes é bloqueado, igual ao aplicativo.

Passo a passo: sincronizar clientes com o Make

Um cenário típico: a cada 15 minutos, trazer para o seu CRM os clientes e fornecedores novos ou modificados no Sattotal. No n8n o equivalente é com o nó HTTP Request e um nó Schedule.

1

Crie a chave no Sattotal

Configurações → API → Nova chave, permissão «Somente leitura» se você só vai ler, «Leitura e escrita» se também vai criar clientes a partir do CRM. Copie a chave.

2

Módulo HTTP «Make a request»

URL: sua URL base + /clientes. Método GET. Cabeçalho Authorization com o valor Bearer e a sua chave. Marque «Parse response» para trabalhar com o JSON.

3

Teste a conexão

Antes de tudo, execute uma vez uma requisição a /me: se ela devolver a sua organização e o nome da chave, a autenticação está certa.

4

Adicione o filtro incremental

Guarde a data da última execução em um Data store ou em uma variável e passe-a como actualizadoDesde na URL. Agende o cenário a cada 15 minutos.

5

Mapeie os campos para o seu CRM

Itere data[] e mapeie id, codigo, nombre, apellidos, email, telefono, nif_cif e direccion. Guarde o id do Sattotal no seu CRM para atualizar em vez de duplicar.

Para criar clientes a partir do CRM, use outro módulo HTTP com método POST para /clientes e o corpo JSON do cliente. Se receber 409, use existenteId para vincular.

Boas práticas de segurança

Uma chave por integração

Assim você pode revogar uma sem quebrar as outras, e na lista vê quando cada uma foi usada pela última vez.

Nunca no navegador nem em um repositório público

Guarde-a no cofre de credenciais da sua ferramenta (conexões do Make, credenciais do n8n, variáveis de ambiente). Se ela for parar em um repositório ou em um site, considere-a vazada.

Se vazar, revogue e crie outra

A revogação é imediata: a chave antiga passa a receber 401 CLAVE_REVOCADA. Atualize a nova na sua ferramenta e pronto.

Especificação API

A referência técnica completa (rotas, parâmetros, esquemas e códigos de erro) está publicada no formato aberto em /api/v1/openapi.json, sem precisar de chave. Por padrão ela vem em espanhol; adicione ?lang= com o seu idioma para tê-la traduzida (por exemplo /api/v1/openapi.json?lang=pt, ?lang=en ou ?lang=ro). Você pode importá-la no Postman, Insomnia, Make ou n8n para ter todas as chamadas prontas.

Perguntas frequentes

Perdi a chave, posso vê-la de novo?

Não. Ela só é mostrada ao ser criada e depois é guardada de forma irreversível. Revogue-a em Configurações → API e crie outra.

Existem webhooks para o Sattotal avisar meu CRM quando algo muda?

Ainda não. A forma recomendada é consultar periodicamente com o parâmetro actualizadoDesde, que devolve só o que mudou.

Quais dados a API expõe?

Clientes e fornecedores: listar, criar, consultar, atualizar e arquivar. As permissões são por recurso, então uma chave criada antes de os fornecedores existirem não acessa esses dados até que um administrador marque o recurso. Além disso, as ordens de serviço em somente leitura (status, datas, aparelho e orçamento), com permissão própria.

Posso excluir um cliente pela API?

Não, só arquivá-lo (activo = false), igual ao aplicativo. Vale tanto para clientes quanto para fornecedores. Um registro arquivado continua aparecendo na sincronização para que seu CRM o reflita.

A API está no plano gratuito?

Não. Ela está incluída no Basic, Pro e Enterprise e durante o período de teste. No plano gratuito você continua podendo ver e revogar as chaves que criou.

Só chega o sobrenome do cliente. Por que o primeiro nome não é salvo?

Quase sempre é o mapeamento de campos: o primeiro nome vai em nombre e o sobrenome em apellidos. Se a sua ferramenta envia o nome com outra chave (firstName, name, apellido…), a API a descarta e avisa em avisos.camposIgnorados na resposta. Corrija o mapeamento e envie o cliente de novo com um PATCH.

Consigo encontrar o cliente pelo número que está me ligando?

Sim. Chame GET /api/v1/clientes?telefono= com o número do jeito que ele chega: não importa se vem com código internacional, espaços ou hífens, e a busca inclui também o telefone secundário. Com o id dele você pode depois pedir as ordens (/clientes/{id}/reparaciones) e o resumo (/clientes/{id}/resumen).

Quer experimentar você mesmo?

Experimente a Sattotal grátis com dados de exemplo, sem cartão de crédito.