← HomeFleetPay / API

Declare a CIOT without a CT-e

Parameters, data structure and responses from the versioned contract.

POST/fiscal/ciot
declararCiotSandbox Base: https://api.fleetpay.site/v1

Technical descriptions are translated from the versioned contract. Original identifiers and JSON are preserved; data examples are omitted.

Registers a Transport Operation with ANTT from the trip, without depending on a CT-e issued by FleetPay.

It is the companion to POST /fiscal/cte/{cte_uuid}/ciot/emissao: the party contracting freight and declaring the CIOT is not always the party issuing its tax document. On this route, the entire trip is supplied in the body — contracted carrier, route, cargo, vehicle, driver, documents and amounts — and the CIOT is the only output.

Both routes coexist. If you issue the CT-e through FleetPay and want its CIOT linked to it, continue using the anchored route: nothing has changed there.

The response code tells you the outcome

CodeMeaningCan the trip proceed?
201ANTT returned the CIOT: number and verification code are in the response.Yes
202The declaration was submitted; the outcome will arrive later.No — query first
422The declaration was not transmitted, or was rejected.No

Treating a 202 as success sends a truck onto the road with a CIOT that may not exist. After a 202, query the operation by id until its status changes from sent.

The operation exists even when the declaration fails

The record is created before contacting the provider. A 422 returns the operation's id in error.details.ciot.id; it remains readable through GET /fiscal/ciot/{id}, with the reason recorded. Save this ID: it is how a rejection is investigated.

Idempotency

referencia_externa is optional and unique per company. With it, a network retry receives 400 validacao rather than generating another CIOT for the same freight operation — which would be a regulatory problem, not merely an inconvenience. Without it, you bear that risk.

Scope of this version

