API: CIOT (Operações de Transporte)

Crie, valide e emita o CIOT em uma única chamada, ou em etapas.

Visão geral

Toda a tela de CIOT também está disponível por API. Você pode enviar a operação completa (contratantes, veículos, pagamentos e documentos) em uma única requisição e, opcionalmente, rodar a validação e a emissão na ANTT no mesmo passo.

Escopo de operações suportadas

A API atende operações de Lotação e Fracionada nas seguintes modalidades de contratação:

  • Frota própria — quando a empresa transporta carga com veículos próprios.
  • TAC autônomo — transportador autônomo de carga.
  • ETC contratado — empresa de transporte rodoviário de carga contratada.
  • ETC equiparado a TAC — ETC tratado como TAC para fins de pagamento.

Autenticação

Use os headers X-FreteFlow-Key (formato prefix.secret) e X-FreteFlow-Signature (HMAC-SHA256 do body cru com o segredo da chave). Veja Autenticação para detalhes.

Escopos necessários

read para GET; write para POST/PATCH/DELETE.
POST/api/public/v1/ciot/operationsAuth: API key

Cria a operação completa. Body principal:

CampoTipoDescrição
external_idstringIdentificador no seu sistema (vai para os logs).
tipo_operacaoreqenumlotacao | fracionada
freight_iduuidVincular a um frete já existente no FreteFlow.
contratado_cpf_cnpjreqstringCNPJ/CPF do transportador.
contratado_rntrcreqstringRNTRC do transportador.
contratado_tipoenumTAC | ETC | CTC. Define quais regras de validação se aplicam (titular do pagamento, limite de adiantamento, validade).
equiparado_tacbooleanMarque true quando o contratado for ETC equiparado a TAC. Trata o pagamento como TAC autônomo (titular = contratado, adiantamento ≤ 30%).
contratado_nomestringRazão social do transportador (opcional, será buscada na consulta).
origemobject{tipo, uf, codigo_municipio | cep | lat+lng, ...}
destinoobjectMesma estrutura de origem. tipo deve ser igual ao da origem.
distancia_kmnumberCalculado automaticamente se omitido (em alguns casos).
codigo_natureza_cargastringTabela ANTT de natureza da carga.
codigo_tipo_carganumberTabela ANTT de tipo da carga.
peso_carganumberEm kg.
valor_fretenumberValor total do frete.
data_declaracaoISO dateData da declaração (default: hoje).
viagem_inicioISO date|datetime
viagem_fimISO date|datetime
tipo_pagamentoenumpix | conta_corrente | cartao_pre_pago_ip | conta_poupanca | conta_pagamento | outros
indicador_pagamentoenumvista | prazo
contingenciabooleanSe true, exige justificativa_contingencia.
contratantesreqarrayMín. 1. Veja estrutura abaixo.
vehiclesreqarrayMín. 1 veículo. Veja estrutura abaixo.
paymentsarrayItens de pagamento (adiantamento/saldo/parcela/pedagio/ajuste).
documentsarrayNF-e, CT-e ou MDF-e vinculados.
auto_validatebooleanDefault true. Roda validações após criar.
auto_emitbooleanDefault false. Se true, emite na ANTT após validar.

Origem / Destino

O tipo deve ser igual nos dois lados (municipio, cep ou latlng). Conforme o tipo, envie:

  • municipio: uf + codigo_municipio (IBGE) + municipio_nome
  • cep: cep (8 dígitos)
  • latlng: lat + lng + endereco_descricao

Contratantes

CampoTipoDescrição
cpf_cnpjreqstringSomente dígitos.
nomereqstring
rntrcstringQuando contratante é transportador.
papelenumprincipal | solidario | intermediario (default: 1º = principal).
valor_fretenumber
percentualnumber0–100.
observacoesstring

Veículos

CampoTipoDescrição
platereqstringPlaca Mercosul ou padrão antigo.
vehicle_kindreqenumautomotor | implemento | cavalo_trator
rntrcstring
axlesnumber
own_fleetbooleanFrota própria do contratado.

