Skip to content

Test everything, break nothing.

The sandbox is a free test environment with the same API v5 as production. It stamps with a test PAC, so the CFDI you generate have no tax validity. When your integration works, you switch the base URL and the key.

Factura Digital · API v5Sandbox
POST
https://sandbox-app.facturadigital.com.mx/api/v5/invoice/create
application/x-www-form-urlencoded
json={
"Version": "4.0",
"Serie": "A",
"Folio": "AUTO",
"Fecha": "AUTO",
"Receptor": {
"Rfc": "XIA190128J61",
"Nombre": "XENON INDUSTRIAL ARTICLES",
"UsoCFDI": "G03"
},
"Conceptos": [ ... ],
...
}
Response200 OK
{
"message": "The document was generated successfully",
"code": 200,
"cfdi": {
"UUID": "6FA90F39-2D7A-4F1C-9C4D-AC2B11D9F6E0",
"FechaTimbrado": "2026-09-23T10:15:30",
"XmlBase64": "PD94bWwgdmVyc2lvbj0i...",
"PDF": "https://sandbox-app.facturadigital.com.mx/docs/pdf/6FA90F39-2D7A-4F1C-9C4D-AC2B11D9F6E0",
"XML": "https://sandbox-app.facturadigital.com.mx/docs/xml/..."
}
}

Sample interface with real API v5 calls against the sandbox; the values are examples. The full reference is at docs.facturadigital.com.mx.

The same API, with test stamping

What works the same as in production and what changes in the sandbox.

The same API v5

Same endpoints, same fields and same responses as in production. Only the base URL and the key change.

Test PAC

The sandbox always stamps with a test PAC. The CFDI you generate there have no tax validity.

PDF marked as a test

The PDF of every test CFDI carries the marks “Timbrado de prueba” and “Sin validez fiscal”.

Emails stay inside

If you ask for email delivery (enviar_mail), the message doesn't reach the real recipient: outside production it's diverted to a test inbox.

One key per environment

Your sandbox key doesn't work in production and vice versa. If you mix them up, the error tells you which environment answered.

A separate account

Your sandbox account is independent from production: its CFDI, keys and PDF templates don't mix.

Errors you can trigger on purpose

Errors respond with HTTP 400 and an internal code in the body. You can reproduce these in the sandbox to test how your system reacts.

Invalid key or wrong environment

code 501

The message ends with the environment that answered, for example [Environment: SANDBOX].

Call without the X-Api-Key header or with your production key

No CSD uploaded

code 602

To seal the XML, the account needs an active Certificado de Sello Digital.

POST /invoice/create before uploading your CSD

No credits

code 601

Each stamped CFDI uses 1 credit; with no balance, nothing is stamped.

Stamp when GET /account/balance returns 0

Missing JSON

code 400

The response says the JSON wasn't received: “Invalid or non received json in headers or body.”

POST /invoice/create without the json field

Doesn't match the SAT schema

code 702

It responds with errorType cfdi_schema_validation and the detail of each error in the errors field.

Send a CFDI that doesn't comply with Anexo 20

Cancellation without a UUID

code 400

Cancellation takes its parameters (UUID, MOTIVO) as headers, not in the body.

POST /invoice/cancel without the UUID header

The same endpoints as in production

What you integrate in the sandbox works the same in production.

Stamp from JSON

POST /invoice/create: you send the CFDI as JSON and the API builds the XML, seals it with your CSD and stamps it.

Stamp sealed XML

POST /invoice/stampxml (Base64) and /invoice/stampxmlfile (file) for XML you already sealed with your CSD.

Cancel

POST /invoice/cancel with reasons 01 to 04, or /invoice/cancelwithcsd sending the CSD in the request.

Look up

GET /invoice/list, listextended, listpayments, listreceived, listbydaterange and listwithfilters.

Account

GET /account/authorize to get your key and GET /account/balance to check your credits.

The same responses

Success with HTTP 200 and code 200; validation, key, balance or certificate errors with HTTP 400 and an internal code (501, 601, 602, 702…).

Going live

Your code doesn't change: only the base URL and the key.

  1. 01

    Integrate against the sandbox

    https://sandbox-app.facturadigital.com.mx/api/v5
  2. 02

    Upload your CSD to your production account

    Configuración → Certificados
  3. 03

    Switch the key

    X-Api-Key: <production key>
  4. 04

    Switch the base URL

    https://app.facturadigital.com.mx/api/v5

The same code stamps in production with your folios, which never expire.

Also in API v5

WebhooksNew

Notifications to your system when a CFDI is stamped or cancelled, or when a payment is recorded.

Official SDKsNew

Libraries for Node.js, PHP and Python that call the same API v5.

MCP serverNew

Connect Claude, ChatGPT or Gemini to your account. The assistant prepares the invoice and you confirm.

Frequently asked questions

Does the sandbox cost anything?

No. The sandbox is free. It's a separate environment, so what you stamp there doesn't use the folios in your production account.

Do sandbox CFDI have tax validity?

No. The sandbox always stamps with a test PAC: the CFDI have no tax validity and the PDF says so with the marks “Timbrado de prueba” and “Sin validez fiscal”.

How do I tell sandbox from production in my code?

By the base URL (https://sandbox-app.facturadigital.com.mx/api/v5 versus https://app.facturadigital.com.mx/api/v5) and by the key: each environment has its own. If you use one environment's key in the other, the API responds with code 501 and the message ends with the environment that answered, for example [Environment: SANDBOX].

How do I get my sandbox key?

The same way as in production, but in your sandbox account: copy it from Configuración → Datos de facturación or get it with GET /account/authorize by sending your username and password in the API-USUARIO and API-PASSWORD headers. It goes in the X-Api-Key header, Base64-encoded.

Does the sandbox send emails?

Not to your customers. Outside production, emails (for example, with enviar_mail) are diverted to a test inbox.

Can I test with the official SDKs?

Yes. The SDKs call the same API v5; for the sandbox you use the test base URL and key.

Which PAC errors should I handle?

Two: code 5037 means the PAC couldn't be reached; nothing was sent and you can retry. Code 5034 means the PAC didn't respond; the CFDI may have been stamped, so check with the SAT before retrying. The response includes the Serie and Folio that were used.

Once it all passes in sandbox, you're ready for production.

The sandbox is free and the API is included: in production you pay for folios that never expire.