Catálogos
Clientes
Alta, búsqueda y actualización de los receptores de tus CFDI.
Un CFDI de ingreso necesita un receptor registrado. En Facty ese receptor es un
cliente, y el clientId que devuelve esta API es lo que mandas al timbrar.
Listar y buscar
GET /api/authenticated/{org}/clients
Scope: clients.read
| Parámetro | Tipo | Descripción |
|---|---|---|
q | string | Busca en RFC y razón social, sin distinguir mayúsculas. Máx. 100 caracteres. |
limit | número | 1–500. Default 50. |
cursor | cuid | Id del último elemento de la página anterior. |
curl -s "$FACTY_HOST/api/authenticated/$FACTY_ORG/clients?q=acme&limit=20" \
-H "X-API-Key: $FACTY_KEY" | jq
{
"items": [
{
"id": "clx9aa3k80000abcd1234efgh",
"rfc": "ACM980101ABC",
"legalName": "ACME SA DE CV",
"email": "facturas@acme.mx",
"cp": "06600",
"regimenFiscal": "601",
"usoCfdiDefault": "G03",
"createdAt": "2026-03-11T15:22:04.000Z"
}
],
"nextCursor": null
}
Para resolver un RFC exacto antes de timbrar, ?q= con el RFC completo es
suficiente; verifica de todos modos el rfc de la fila que uses.
Crear
POST /api/authenticated/{org}/clients
Scope: clients.create
| Campo | Requerido | Reglas |
|---|---|---|
rfc | sí | 12 (moral) o 13 (física) caracteres. Se normaliza a mayúsculas. |
legalName | sí | Razón social como está en la Constancia de Situación Fiscal: sin el régimen de capital, sin puntos. 2–255 caracteres. |
cp | recomendado | 5 dígitos. Es el domicilio fiscal del receptor; el SAT lo valida contra su padrón. |
regimenFiscal | recomendado | Clave de 3 dígitos de c_RegimenFiscal. |
usoCfdiDefault | no | Clave de c_UsoCFDI que se usará si el timbrado no manda usoCfdi. |
email | no | Para el envío del CFDI por correo. |
upsert | no | Ver abajo. |
curl -s -X POST "$FACTY_HOST/api/authenticated/$FACTY_ORG/clients" \
-H "X-API-Key: $FACTY_KEY" -H "Content-Type: application/json" \
-d '{
"rfc": "ACM980101ABC",
"legalName": "ACME SA DE CV",
"cp": "06600",
"regimenFiscal": "601",
"usoCfdiDefault": "G03",
"email": "facturas@acme.mx"
}' | jq
Respuesta 201:
{ "id": "clx9aa3k80000abcd1234efgh", "rfc": "ACM980101ABC", "created": true }
upsert — para sincronizadores
Por default, un RFC que ya existe devuelve 409: la app web usa ese conflicto
para decirle a una persona "ya tienes un cliente con ese RFC".
Un sincronizador quiere lo contrario. Con "upsert": true, un RFC existente es
el caso de éxito:
| Resultado | HTTP | created |
|---|---|---|
| Se creó un cliente nuevo | 201 | true |
| Ya existía ese RFC | 200 | false |
Así, una corrida interrumpida converge al reintentarse en vez de fallar.
Actualizar
PATCH /api/authenticated/{org}/clients/{clientId}
Scope: clients.update. Acepta los mismos campos que el alta; manda solo los que
cambian.
curl -s -X PATCH "$FACTY_HOST/api/authenticated/$FACTY_ORG/clients/clx9aa…" \
-H "X-API-Key: $FACTY_KEY" -H "Content-Type: application/json" \
-d '{ "email": "cuentas.por.pagar@acme.mx" }' | jq
Facturar al público en general
Para el CFDI global o una venta al mostrador, el receptor es el genérico del SAT:
| Campo | Valor |
|---|---|
rfc | XAXX010101000 |
legalName | PUBLICO EN GENERAL |
regimenFiscal | 616 (Sin obligaciones fiscales) |
usoCfdiDefault | S01 (Sin efectos fiscales) |
cp | El CP de tu propio domicilio fiscal |
Ver factura global para el nodo
informacionGlobal.
Clientes en el extranjero
Si vas a exportar, el cliente admite además los datos de comercio exterior:
numRegIdTrib (tax id extranjero), residenciaFiscalPais (clave de 3 letras) y
el domicilio desglosado (extCalle, extNumExterior, extColonia,
extMunicipio, extEstado, extPais, extCodigoPostal).
Facturas pendientes de un cliente
Útil para armar un complemento de pago sin recorrer todo el historial:
GET /api/authenticated/{org}/clients/{clientId}/ppd-invoices
Scope: invoices.read. Devuelve las facturas PPD de ese cliente con saldo
pendiente. Ver Complemento de pago.