Pagamentos

CampoTipoDescrição
kindreqenumadiantamento | saldo | parcela | pedagio | ajuste
contratante_indexnumberÍndice 0-based em contratantes[]. Alternativa a contratante_cpf_cnpj.
contratante_cpf_cnpjstringResolução pelo CPF/CNPJ do contratante.
tipo_pagamentoreqenum
indicador_pagamentoreqenumvista | prazo
amountreqnumber
due_datereqISO date
banco / agencia / conta / titular_cpf_cnpjstringPara tipos bancários.
codigo_pagamentostringPara PIX/cartão pré-pago.

Documentos fiscais

CampoTipoDescrição
kindreqenumnfe | cte | mdfe
access_keystringChave de 44 dígitos.
number / seriesstring
emitter_cnpj / emitter_namestring
freight_value / cargo_weight_kgnumber

Exemplo completo

bash
curl -X POST https://freteflow.fr.com.br/api/public/v1/ciot/operations \
  -H "X-FreteFlow-Key: ff_pub_xxx.yyy" \
  -H "X-FreteFlow-Signature: sha256=<hmac-sha256(body, secret)>" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "OP-2025-0001",
    "tipo_operacao": "lotacao",
    "contratado_cpf_cnpj": "12345678000190",
    "contratado_rntrc": "12345678",
    "origem":  { "tipo": "municipio", "uf": "SP", "codigo_municipio": "3550308", "municipio_nome": "São Paulo" },
    "destino": { "tipo": "municipio", "uf": "RJ", "codigo_municipio": "3304557", "municipio_nome": "Rio de Janeiro" },
    "valor_frete": 4500.00,
    "peso_carga": 12000,
    "tipo_pagamento": "pix",
    "indicador_pagamento": "vista",
    "chave_pix": "transportador@email.com",
    "contratantes": [
      { "cpf_cnpj": "98765432000111", "nome": "Embarcador Ltda", "papel": "principal", "valor_frete": 4500.00 }
    ],
    "vehicles": [
      { "plate": "ABC1D23", "vehicle_kind": "cavalo_trator", "axles": 6, "rntrc": "12345678" }
    ],
    "payments": [
      { "kind": "adiantamento", "tipo_pagamento": "pix", "indicador_pagamento": "vista",
        "amount": 1500.00, "due_date": "2026-05-20" },
      { "kind": "saldo", "tipo_pagamento": "pix", "indicador_pagamento": "prazo",
        "amount": 3000.00, "due_date": "2026-06-05" }
    ],
    "documents": [
      { "kind": "cte", "access_key": "35260512345678000190570010000000011000000017",
        "freight_value": 4500.00, "cargo_weight_kg": 12000 }
    ],
    "auto_validate": true,
    "auto_emit": true
  }'

Resposta

json
{
  "data": { "id": "0c3e...", "code": "CIOT-0123", "status": "emitido", "codigo_ciot": "...", "protocolo": "..." },
  "validation": { "items": [...], "summary": { "ok": true, "blockers": 0, "warnings": 0 } },
  "emission":   { "ok": true, "codigo_ciot": "...", "protocolo": "...", "mensagem": "..." }
}

Falha na validação

Se auto_emit=true e a validação não passar, a operação fica em status com_divergencia e emission.ok=false com reason="validation_blocked". Corrija via PATCH e chame /emit de novo.

Exemplos por modalidade

As regras de Frota Própria, TAC autônomo, ETC contratado e ETC equiparado a TAC são validadas automaticamente pelo FreteFlow antes da emissão. Os campos extras necessários são contratado_tipo e equiparado_tac, além dos dados bancários do recebedor quando a operação envolve transportador autônomo.

1) Frota própria

Quando a empresa contratante e o contratado são a mesma pessoa jurídica e o transporte é feito com veículos próprios. Os dados bancários do recebedor são dispensados (não há pagamento a terceiro).