Full or partial loads, declared on your own behalf (contratado.documento must be the authenticated company's CNPJ), with one to ten vehicles and one to one hundred tax documents containing sender and recipient.

For partial loads, provide carga.contratantes. rota.trechos can detail up to one hundred pickup/delivery pairs; rota.origem and rota.destino still represent the trip's endpoints. TAC agregado, freight installments and toll vouchers with toll plazas are not yet accepted by this route.

Simulated sandbox mode

This operation has no contracted CIOT provider behind it: in the sandbox environment, FleetPay generates a deterministic response with no regulatory effect — nothing is registered with ANTT, and no CIOT handled here has legal validity.

Test sentinels

In simulated mode, these referencia_externa values force an outcome — use them to exercise paths beyond the happy path:

referencia_externaResponse
CIOT-PENDENTE202 — declaration submitted, no final outcome
CIOT-RECUSAR422 declaracao_recusada — the provider rejected it
any other value201 — CIOT registered

The external reference acts as the sentinel because it is the only body field that belongs to you, is optional and is not sent to ANTT — requesting an outcome through it does not contaminate any operation data.

Authentication

[
  {
    "oauth2": []
  },
  {
    "chaveApi": []
  }
]
Availability depends on the environment, enabled scopes and provider. This reference does not execute requests or collect credentials.

Parameters

No parameters declared for this operation.

Request Body

Required

application/json

referencia_externastring | nullOptional

Your system's identifier for this trip. Optional and unique per company: this is the idempotency key that prevents a network retry from creating a second CIOT for the same freight operation.

It is not sent to ANTT.

maxLength64
tipo_operacaostringRequired

lotacao for a load occupying the entire operation; fracionado for loads from multiple contracting parties on the same trip. TAC agregado remains outside the scope of this version.

"lotacao" · "fracionado"
contratadoobjectRequired

The carrier. Must be the authenticated company: this route declares operations on its own behalf. A different contracted party results in 422 declaracao_bloqueada.

viagemobjectRequired
rotaobjectRequired
cargaobjectRequired
veiculosarrayRequired

One to ten vehicles per operation.

minItems1
maxItems10
motoristaobjectRequired
valoresobjectRequired

Responses

201 HTTP Response

CIOT registered with ANTT.

application/json

202 HTTP Response

Declaration submitted, but no final outcome yet. Do not start the trip: query the operation by id until its status is no longer sent.

application/json

400 HTTP Response

validacao — a required trip field is missing, or another operation belonging to this company has already used referencia_externa.

application/json

errorobjectOptional
401 HTTP Response

Unauthenticated (autenticacao): missing, invalid or expired credentials, including an API key used in the wrong environment. A sandbox key is not valid in production, nor a production key in the sandbox; the error message indicates the expected environment.

application/json

errorobjectOptional
403 HTTP Response

Scope not enabled for these credentials

application/json

errorobjectOptional
422 HTTP Response

declaracao_bloqueada — the declaration was never transmitted (the contracted party is not the authenticated company, its profile is not supported, or no provider is available). declaracao_recusada — the provider rejected the declaration.

In both cases, error.details.ciot.id identifies the operation, which remains readable through GET /fiscal/ciot/{id}.

application/json

errorobjectOptional
Complete Operation Definition
{
  "tags": [
    "CIOT"
  ],
  "summary": "Declarar CIOT sem CT-e",
  "operationId": "declararCiot",
  "description": "Registra uma Operação de Transporte na ANTT a partir da **viagem**, sem depender de um\nCT-e emitido pela FleetPay.\n\nÉ o irmão de `POST /fiscal/cte/{cte_uuid}/ciot/emissao`, e existe porque quem contrata\nfrete e precisa declarar o CIOT nem sempre é quem emite o documento fiscal dele. Nesta\nrota a viagem inteira chega no corpo — contratado, rota, carga, veículo, motorista,\ndocumentos e valores — e o CIOT é a única coisa que se produz.\n\n**As duas rotas convivem.** Se você emite o CT-e pela FleetPay e quer o CIOT amarrado a\nele, continue na rota ancorada: nada mudou lá.\n\n## O código de resposta conta o desfecho\n\n| Código | Significa | Pode seguir viagem? |\n|---|---|---|\n| `201` | A ANTT devolveu o CIOT: número e código verificador na resposta. | **Sim** |\n| `202` | A declaração foi entregue e o veredito vem depois. | **Não** — consulte antes |\n| `422` | A declaração não saiu daqui, ou foi recusada. | Não |\n\nTratar um `202` como sucesso põe caminhão na estrada com um CIOT que talvez não exista.\nEm `202`, releia a operação pelo `id` até o status sair de `sent`.\n\n## A operação existe mesmo quando a declaração falha\n\nA linha é criada **antes** da chamada ao provedor. Um `422` devolve o `id` da operação\nem `error.details.ciot.id`, e ela continua legível por `GET /fiscal/ciot/{id}` com o\nmotivo gravado. Guarde esse id: é por ele que se investiga uma recusa.\n\n## Idempotência\n\n`referencia_externa` é opcional e **única por empresa**. Com ela, um retry de rede\nesbarra em `400 validacao` em vez de gerar um segundo CIOT para o mesmo frete — o que\nseria problema regulatório, não inconveniência. Sem ela, o risco é seu.\n\n## Escopo desta versão\n\nCarga **lotação ou fracionada**, declarada **em nome próprio** (o\n`contratado.documento` tem de ser o CNPJ da empresa autenticada), de um a dez veículos\ne de um a cem documentos fiscais com remetente e destinatário.\n\nNo fracionado, informe `carga.contratantes`. `rota.trechos` pode detalhar até cem\npares de coleta e entrega; `rota.origem` e `rota.destino` continuam representando os\nextremos da viagem. TAC agregado, parcelas do frete e Vale-Pedágio com praças ainda\nnão são aceitos por esta rota.\n\n## Modo simulado em homologação\n\nEsta operação **não tem provedor de CIOT contratado** por trás: em homologação a\nresposta é gerada pela FleetPay, é determinística e **não tem efeito regulatório** —\nnada é registrado na ANTT e nenhum CIOT tratado aqui tem valor legal.\n\n### Sentinelas de teste\n\nEm modo simulado, estes valores de `referencia_externa` forçam um desfecho — use-os\npara exercitar os caminhos que não são o feliz:\n\n| `referencia_externa` | Resposta |\n|---|---|\n| `CIOT-PENDENTE` | `202` — declaração entregue, sem veredito |\n| `CIOT-RECUSAR` | `422 declaracao_recusada` — o provedor recusou |\n| qualquer outro valor | `201` — CIOT registrado |\n\nA referência externa serve de sentinela porque é o único campo do corpo que é seu, é\nopcional e **não vai para a ANTT** — pedir um desfecho por ela não contamina nenhum\ndado da operação.\n",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeclaracaoCiot"
        }
      }
    }
  },
  "responses": {
    "201": {
      "description": "CIOT registrado na ANTT.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/RespostaCiot"
          }
        }
      }
    },
    "202": {
      "description": "Declaração entregue e ainda sem desfecho. **Não siga viagem**: releia a operação\npelo `id` até o status sair de `sent`.\n",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/RespostaCiot"
          }
        }
      }
    },
    "400": {
      "description": "`validacao` — falta campo obrigatório da viagem, ou a `referencia_externa` já foi\nusada por outra operação desta empresa.\n",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Erro"
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Erro401"
    },
    "403": {
      "$ref": "#/components/responses/Erro403"
    },
    "422": {
      "description": "`declaracao_bloqueada` — a declaração não chegou a ser transmitida (o contratado\nnão é a empresa autenticada, o perfil dele não é coberto, ou não há provedor).\n`declaracao_recusada` — o provedor respondeu recusando.\n\nNos dois casos `error.details.ciot.id` traz o endereço da operação, que permanece\nlegível por `GET /fiscal/ciot/{id}`.\n",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Erro"
          }
        }
      }
    }
  },
  "method": "POST",
  "path": "/fiscal/ciot",
  "parameters": []
}