Crear emisor
POSThttps://api.cfdi.express/v1/merchantsAPI key
Registra un RFC emisor con su régimen fiscal, código postal de expedición y serie. Es el primer paso antes de timbrar.
La razón social debe ir exactamente como aparece en tu Constancia de Situación Fiscal, en mayúsculas y sin el sufijo de régimen societario (SA DE CV, S DE RL…) salvo que esté impreso ahí. El SAT rechaza el timbrado si no coincide.
Una cuenta puede tener varios emisores activos a la vez; eliges cuál factura con merchantId en cada request.
Después de crearlo, sube su CSD con POST /v1/merchants/{id}/csd. Sin CSD el emisor no puede timbrar.
Autenticación
Authorization: Bearer sk_test_... | sk_live_...Parámetros
Cuerpo (JSON)
| Campo | Tipo | Descripción |
|---|---|---|
| rfcreq | string | RFC del emisor, 12 o 13 caracteres en mayúsculas. |
| legalNamereq | string | Razón social tal como está registrada ante el SAT. Máximo 300 caracteres. |
| regimenFiscalreq | string | Clave de 3 dígitos del catálogo c_RegimenFiscal (601, 626, 612…). |
| zipreq | string | Código postal del lugar de expedición, 5 dígitos. |
| serie | string | Serie de los folios. 1 a 10 caracteres. Default A. |
| defaultClaveProdServ | string | Clave de producto/servicio de 8 dígitos usada cuando un concepto no trae la suya. |
| defaultClaveUnidad | string | Clave de unidad usada por default (por ejemplo E48 o H87). |
Ejemplos
cURL
curl -X POST https://api.cfdi.express/v1/merchants \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"rfc": "EKU9003173C9",
"legalName": "ESCUELA KEMPER URGATE",
"regimenFiscal": "601",
"zip": "42501",
"serie": "A"
}'Node.js
const res = await fetch("https://api.cfdi.express/v1/merchants", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CFDI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
rfc: "EKU9003173C9",
legalName: "ESCUELA KEMPER URGATE",
regimenFiscal: "601",
zip: "42501",
serie: "A",
defaultClaveProdServ: "01010101",
defaultClaveUnidad: "E48",
}),
});
const merchant = await res.json();Respuesta
201 Created
{
"id": "mkq2f8v3x1t7p9d4n6c0b5rz",
"object": "merchant",
"livemode": false,
"rfc": "EKU9003173C9",
"legalName": "ESCUELA KEMPER URGATE",
"regimenFiscal": "601",
"zip": "42501",
"serie": "A",
"defaultClaveProdServ": "01010101",
"defaultClaveUnidad": "E48",
"csd": null,
"logoUrl": null,
"createdAt": "2026-08-18T16:20:03.114Z"
}Errores
| Status | code | Cuándo aparece |
|---|---|---|
| 400 | validation_error | RFC mal formado, régimen fiscal inexistente o un emisor con ese RFC ya existe. El arreglo errors indica el campo. |
| 401 | unauthorized | Falta el header Authorization o la llave es inválida. |