json
{
  "external_id": "OP-FP-0001",
  "tipo_operacao": "lotacao",
  "contratado_tipo": "ETC",
  "contratado_cpf_cnpj": "12345678000190",
  "contratado_rntrc": "12345678",
  "origem":  { "tipo": "municipio", "uf": "SP", "codigo_municipio": "3550308" },
  "destino": { "tipo": "municipio", "uf": "RJ", "codigo_municipio": "3304557" },
  "valor_frete": 6000.00,
  "peso_carga": 18000,
  "codigo_natureza_carga": "1001",
  "tipo_pagamento": "pix",
  "indicador_pagamento": "vista",
  "contratantes": [
    { "cpf_cnpj": "12345678000190", "nome": "Minha Empresa Ltda", "papel": "principal", "valor_frete": 6000.00 }
  ],
  "vehicles": [
    { "plate": "ABC1D23", "vehicle_kind": "cavalo_trator", "axles": 6, "rntrc": "12345678", "own_fleet": true }
  ]
}

2) TAC autônomo

Contratado pessoa física com RNTRC TAC. Dados bancários do recebedor são obrigatórios e o titular da conta deve ser o próprio contratado. Adiantamento limitado a 30% do frete.

json
{
  "external_id": "OP-TAC-0001",
  "tipo_operacao": "lotacao",
  "contratado_tipo": "TAC",
  "contratado_cpf_cnpj": "12345678901",
  "contratado_rntrc": "87654321",
  "origem":  { "tipo": "municipio", "uf": "SP", "codigo_municipio": "3550308" },
  "destino": { "tipo": "municipio", "uf": "MG", "codigo_municipio": "3106200" },
  "valor_frete": 5000.00,
  "peso_carga": 15000,
  "codigo_natureza_carga": "1001",
  "tipo_pagamento": "pix",
  "indicador_pagamento": "vista",
  "bank_code": "001",
  "agency": "1234",
  "account_number": "56789-0",
  "cpf_cnpj_owner": "12345678901",
  "payments": [
    { "kind": "adiantamento", "tipo_pagamento": "pix", "indicador_pagamento": "vista",
      "amount": 1500.00, "due_date": "2026-05-20" },
    { "kind": "saldo", "tipo_pagamento": "pix", "indicador_pagamento": "prazo",
      "amount": 3500.00, "due_date": "2026-06-05" }
  ]
}

3) ETC Equiparado a TAC

Pessoa jurídica transportadora equiparada a TAC para fins de pagamento. Aplica todas as regras de TAC (banco obrigatório, titular = contratado, adiantamento ≤ 30%), mas mantém o tipo de viagem padrão.

json
{
  "external_id": "OP-ETC-EQ-0001",
  "tipo_operacao": "lotacao",
  "contratado_tipo": "ETC",
  "equiparado_tac": true,
  "contratado_cpf_cnpj": "12345678000190",
  "contratado_rntrc": "12345678",
  "origem":  { "tipo": "municipio", "uf": "SP", "codigo_municipio": "3550308" },
  "destino": { "tipo": "municipio", "uf": "RJ", "codigo_municipio": "3304557" },
  "valor_frete": 8000.00,
  "peso_carga": 20000,
  "codigo_natureza_carga": "1001",
  "tipo_pagamento": "pix",
  "indicador_pagamento": "vista",
  "bank_code": "237",
  "agency": "0001",
  "account_number": "12345-6",
  "cpf_cnpj_owner": "12345678000190"
}

Códigos de validação relevantes

CampoTipoDescrição
TR05blockerTitular da conta de pagamento deve ser o próprio contratado (TAC ou equiparado).
TR06blockerequiparado_tac=true exige contratado_tipo='ETC'.
PG13blockerPagamento com titular diferente do contratado em TAC ou equiparado.
PG14blockerForma de pagamento 'outros' não permitida para TAC ou equiparado.
PG17blockerAdiantamento acima de 30% do valor do frete (TAC ou equiparado).
PRV02blockerDados bancários (banco, agência, conta) do recebedor obrigatórios para TAC ou equiparado.
PRV03blockercpf_cnpj_owner deve coincidir com o contratado.
PRV04blockercodigo_natureza_carga é obrigatório.

