DC-e
DC-e (model 99, Declaração de Conteúdo Eletrônica) issuance on behalf of marketplaces and companies, including onboarding, webhook payloads, error model, state machine and integration checklist.
Overview and onboarding flow
The DC-e (model 99, Declaração de Conteúdo Eletrônica, Ajuste SINIEF 05/2021) is the electronic content declaration that accompanies shipments of goods sent by non-taxpayers, issued on their behalf by a marketplace, or by a company for itself. Company registration, certificate association and webhook registration are shared with NF-e; the resource segment keeps the document's original dc-e and every document-level operation lives under /dc-e/{dceId}.
| Step | API | Notes |
|---|---|---|
| 1 Register company | POST /openapi/v2/empresas | Same as NF-e, with the optional emissaoDCe section; at least one of emissaoNFeProduto / emissaoDCe is required, a DC-e-only integrator may omit the NF-e block; a body carrying id is an update |
| 2 Link certificate | POST /openapi/v1/empresas/{empresaId}/certificadoDigital | Same as NF-e |
| 3 Register webhook | POST /openapi/v1/webhooks | Same as NF-e; DC-e results reuse the same callback URL |
| 4 Issue | POST /openapi/v2/empresas/{empresaId}/dc-e | Accepted immediately (200, no body); authorized asynchronously with SEFAZ |
| 5 Query | GET /openapi/v2/empresas/{empresaId}/dc-e/{dceId} | Status, protocol, XML / DACE download links, request echo |
| 6 Cancel | DELETE /openapi/v2/empresas/{empresaId}/dc-e/{dceId} | Within 24 hours after authorization; asynchronous: 200 with no body, result via webhook |
Authentication is identical to NF-e: headers token / timestamp / sign, with sign = MD5(token + path + body + timestamp) as lowercase hex; path includes the /openapi prefix and path variables and excludes the query string; GET / DELETE without a body use an empty string; a DELETE with a body (cancellation with a reason) signs the raw JSON with CR/LF removed. See Authentication.
Prerequisites
- The company must be approved with a usable certificate (otherwise
DCe00008). The DC-e authorizer is SEFAZ-PR (the only authorizer listed on the national DC-e portal); companies from every state are routed to it. - The company must have its DC-e issuance parameters configured:
emissaoDCe.tipoEmitenteand a model 99 number series (sequencialDCe/serieDCe); missing either returnsDCe00004. - Phase one supports two issuer types:
Marketplace(a platform issuing on behalf of non-taxpayer sellers / individuals) andOwnIssuer(a company issuing for itself).Carriercan be registered but issuance is rejected (10019013) until SVRS publishes the new schema package. ambientein the request must match the company's current environment, otherwiseDCe00004(document wording: "not configured for the informed environment"). After registration the company is in the certification environment (Homologacao); switching to production is an operations action with no API, and sendingambiente=Producaobefore the switch returnsDCe00004.- Phase one supports normal issuance only (
tpEmis=1); offline contingency comes in phase two.
Company registration: the emissaoDCe section
Register company accepts an optional emissaoDCe section (all other fields unchanged):
"emissaoDCe": {"ambienteProducao": {"tipoEmitente": "Marketplace","sequencialDCe": 1,"serieDCe": "1","siteMarketplace": "https://loja.exemplo.com.br"}}
| Field | Type | Required | Description |
|---|---|---|---|
tipoEmitente | string | yes | Marketplace / OwnIssuer (document alias EmissorProprio) / Carrier (alias Transportadora; registration allowed, issuance rejected) |
sequencialDCe | integer | yes | First nDC (1-999999999); the platform numbers sequentially from it |
serieDCe | string | yes | Series (0-999, up to 3 digits) |
siteMarketplace | string | Required for Marketplace | Platform site (2-120 characters), written to XML Marketplace/Site and to the DACE |
- A company registered without
emissaoDCeis not enabled for DC-e: registration still succeeds, but the response carriesdceHabilitado=falseand issuance returnsDCe00004. Check that field right after registering. - To enable DC-e later, raise the starting number or fix contact details, resend the registration payload with
id. The model 99 series only moves up; the full update rules are on the Register company page.
Endpoints
| Endpoint | Purpose |
|---|---|
| Issue DC-e | POST /openapi/v2/empresas/{empresaId}/dc-e, accepted with HTTP 200 and no body; idempotent on id |
| Query DC-e | GET /openapi/v2/empresas/{empresaId}/dc-e/{dceId}, status, protocol, download links and request echo |
| Cancel DC-e | DELETE /openapi/v2/empresas/{empresaId}/dc-e/{dceId}, asynchronous, within 24 hours after authorization |
Webhook payload
Webhook registration and signature headers are shared with NF-e; register the callback URL with Register webhook. Delivery request headers: besides the five platform signature headers (X-Tffiscal-Event / X-Tffiscal-Event-Id / X-Tffiscal-Delivery-Id / X-Tffiscal-Timestamp / X-Tffiscal-Signature), every delivery carries both token and x-token with the same value (the token registered with the webhook, sent back verbatim); the receiver may verify either one.
Event codes and the compatibility payload (tipo="DC-e", 14 fields in fixed order):
| Event code | Trigger | dceStatus |
|---|---|---|
dce.authorized | Authorization 100 | Autorizada |
dce.rejected | SEFAZ rejection or terminal task failure (including failures before the document is numbered, which have no chave) | Negada (dceMotivoStatus is cStat - reason; a terminal failure without cStat carries the reason only) |
dce.canceled | Cancellation registered (135 / 136 / 155) | Cancelada (dceDataAutorizacao is the cancellation registration time, dceNumeroProtocolo the cancellation event protocol) |
dce.cancel_rejected | SEFAZ rejected the cancellation or the cancellation task failed terminally | CancelamentoNegado (the document stays authorized; carries the authorization protocol / digest / XML link) |
Payload fields
| Field | Type | Description |
|---|---|---|
tipo | string | Always DC-e |
empresaId | string | Company identifier |
dceId | string | The id sent at issuance; correlate deliveries by this field |
dceStatus | string | Autorizada / Negada / Cancelada / CancelamentoNegado |
dceMotivoStatus | string | cStat - xMotivo on rejection or cancellation rejection, the failure reason on terminal failure; null otherwise |
dceLinkDace | string | DACE link lazily rendered by chave (authorized / cancelled callbacks); null on rejection |
dceLinkXml | string | XML download link; null when there is no authorized XML |
dceNumero | string | DC-e number; null when the document was never numbered |
dceSerie | string | DC-e series; null when the document was never numbered |
dceChaveAcesso | string | 44-digit access key; null when the document was never numbered |
dceDataEmissao | string | Issue time; the acceptance time for failures before numbering |
dceDataAutorizacao | string | Authorization time; the cancellation registration time in dce.canceled; null otherwise |
dceNumeroProtocolo | string | Authorization protocol; the cancellation event protocol in dce.canceled; null on rejection |
dceDigestValue | string | Signature digest of the authorized document; null on rejection and in dce.canceled |
dce.authorized
{ "tipo": "DC-e", "empresaId": "1934811222334455", "dceId": "DCe-000012333", "dceStatus": "Autorizada", "dceMotivoStatus": null,"dceLinkDace": "https://api.v2.tffiscal.com/openapi/files/dace/35260940673061000134990010000000011100000012?token=...", "dceLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/7?token=...","dceNumero": "1", "dceSerie": "1", "dceChaveAcesso": "41260940673061000134990010000000011101234567","dceDataEmissao": "2026-09-06T12:00:00Z", "dceDataAutorizacao": "2026-09-06T12:00:03Z","dceNumeroProtocolo": "141260000000001", "dceDigestValue": "tasG40Ic6Zh7PIBiLEEH7Hb940Y=" }
dce.rejected
{ "tipo": "DC-e", "empresaId": "1934811222334455", "dceId": "DCe-000012333", "dceStatus": "Negada","dceMotivoStatus": "225 - Rejeicao: Falha no schema XML", "dceLinkDace": null, "dceLinkXml": null,"dceNumero": "1", "dceSerie": "1", "dceChaveAcesso": "4126...", "dceDataEmissao": "2026-09-06T12:00:00Z","dceDataAutorizacao": null, "dceNumeroProtocolo": null, "dceDigestValue": null }
Failure before numbering (company not configured for DC-e / missing series / message mapping failure and other terminal failures where the document was never numbered and has no chave): dce.rejected is still delivered, the document fact fields are null, dceMotivoStatus carries the failure reason and dceDataEmissao the acceptance time. Correlate by dceId and never assume dceChaveAcesso is present:
{ "tipo": "DC-e", "empresaId": "1934811222334455", "dceId": "DCe-000012333", "dceStatus": "Negada","dceMotivoStatus": "Empresa não configurada para emissão de DC-e", "dceLinkDace": null, "dceLinkXml": null,"dceNumero": null, "dceSerie": null, "dceChaveAcesso": null, "dceDataEmissao": "2026-09-06T12:00:00Z","dceDataAutorizacao": null, "dceNumeroProtocolo": null, "dceDigestValue": null }
dce.canceled
{ "tipo": "DC-e", "empresaId": "1934811222334455", "dceId": "DCe-000012333", "dceStatus": "Cancelada", "dceMotivoStatus": null,"dceLinkDace": "https://.../openapi/files/dace/35260940673061000134990010000000011100000012?token=...", "dceLinkXml": "https://.../openapi/files/xml/7?token=...","dceNumero": "1", "dceSerie": "1", "dceChaveAcesso": "4126...", "dceDataEmissao": "2026-09-06T12:00:00Z","dceDataAutorizacao": "2026-09-06T15:00:00Z", "dceNumeroProtocolo": "141260000000099", "dceDigestValue": null }
dce.cancel_rejected
{ "tipo": "DC-e", "empresaId": "1934811222334455", "dceId": "DCe-000012333", "dceStatus": "CancelamentoNegado","dceMotivoStatus": "594 - Rejeicao: O numero de sequencia do evento informado e maior que o permitido","dceLinkDace": null, "dceLinkXml": "https://.../openapi/files/xml/7?token=...", "dceNumero": "1", "dceSerie": "1","dceChaveAcesso": "4126...", "dceDataEmissao": "2026-09-06T12:00:00Z", "dceDataAutorizacao": null,"dceNumeroProtocolo": "141260000000001", "dceDigestValue": "tasG40Ic6Zh7PIBiLEEH7Hb940Y=" }
In the authorized / cancelled callbacks dceLinkDace is the DACE link lazily rendered by chave (nothing is rendered at delivery time; the first download renders and archives it); both links share the query API shape (/openapi/files/{kind}/{ref}?token=…) and their lifetime comes from the tenant-level setting (default 7 days). See File download.
Error model
Same shapes as NF-e: business errors are [{ "codigo", "mensagem" }] (HTTP 400; a missing document / task is HTTP 404 with codigo DCe0001); authentication-layer errors use the platform envelope (401 / 403 / 429, see Authentication). Cases with a documented example code reuse the document's code; every other codigo is the platform's numeric error code, and mensagem is localized by request language (Portuguese uses the document wording).
| codigo | HTTP | Scenario | Action |
|---|---|---|---|
DCe0001 | 404 | dceId not found, not owned by the company, or cancellation requested before the document was materialized | Check id and empresaId; cancel Pendente documents only after authorization |
10003000 | 404 | empresaId not found | Check empresaId |
DCe00004 | 400 | Company not configured for DC-e (missing tipoEmitente / model 99 series / Marketplace site), or ambiente differs from the company's current environment | Send emissaoDCe at registration or through an update with id; submit for the company's current environment and ask operations for the production switch |
DCe00005 / DCe00006 / DCe00007 | 400 | Marketplace / Carrier company without remetente / remetente.endereco missing / Brazilian sender without cpfCnpj | Add the sender data |
DCe00008 | 400 | Company cannot issue (not approved / certificate not ready) | Wait for approval / link the certificate |
DCe00009 | 400 | Brazilian recipient without cpfCnpj | Add the recipient document |
GW001 | 400 | Municipality IBGE code not found or inconsistent with uf | Check cidade / uf |
10019005 / 10019006 | 400 | Concurrent duplicate request / too many pending tasks for the CNPJ | Retry later |
10019007 | 400 | Number series unresolved (several enabled series) | Ask operations to consolidate the series |
10019013 | 400 | Issuer type Carrier not supported for issuance yet | Use a Marketplace / OwnIssuer company |
10019018 – 10019022 | 400 | Invalid item / enum or format / carrier CNPJ / additional information too long / autorizacaoDownloadXml | Fix per mensagem |
10019030 / 10019031 | 400 | Same id with a different message / production: an active or authorized document already exists for the id | Use a new id or resend the original message / query the original |
10019040 / 10019041 / 10019042 / 10019043 | 400 | Status does not allow cancellation / 24-hour window exceeded / cancellation already accepted / invalid reason | See Cancel DC-e |
10019048 | 400 | dataEmissao outside the allowed window (more than 5 minutes ahead or more than 30 days back) | Use the current time or omit dataEmissao |
10001001 | 400 | Request field validation failed (one entry per field); registration / update contract errors | Fix per mensagem |
The per-endpoint code lists are on Issue DC-e, Query DC-e and Cancel DC-e. SEFAZ rejections during issuance are not HTTP errors: they surface as query status Negada and the dce.rejected webhook; SEFAZ rejections of the cancellation surface as dce.cancel_rejected.
State machine
Accepted (POST 200) ─→ Pendente ─number + send to SEFAZ─┬─ cStat 100 ─→ Autorizada ─DELETE 200─→ CancelamentoPendente ─┬─ 135/136/155 ─→ Cancelada│ └─ SEFAZ rejection ─→ Autorizada (webhook CancelamentoNegado)├─ other terminal cStat ─→ Negada└─ unparseable parameters / retry budget exhausted ─→ Falha (same id may be resubmitted)
- While
Pendente, SEFAZ outages (108 / 109) are retried with back-off by the platform; there is no contingency rerouting in phase one. Duplicate issuance (451 / 452 / 539) is reconciled by querying SEFAZ first. - After
Negada/Falhathe sameidmay be resubmitted (reopened with the new message); afterAutorizadaa resubmission with the sameidonly hits idempotency.
Notes
- The CNPJ in the key is the platform company: positions 7-20 always carry the authorized issuer (the Marketplace company or the self-issuing company); a CPF sender only appears in the XML
emitgroup and in the DACE REMETENTE block. - Fixed recipient name in the certification environment: with
tpAmb=2the recipient name in the XML and DACE isDCE EMITIDA EM AMBIENTE DE HOMOLOGACAO(SEFAZ validation 598); the query echo keeps the original. - 24-hour cancellation window: counted from the authorization time; after it the document can only be kept. The official DC-e has cancellation only: no correction letter, no number invalidation.
- Carrier not supported yet: the current official schema restricts
tpEmitto Marketplace / own issuer; a registered carrier company is rejected with10019013at issuance. - DACE: A4 portrait, rendered on demand and cached; re-rendered with the
CANCELADAwatermark after cancellation; the certification environment carries theSEM VALOR FISCAL - HOMOLOGAÇÃOwatermark. - Authorizer: DC-e from every state goes to the SEFAZ-PR authorizer; the QR code points to
https://www.fazenda.pr.gov.br/dce/qrcode?chDCe={chave}&tpAmb={tpAmb}.
Integration checklist
- In the certification environment: company registered (with
emissaoDCe, responsedceHabilitado=trueconfirmed), certificate linked, webhook registered (receiver accepts bothtoken/x-token). - Issue a minimal DC-e (the example on Issue DC-e), query it as
Autorizada, download the XML and the DACE, receive thedce.authorizedcallback. - Resend the same
idonce and confirm HTTP 200 with no second document; change one item and resend, confirm10019030. - Cancel the document: confirm 200 with no body, query
CancelamentoPendente→Cancelada, receive thedce.canceledcallback, DACE carries the watermark. - Cancel the cancelled document again and confirm
10019040; query a non-existent id and confirm 404DCe0001. - Send deliberate errors (
ambiente=Producao,cidade=9999999, missingremetente) and confirm the 400 error array with codesDCe00004/GW001/DCe00005. - Issue for a company not enabled for DC-e and confirm
DCe00004; resend the registration payload withidand a highersequencialDCe, confirm 200 and that the next document starts from the new number; resend a lower number and confirm 40010001001.
