← HomeFleetPay / API

Issue a batch of contra-CT-e documents

Parameters, data structure and responses from the versioned contract.

POST/fiscal/cte-subcontratacao/lote
createContraCteBatchSandbox Base: https://api.fleetpay.site/v1

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

Issues multiple counter-CT-e documents in one call and returns a batch_id. Issuance runs in the background; results by access key are available from GET /fiscal/cte-subcontratacao/lote/{batch_id}. Each contracting carrier CT-e must have been received first through POST /fiscal/cte-subcontratacao.

Two Structures, One Endpoint

  • 1:1 — a complete counter-CT-e for each contracting carrier CT-e. ctes[] contains the access keys; the driver (motorista.cpf) and vehicle (placa) are shared by the entire batch.
  • Legs — a contracting carrier CT-e subcontracted into route segments: ctes[].pernas[] describes each segment with its own origin/destination. Each leg can have its own driver, vehicle and amount (batch motorista/placa are defaults for legs that omit them). Do not mix keys with and without pernas in the same batch.

Amount: Per Key OR Allocation, Never Both

  • ctes[].valor (or pernas[].valor) freezes the amount of each counter-CT-e; the fiscal amounts (vTPrest/vRec) and driver transfer use that amount without rounding.
  • Batch valores.frete_bruto allocates total ÷ N in cents, assigning remaining cents to the last keys in sequence; the sum is exact.

Providing both returns 422.

Leg Route

By default, the counter-CT-e inherits the contracting carrier's origin → destination. Batch origem/destino (or values per key/leg) declare the ACTUAL leg route, which determines CFOP and ICMS: origin in the issuer's state → 5360 (same state) / 6360 (another state); origin outside the issuer's state → 5932 (start and end in the same state) / 6932. With a service-type tax rule (tp_serv in the rule), the rule's CFOP is retained when service starts in the issuer's state; 5932/6932 still applies when it starts in another state. Municipality/state pairs are validated; a tax rule applicable to the route and service type must exist (GET /fiscal/regras-tributacao).

Service Type