Retificação não suportada

Em alguns casos, a retificação de um CIOT já emitido não é aceita. Para corrigir, cancele e emita um novo.
GET/api/public/v1/ciot/operationsAuth: API key

Lista operações da empresa. Query params: status, tipo_operacao, from, to, limit (máx 200).

GET/api/public/v1/ciot/operations/{id}Auth: API key

Retorna a operação completa, incluindo contratantes, veículos, pagamentos, documentos e últimos 50 eventos.

PATCH/api/public/v1/ciot/operations/{id}Auth: API key

Atualiza campos da operação (apenas em status diferente de emitido/encerrado/cancelado). Os campos id, company_id, codigo_ciot, codigo_verificador, protocolo e status são protegidos.

DELETE/api/public/v1/ciot/operations/{id}Auth: API key

Cancela uma operação ainda não emitida (rascunho, validado, com_divergencia, pronto_emissao). Para operações já emitidas, use o endpoint /cancel abaixo.

POST/api/public/v1/ciot/operations/{id}/validateAuth: API key

Roda novamente as validações declarativas. Atualiza status conforme o resultado.

POST/api/public/v1/ciot/operations/{id}/emitAuth: API key

Valida e emite o CIOT. Resposta 200 em sucesso, 422 quando bloqueado por validação ou rejeitado.

Cancelamento e Encerramento

Operações já emitidas (status = "emitido") seguem dois fluxos finais distintos: cancelamento (anula a operação) ou encerramento (fecha a operação após a conclusão da viagem). Ambos consomem o codigo_ciot existente e registram um evento na timeline da operação.

POST/api/public/v1/ciot/operations/{id}/cancelAuth: API key

Cancela uma operação já emitida. Body:

CampoTipoDescrição
motivoreqstringJustificativa do cancelamento (3 a 500 caracteres). Vai para o registro de eventos e para o órgão emissor.
bash
curl -X POST https://freteflow.fr.com.br/api/public/v1/ciot/operations/0c3e.../cancel \
  -H "X-FreteFlow-Key: ff_pub_xxx.yyy" \
  -H "X-FreteFlow-Signature: sha256=<hmac>" \
  -H "Content-Type: application/json" \
  -d '{ "motivo": "Cliente cancelou a carga antes do embarque" }'
json
{ "ok": true, "mensagem": "Operação cancelada com sucesso" }

Resposta 200 em sucesso. 422 quando a operação não está em status emitido (reason: "invalid_status") ou foi rejeitada (reason: "rejected"). 404 se não pertencer à empresa.

POST/api/public/v1/ciot/operations/{id}/encerrarAuth: API key

Encerra uma operação já emitida após a conclusão da viagem. Body opcional:

CampoTipoDescrição
data_encerramentoISO dateData efetiva do encerramento. Default: agora.
observacoesstringObservações livres (até 500 caracteres).
bash
curl -X POST https://freteflow.fr.com.br/api/public/v1/ciot/operations/0c3e.../encerrar \
  -H "X-FreteFlow-Key: ff_pub_xxx.yyy" \
  -H "X-FreteFlow-Signature: sha256=<hmac>" \
  -H "Content-Type: application/json" \
  -d '{ "data_encerramento": "2026-06-12", "observacoes": "Entrega confirmada pelo destinatário" }'
json
{ "ok": true, "mensagem": "Operação encerrada com sucesso" }

Mesmas regras de status code do /cancel. Após o encerramento a operação fica em status = "encerrado" e não aceita mais alterações.

Ações irreversíveis

Tanto cancelamento quanto encerramento são finais. Não há endpoint para reabrir uma operação. Em caso de erro, será necessário emitir uma nova operação.

Códigos de status

  • rascunho → recém-criado, ainda não validado
  • validado / com_divergencia / pronto_emissao → resultado da validação
  • emitindo → emissão em andamento
  • emitido → CIOT gerado com sucesso
  • rejeitado → ANTT rejeitou; veja mensagem_antt
  • cancelado / encerrado → estados finais