Income and transfer
TipoDeComprobante I to bill the freight or T to move your own goods. On a transfer, the API sets SubTotal, Total and amounts to 0, the currency to XXX and the CFDI use to S01, as the SAT requires.
Send the JSON with the Carta Porte 3.1 complement and get the stamped CFDI back, ultra-fast and valid with the SAT, with its XML and PDF. Before stamping we check the SAT rules; if something fails, we tell you which field to fix with the error's CP code. The API is included: each stamped CFDI uses 1 folio.
The same complement you stamp on the web, from your TMS or your ERP.
TipoDeComprobante I to bill the freight or T to move your own goods. On a transfer, the API sets SubTotal, Total and amounts to 0, the currency to XXX and the CFDI use to S01, as the SAT requires.
We check the rules of the Carta Porte 3.1 error matrix (CP104, CP107, CP109, CP130, CP141 and CP193, among others). If something fails, nothing is stamped and no folio is used.
TotalDistRec, NumTotalMercancias and PesoBrutoTotal are calculated from your locations and your goods. You don't have to balance them by hand.
Send IdCCP with the value "AUTO" and the API generates the Carta Porte identifier in the SAT's format.
Locations, goods, transport figures and customs documents, with the Autotransporte, TransporteMaritimo and TransporteAereo nodes.
Send your sealed Carta Porte to /invoice/stampxmlfile as an .xml file up to 40 MB, or to /invoice/stampxml in Base64.
An income Carta Porte 3.1 by road. The JSON goes in the json field of POST /invoice/create, with your key in the X-Api-Key header.
# FD_API=https://sandbox-app.facturadigital.com.mx/api/v5
curl -X POST "$FD_API/invoice/create" \
-H "X-Api-Key: $FD_API_KEY" \
--data-urlencode "json@carta-porte.json"{
"Version": "4.0",
"Serie": "CP",
"Folio": "AUTO",
"Fecha": "AUTO",
"FormaPago": "03",
"MetodoPago": "PUE",
"Moneda": "MXN",
"TipoDeComprobante": "I",
"Exportacion": "01",
"LugarExpedicion": "64000",
"SubTotal": "5000.00",
"Total": "5800.00",
"Emisor": { "RegimenFiscal": "601" },
"Receptor": {
"Rfc": "XIA190128J61",
"Nombre": "XENON INDUSTRIAL ARTICLES",
"DomicilioFiscalReceptor": "76343",
"RegimenFiscalReceptor": "601",
"UsoCFDI": "G03"
},
"Conceptos": [{
"ClaveProdServ": "78101802",
"Cantidad": "1",
"ClaveUnidad": "E48",
"Descripcion": "Flete Monterrey a Saltillo",
"ValorUnitario": "5000.00",
"Importe": "5000.00",
"ObjetoImp": "02",
"Impuestos": { "Traslados": [{ ... }] }
}],
"Impuestos": { ... },
"Complemento": {
"CartaPorte31": {
"Version": "3.1",
"IdCCP": "AUTO",
"TranspInternac": "No",
"Ubicaciones": [
{
"TipoUbicacion": "Origen",
"RFCRemitenteDestinatario": "XIA190128J61",
"FechaHoraSalidaLlegada": "2026-09-28T08:00:00",
"Domicilio": {
"Estado": "NLE", "Pais": "MEX", "CodigoPostal": "64000"
}
},
{
"TipoUbicacion": "Destino",
"RFCRemitenteDestinatario": "XIA190128J61",
"FechaHoraSalidaLlegada": "2026-09-28T10:30:00",
"DistanciaRecorrida": "85",
"Domicilio": {
"Estado": "COA", "Pais": "MEX", "CodigoPostal": "25000"
}
}
],
"Mercancias": {
"UnidadPeso": "KGM",
"Mercancia": [{
"BienesTransp": "31161500",
"Descripcion": "Tornillería",
"Cantidad": "10",
"ClaveUnidad": "H87",
"PesoEnKg": "1200"
}],
"Autotransporte": {
"PermSCT": "TPAF01",
"NumPermisoSCT": "PERMISO-DE-MUESTRA",
"IdentificacionVehicular": {
"ConfigVehicular": "C2",
"PesoBrutoVehicular": "10.5",
"PlacaVM": "123AB4",
"AnioModeloVM": "2022"
},
"Seguros": {
"AseguraRespCivil": "ASEGURADORA DE MUESTRA",
"PolizaRespCivil": "POL-000123"
}
}
},
"FiguraTransporte": [{
"TipoFigura": "01",
"RFCFigura": "RFC_DEL_OPERADOR",
"NumLicencia": "LIC-000123",
"NombreFigura": "NOMBRE DEL OPERADOR"
}]
}
}
}{
"message": "The document was generated successfully",
"code": 200,
"cfdi": {
"UUID": "6FA90F39-2D7A-4F1C-9B3E-5C1D8A0E7B42",
"FechaTimbrado": "2026-09-28T08:01:12",
"CadenaQR": "https://verificacfdi.facturaelectronica.sat.gob.mx/...",
"XmlBase64": "PD94bWwgdmVyc2lvbj0iMS4wIi...",
"PDF": "https://app.facturadigital.com.mx/docs/pdf/6FA90F39-...",
"XML": "https://app.facturadigital.com.mx/docs/xml/...",
"Serie": "CP",
"Folio": "1042",
...
}
}From the sandbox to your first Carta Porte stamped in production.
It's free and stamps with a test PAC, with no tax validity. Upload your CSD and copy your key from Configuración → Datos de facturación.
If you send Folio "AUTO", create the series for the document type (I or T) in Configuración → Series y Folios.
Each trip in your system becomes a CartaPorte31: origin and destinations with their distance, goods with their weight, the vehicle and the driver.
Call POST /invoice/create and store the UUID, Serie and Folio. To go live you switch the base URL and the key; your code stays the same.
Errors respond with HTTP 400 and a code in the body. Carta Porte errors also include, in errors, the SAT's CP code and the field path.
errorType is cartaporte_validation and each item in errors carries the CP code, the field path and the message in Spanish. The docs link points to the guide for these errors.
{
"message": "Invalid 'CartaPorte31' complement: CP193: Falta la figura del transporte. ...",
"code": 400,
"errorType": "cartaporte_validation",
"docs": "https://docs.facturadigital.com.mx/errores/cartaporte",
"errors": [{
"severity": "error",
"code": "CP193",
"field": "Complemento.CartaPorte31.FiguraTransporte",
"message": "Falta la figura del transporte. Con autotransporte tienes que registrar al menos al operador (quien maneja la unidad)."
}]
}Stamp the REP for your PPD invoices with the same endpoint and the same key.
Cancel a CFDI with reasons 01 to 04 and get the SAT acknowledgment. Cancelling uses no folio.
Types, rules and how to fill in the complement if you stamp it from the app.
A free test environment with the same API v5 as production.
Libraries to call API v5 from your language, with the same endpoints.
Authentication, endpoints and the three ways to stamp: JSON, Base64 XML or an XML file.
Something missing? Message us or check the full reference.
Yes. Send the CFDI with Complemento.CartaPorte31 to POST /invoice/create, as income (I) or transfer (T), and you get the stamped CFDI with its XML and PDF. If you already build and seal your XML, stamp it at /invoice/stampxml (Base64) or /invoice/stampxmlfile (a file up to 40 MB).
Road, sea and air transport. The API doesn't generate the TransporteFerroviario node: if you move goods by rail, message us before you integrate.
A CartaPorte30 is converted to 3.1 before stamping, including the change from RegimenAduanero to RegimenesAduaneros. It's then validated just like a 3.1.
No. The API calculates them from the destinations' distances, the number of goods and their weights. If a weight or a quantity isn't a valid number, you get CP149 or CP154 so you can fix that value.
With TipoDeComprobante T and your own RFC as the receiver (rule CP107). The API sets SubTotal, Total and amounts to 0, the currency to XXX and the CFDI use to S01, removes the payment form and method, and marks the line items as not subject to tax.
Nothing is stamped and no folio is used. You get HTTP 400 with errorType cartaporte_validation and the errors list: the SAT's CP code, the field path and the message in Spanish.
The API is included: you pay for folios, not for the API. Each stamped CFDI uses 1 folio, same as on the web, and folios never expire. The sandbox is free.
It's free and uses the same API v5 as production. Once it works, you switch the base URL and the key.