tipo_servico is each counter-CT-e's ide/tpServ, with precedence leg → key → batch → 1 (subcontracting). Only 1 subcontracting, 2 onward carriage and 3 intermediate onward carriage are supported. For onward carriage, the route is the leg performed by the subcontractor, not the contracting carrier's entire trip: 2 and 3 require origem and destino (at key, batch or leg level; 422 if missing). A "leg" equal to the contracting carrier CT-e's entire trip is rejected on that row with redespacho_exige_rota. A contracting carrier CT-e linked to multimodal transport (tpServ 4) does not allow a counter-CT-e (origem_incompativel_com_tipo; in the inbox, allows_counter_cte: false). The result row returns the issued document's tipo_servico (for a duplicated row, the requested type; the existing counter-CT-e's type is available from GET /fiscal/cte/{counter_cte_id}, field service_type).

Driver Transfer (Same Rule as CIOT)

repasse.parcelas is the batch installment rule (positions 1..3, percentages totaling 100, dias from 0 to 30) and overrides the driver's registered rule. Counter-CT-e documents for the same driver within the batch form a group:

  • N ≥ number of installments → each whole document is assigned to an installment (60/20/20 across 15 documents = 9/3/3 documents, always ≥ 1 per installment). Installment 1 is released on scanning, 2 on completion and 3 on submission of accounts;
  • N < number of installments → each document's amount is split across the installments (60/20/20 of its amount).

The bucket is determined by position in the batch, not amount: when amounts differ, key order determines the amount assigned to each installment. An installment exists only after the document is scanned; query it through GET /carriers/parcelas-repasse/{documento} (accepts counter_cte_id).

One Mode per Source and Blocking Conditions

A key with an active full counter-CT-e does not accept legs (origem_ja_subcontratada_1a1), and vice versa (origem_ja_subcontratada_em_pernas); canceling the counter-CT-e enables the other mode. A key already subcontracted in the same mode returns duplicated with the existing counter_cte_id, so batch resubmission is safe. A CT-e issued by your own company returns cte_proprio; a route without a rule, sem_regra_tributacao; an onward-carriage leg equal to the entire trip, redespacho_exige_rota; a source linked to multimodal transport, origem_incompativel_com_tipo. A source whose transfer has already been paid cannot be converted to legs.

Canceling a counter-CT-e (POST /fiscal/cte/{cte_uuid}/eventos/cancelamento) cancels unpaid installments and removes the document from the group; the contracting carrier's CT-e remains valid.

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

ctesarrayRequired

Each item is the key (string) or an object with chave and the optional fields.

minItems1
motoristaobjectRequired
placastringRequired
pattern"^[A-Za-z]{3}[0-9][A-Za-z0-9][0-9]{2}$"
valoresobjectOptional
tipo_servicointeger | nullOptional

ide/tpServ for the batch's counter-CT-e documents: 1 subcontracting (default), 2 onward carriage, 3 intermediate onward carriage. Can be overridden per key (ctes[].tipo_servico) and per leg (pernas[].tipo_servico). For 2/3, the route segment (origem and destino) is required.

1 · 2 · 3 · null
repasseobjectOptional

Optional. Without this block, the batch is tax documents only: it issues counter-CT-e documents without creating a transfer group, installment or leg ROUTE, or neutralizing the source document's transfer — issued rows return financeiro: "nenhum". With the block, the source CT-e — in the contracting company's account — joins its transfer group with these installments and the batch's driver: the contracting company pays the driver, and the subcontracted carrier never receives a financial document. The payments service sends funds to the individual driver's account or to their carrier's Operational Account for a legal entity. Requires the contracting company's opt-in; without it, the row returns financeiro: "nenhum" with motivo: contratante_sem_opt_in.

referencia_externastring | nullOptional

Your identifier, returned in external_reference.

maxLength64
subcontratadaobjectOptional

On behalf of the subcontracted carrier. The CONTRACTING COMPANY makes the request using its own API key, and the batch is created in the subcontracted carrier's account for this CNPJ — using that carrier's certificate, numbering, tax inbox, driver and vehicle. Requires authorization granted by the subcontracted carrier through POST /fiscal/cte-subcontratacao/autorizacoes; without it, returns 403 emissao_nao_autorizada; a CNPJ that is not a customer returns 404 subcontratada_nao_encontrada. The company's own CNPJ is accepted and changes nothing. With repasse, the contracting company's opt-in is implicit: it requested issuance itself.

Responses

202 HTTP Response

Batch accepted; issuance runs in the background.

application/json

Headers

X-Request-Id

Call correlation identifier.

400 HTTP Response

Invalid request

application/json

errorobjectOptional
401 HTTP Response

FleetPay API key missing or invalid.

application/json

Headers

X-Request-Id

Call correlation identifier.

403 HTTP Response

Fiscal scope disabled for the key, or no active carrier associated with the key.

application/json

Headers

X-Request-Id

Call correlation identifier.

422 HTTP Response

Payload validation (error.details.fields) or business rule before batch creation: motorista_nao_encontrado, veiculo_nao_encontrado. For legs, message identifies the leg (ctes.0.pernas.2).

application/json

429 HTTP Response

Per-carrier limit exceeded.

application/json

Headers

X-Request-Id

Call correlation identifier.

Retry-After

Seconds until another attempt.

500 HTTP Response

Internal failure without operational integration details.

application/json

Headers

X-Request-Id

Call correlation identifier.

Complete Operation Definition
{
  "tags": [
    "CT-e de subcontratação"
  ],
  "summary": "Emitir contra-CT-e em lote (1:1 ou em pernas)",
  "operationId": "createContraCteBatch",
  "description": "Emite **vários contra-CT-e numa chamada** e devolve um `batch_id`; a emissão roda em\nsegundo plano e o resultado por chave sai em `GET /fiscal/cte-subcontratacao/lote/{batch_id}`.\nCada CT-e da contratante precisa ter chegado antes por `POST /fiscal/cte-subcontratacao`.\n\n## Dois desenhos, um endpoint\n\n- **1:1** — um contra-CT-e integral por CT-e da contratante. `ctes[]` traz as chaves; o\n  motorista (`motorista.cpf`) e o veículo (`placa`) são os mesmos para o lote inteiro.\n- **Pernas** — um CT-e da contratante subcontratado em **trechos**: `ctes[].pernas[]`\n  descreve cada trecho com origem/destino próprios, e cada perna pode ter motorista,\n  veículo e valor próprios (o `motorista`/`placa` do lote são o padrão das pernas que não\n  informam os seus). Não misture chaves com e sem `pernas` no mesmo lote.\n\n## Valor: por chave OU rateio — nunca os dois\n\n- `ctes[].valor` (ou `pernas[].valor`) congela o valor de **cada** contra-CT-e; o fiscal\n  (`vTPrest`/`vRec`) e o repasse ao motorista saem desse valor, sem arredondar.\n- `valores.frete_bruto` no lote rateia `total ÷ N` em centavos, com o resíduo nas\n  **últimas** chaves da sequência; a soma fecha exata.\n\nInformar os dois responde `422`.\n\n## Rota do trecho\n\nPor padrão o contra-CT-e herda origem → destino da contratante. `origem`/`destino` no lote\n(ou por chave/perna) declaram a rota REAL do trecho — e é dela que saem CFOP e ICMS:\norigem na UF do emitente → `5360` (mesma UF) / `6360` (outra UF); origem fora da UF do\nemitente → `5932` (início e fim na mesma UF) / `6932`. Com regra de tributação **do tipo\nde serviço** (`tp_serv` na regra), o CFOP da regra é mantido quando a prestação começa na\nUF do emitente; o `5932`/`6932` continua imposto quando começa em outra UF. Os pares\nmunicípio × UF são validados; precisa existir regra de tributação aplicável à rota e ao\ntipo (`GET /fiscal/regras-tributacao`).\n\n## Tipo de serviço\n\n`tipo_servico` é o `ide/tpServ` de cada contra-CT-e, com precedência **perna → chave →\nlote → `1`** (subcontratação). Só `1` subcontratação, `2` redespacho e `3` redespacho\nintermediário. No redespacho a rota é o **trecho** que a subcontratada executa, não a\nviagem da contratante: `2` e `3` exigem `origem` e `destino` (na chave, no lote ou na\nperna — `422` sem eles), e um \"trecho\" igual à viagem inteira do CT-e da contratante é\nrecusado na linha com `redespacho_exige_rota`. Um CT-e da contratante vinculado a\nmultimodal (`tpServ` 4) não admite contra-CT-e (`origem_incompativel_com_tipo`; na caixa,\n`allows_counter_cte: false`). A linha de resultado devolve o `tipo_servico` com que o\ndocumento saiu (na linha `duplicated`, o tipo **pedido** — o do contra-CT-e existente está\nem `GET /fiscal/cte/{counter_cte_id}`, campo `service_type`).\n\n## Repasse ao motorista (mesma regra do CIOT)\n\n`repasse.parcelas` é a regra de parcelas do lote (posições 1..3, percentuais somando 100,\n`dias` de 0 a 30) e **vence a regra cadastrada do motorista**. Os contra-CT-e de um mesmo\nmotorista no lote formam um grupo:\n\n- **N ≥ nº de parcelas** → cada documento inteiro cai numa parcela (60/20/20 em 15 docs =\n  9/3/3 documentos, sempre ≥ 1 por parcela) — a parcela 1 libera na bipagem, a 2 na\n  conclusão, a 3 na prestação de contas;\n- **N < nº de parcelas** → cada documento é fracionado nas parcelas (60/20/20 do valor\n  dele).\n\nO bucket é decidido pela **posição no lote**, não pelo valor: com valores diferentes, a\nordem das chaves define quanto entra em cada parcela. A parcela só existe depois da\n**bipagem** do documento — consulte-a em `GET /carriers/parcelas-repasse/{documento}`\n(aceita o `counter_cte_id`).\n\n## Um modo por origem, e o que bloqueia\n\nUma chave com contra-CT-e integral ativo não aceita pernas (`origem_ja_subcontratada_1a1`)\ne vice-versa (`origem_ja_subcontratada_em_pernas`); cancelar o contra-CT-e libera o outro\nmodo. Chave já subcontratada no mesmo modo responde `duplicated` com o `counter_cte_id`\nexistente — reenviar o lote é seguro. CT-e emitido pela sua própria empresa responde\n`cte_proprio`; rota sem regra, `sem_regra_tributacao`; redespacho com o trecho igual à\nviagem inteira, `redespacho_exige_rota`; origem vinculada a multimodal,\n`origem_incompativel_com_tipo`; origem cujo repasse já foi pago não pode virar pernas.\n\nCancelar um contra-CT-e (`POST /fiscal/cte/{cte_uuid}/eventos/cancelamento`) cancela as\nparcelas ainda não pagas e tira o documento do grupo; o CT-e da contratante continua válido.\n",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ContraCteLoteInput"
        }
      }
    }
  },
  "responses": {
    "202": {
      "description": "Lote aceito; a emissão roda em segundo plano.",
      "headers": {
        "X-Request-Id": {
          "$ref": "#/components/headers/RequestId"
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ContraCteLoteAcceptedEnvelope"
          }
        }
      }
    },
    "400": {
      "$ref": "#/components/responses/Erro400"
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "403": {
      "$ref": "#/components/responses/Forbidden"
    },
    "422": {
      "description": "Validação do payload (`error.details.fields`) ou regra de negócio antes de criar o lote:\n`motorista_nao_encontrado`, `veiculo_nao_encontrado` — nas pernas, o `message` aponta a\nperna (`ctes.0.pernas.2`).\n",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ErrorEnvelope"
          }
        }
      }
    },
    "429": {
      "$ref": "#/components/responses/RateLimited"
    },
    "500": {
      "$ref": "#/components/responses/InternalError"
    }
  },
  "method": "POST",
  "path": "/fiscal/cte-subcontratacao/lote",
  "parameters": []
}