Skip to content

Endpoints — API de Solerba

Base URL: https://api.zelta.dev/v1/solerba

Todos los endpoints requieren autenticación mediante token Bearer. Consulta la para obtener tu token.

Facturas (Invoices)

Listar facturas

http
GET /invoices

Parámetros de consulta:

ParámetroTipoDescripción
pageintegerNúmero de página (default: 1)
per_pageintegerResultados por página (default: 25, max: 100)
typestringTipo de comprobante: I (ingreso), E (egreso), P (pago), T (traslado)
statusstringactive, cancelled, cancellation_pending
receptor_rfcstringFiltrar por RFC del receptor
fromdateFecha de emisión desde (YYYY-MM-DD)
todateFecha de emisión hasta (YYYY-MM-DD)
seriestringFiltrar por serie (ej: A, NC, P)
searchstringBuscar por UUID, folio, razón social del receptor
sort_bystringdate, total, folio, receptor

Ejemplo:

bash
curl -X GET "https://api.zelta.dev/v1/solerba/invoices?type=I&status=active&from=2026-03-01&to=2026-03-31" \
  -H "Authorization: Bearer {token}"

Respuesta:

json
{
  "data": [
    {
      "id": "inv_abc123",
      "uuid": "6128396c-2e3a-4e5b-8d7c-1a2b3c4d5e6f",
      "serie": "A",
      "folio": 1234,
      "type": "I",
      "status": "active",
      "date": "2026-03-11T10:30:00Z",
      "emisor": {
        "rfc": "TUA010101ABC",
        "nombre": "Tu Empresa S.A. de C.V.",
        "regimen_fiscal": "601"
      },
      "receptor": {
        "rfc": "DNA010101ABC",
        "nombre": "Distribuidora Nacional S.A. de C.V.",
        "regimen_fiscal": "601",
        "domicilio_fiscal": "06600",
        "uso_cfdi": "G03"
      },
      "conceptos": [
        {
          "clave_prod_serv": "43232408",
          "descripcion": "Licencia mensual Solerba Plan Business",
          "cantidad": 1,
          "clave_unidad": "E48",
          "valor_unitario": 1500.00,
          "importe": 1500.00,
          "descuento": 0,
          "objeto_imp": "02",
          "impuestos": {
            "traslados": [
              {
                "base": 1500.00,
                "impuesto": "002",
                "tipo_factor": "Tasa",
                "tasa": 0.16,
                "importe": 240.00
              }
            ],
            "retenciones": []
          }
        }
      ],
      "subtotal": 1500.00,
      "total_impuestos_trasladados": 240.00,
      "total_impuestos_retenidos": 0,
      "total": 1740.00,
      "moneda": "MXN",
      "tipo_cambio": 1.0,
      "metodo_pago": "PUE",
      "forma_pago": "03",
      "lugar_expedicion": "06600",
      "exportacion": "01",
      "created_at": "2026-03-11T10:30:00Z",
      "timbrado_at": "2026-03-11T10:30:05Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total_pages": 6,
    "total_count": 145
  }
}

Scope requerido: invoices:read

Crear y timbrar factura

http
POST /invoices

Cuerpo de la petición:

json
{
  "type": "I",
  "receptor": {
    "rfc": "DNA010101ABC",
    "nombre": "Distribuidora Nacional S.A. de C.V.",
    "regimen_fiscal": "601",
    "domicilio_fiscal": "06600",
    "uso_cfdi": "G03"
  },
  "conceptos": [
    {
      "clave_prod_serv": "43232408",
      "descripcion": "Licencia mensual Solerba Plan Business",
      "cantidad": 1,
      "clave_unidad": "E48",
      "valor_unitario": 1500.00,
      "descuento": 0,
      "objeto_imp": "02",
      "impuestos": {
        "traslados": [
          {
            "impuesto": "002",
            "tipo_factor": "Tasa",
            "tasa": 0.16
          }
        ]
      }
    }
  ],
  "metodo_pago": "PUE",
  "forma_pago": "03",
  "moneda": "MXN",
  "tipo_cambio": 1.0,
  "exportacion": "01",
  "serie": "A",
  "enviar_email": true
}

Respuesta (201 Created):

json
{
  "data": {
    "id": "inv_abc123",
    "uuid": "6128396c-2e3a-4e5b-8d7c-1a2b3c4d5e6f",
    "serie": "A",
    "folio": 1234,
    "type": "I",
    "status": "active",
    "subtotal": 1500.00,
    "total": 1740.00,
    "timbrado_at": "2026-03-11T10:30:05Z",
    "xml_url": "https://api.zelta.dev/v1/solerba/invoices/inv_abc123/xml",
    "pdf_url": "https://api.zelta.dev/v1/solerba/invoices/inv_abc123/pdf"
  }
}

Scope requerido: invoices:write

Validación previa al timbrado

Solerba valida todos los datos antes de enviar al PAC para timbrar. Si algún dato es incorrecto (RFC inválido, clave de producto inexistente, cálculo de impuestos inconsistente), la API retornará un error 422 con el detalle de la validación fallida.

Obtener factura

http
GET /invoices/{invoice_id}

Scope requerido: invoices:read

Obtener XML de factura

http
GET /invoices/{invoice_id}/xml

Retorna el archivo XML timbrado del CFDI.

Headers de respuesta:

Content-Type: application/xml
Content-Disposition: attachment; filename="A-1234.xml"

Scope requerido: invoices:read

Obtener PDF de factura

http
GET /invoices/{invoice_id}/pdf

Retorna la representación impresa (PDF) del CFDI.

Headers de respuesta:

Content-Type: application/pdf
Content-Disposition: attachment; filename="A-1234.pdf"

Scope requerido: invoices:read

Cancelar factura

http
POST /invoices/{invoice_id}/cancel

Cuerpo de la petición:

json
{
  "motivo": "01",
  "uuid_sustitucion": "7a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d"
}
CampoTipoDescripción
motivostringClave del motivo de cancelación SAT: 01, 02, 03, 04
uuid_sustitucionstringUUID de la factura que sustituye (requerido si motivo = 01)

Respuesta:

json
{
  "data": {
    "id": "inv_abc123",
    "uuid": "6128396c-2e3a-4e5b-8d7c-1a2b3c4d5e6f",
    "status": "cancellation_pending",
    "cancellation": {
      "motivo": "01",
      "uuid_sustitucion": "7a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d",
      "requested_at": "2026-03-11T15:00:00Z",
      "status": "pending_acceptance"
    }
  }
}

Scope requerido: invoices:write

Estados de cancelación

Después de solicitar una cancelación, el estado puede ser: pending_acceptance (esperando aceptación del receptor), cancelled (cancelado exitosamente), rejected (rechazado por el receptor). Facturas menores a $1,000 MXN se cancelan automáticamente sin esperar aceptación.

Enviar factura por correo

http
POST /invoices/{invoice_id}/send
json
{
  "email": "contabilidad@distribuidora.com",
  "include_xml": true,
  "include_pdf": true,
  "message": "Adjunto su factura correspondiente al servicio de marzo 2026."
}

Scope requerido: invoices:write

Facturación masiva (batch)

http
POST /invoices/batch

Cuerpo de la petición:

json
{
  "invoices": [
    {
      "type": "I",
      "receptor": {
        "rfc": "DNA010101ABC",
        "nombre": "Distribuidora Nacional S.A. de C.V.",
        "regimen_fiscal": "601",
        "domicilio_fiscal": "06600",
        "uso_cfdi": "G03"
      },
      "conceptos": [
        {
          "clave_prod_serv": "43232408",
          "descripcion": "Licencia mensual Solerba",
          "cantidad": 1,
          "clave_unidad": "E48",
          "valor_unitario": 1500.00,
          "objeto_imp": "02",
          "impuestos": {
            "traslados": [{ "impuesto": "002", "tipo_factor": "Tasa", "tasa": 0.16 }]
          }
        }
      ],
      "metodo_pago": "PUE",
      "forma_pago": "03",
      "moneda": "MXN"
    }
  ]
}

Respuesta:

json
{
  "data": {
    "batch_id": "batch_xyz789",
    "total_invoices": 50,
    "successful": 48,
    "failed": 2,
    "results": [
      {
        "index": 0,
        "status": "success",
        "invoice_id": "inv_abc123",
        "uuid": "6128396c-2e3a-4e5b-8d7c-1a2b3c4d5e6f"
      },
      {
        "index": 23,
        "status": "error",
        "error": "RFC del receptor no encontrado en la base de datos del SAT"
      }
    ]
  }
}

Scope requerido: invoices:write

Límites del batch

Se permiten hasta 100 facturas por petición batch. Para volúmenes mayores, divide en múltiples peticiones. Cada factura se timbra de forma independiente: si una falla, las demás continúan normalmente.


Complementos de pago

Crear complemento de pago

http
POST /payment-receipts

Cuerpo de la petición:

json
{
  "fecha_pago": "2026-03-15",
  "forma_pago": "03",
  "moneda": "MXN",
  "monto": 5000.00,
  "numero_operacion": "REF-2026031500123",
  "rfc_banco_ordenante": "BMI9704113PA",
  "cuenta_ordenante": "0123456789",
  "rfc_banco_beneficiario": "BBA830831LJ2",
  "cuenta_beneficiaria": "9876543210",
  "documentos_relacionados": [
    {
      "uuid_factura": "6128396c-2e3a-4e5b-8d7c-1a2b3c4d5e6f",
      "serie": "A",
      "folio": 1234,
      "moneda_dr": "MXN",
      "num_parcialidad": 1,
      "saldo_anterior": 17400.00,
      "importe_pagado": 5000.00,
      "saldo_insoluto": 12400.00,
      "objeto_imp_dr": "02",
      "impuestos_dr": {
        "traslados": [
          {
            "base": 4310.34,
            "impuesto": "002",
            "tipo_factor": "Tasa",
            "tasa": 0.16,
            "importe": 689.66
          }
        ]
      }
    }
  ]
}

Respuesta (201 Created):

json
{
  "data": {
    "id": "pr_def456",
    "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "serie": "P",
    "folio": 42,
    "type": "P",
    "status": "active",
    "monto": 5000.00,
    "timbrado_at": "2026-03-15T14:20:05Z",
    "xml_url": "https://api.zelta.dev/v1/solerba/payment-receipts/pr_def456/xml",
    "pdf_url": "https://api.zelta.dev/v1/solerba/payment-receipts/pr_def456/pdf"
  }
}

Scope requerido: invoices:write

Listar complementos de pago

http
GET /payment-receipts

Parámetros de consulta:

ParámetroTipoDescripción
pageintegerNúmero de página
per_pageintegerResultados por página
fromdateFecha de pago desde
todateFecha de pago hasta
receptor_rfcstringFiltrar por RFC del receptor
invoice_uuidstringFiltrar por UUID de factura relacionada

Scope requerido: invoices:read

Obtener complemento de pago

http
GET /payment-receipts/{payment_receipt_id}

Obtener XML del complemento

http
GET /payment-receipts/{payment_receipt_id}/xml

Obtener PDF del complemento

http
GET /payment-receipts/{payment_receipt_id}/pdf

Clientes (Receptores)

Listar clientes

http
GET /clients

Parámetros de consulta:

ParámetroTipoDescripción
pageintegerNúmero de página
per_pageintegerResultados por página (default: 25, max: 100)
searchstringBuscar por RFC, razón social o correo electrónico
regimen_fiscalstringFiltrar por clave de régimen fiscal
sort_bystringname, rfc, created_at, invoice_count

Ejemplo:

bash
curl -X GET "https://api.zelta.dev/v1/solerba/clients?search=distribuidora" \
  -H "Authorization: Bearer {token}"

Respuesta:

json
{
  "data": [
    {
      "id": "cli_ghi789",
      "rfc": "DNA010101ABC",
      "nombre": "Distribuidora Nacional S.A. de C.V.",
      "regimen_fiscal": "601",
      "domicilio_fiscal": "06600",
      "uso_cfdi_default": "G03",
      "email": "contabilidad@distribuidora.com",
      "telefono": "+52 55 1234 5678",
      "invoice_count": 28,
      "total_facturado": 852000.00,
      "created_at": "2025-08-15T09:00:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total_pages": 1,
    "total_count": 1
  }
}

Scope requerido: catalogs:read

Crear cliente

http
POST /clients
json
{
  "rfc": "DNA010101ABC",
  "nombre": "Distribuidora Nacional S.A. de C.V.",
  "regimen_fiscal": "601",
  "domicilio_fiscal": "06600",
  "uso_cfdi_default": "G03",
  "email": "contabilidad@distribuidora.com",
  "telefono": "+52 55 1234 5678"
}

Scope requerido: catalogs:read

Validación de RFC

Al crear un cliente, Solerba valida el RFC contra la base de datos del SAT. Si el RFC no existe o corresponde a un contribuyente en la lista 69-B, se retornará una advertencia (no un error) en la respuesta.

Obtener cliente

http
GET /clients/{client_id}

Actualizar cliente

http
PATCH /clients/{client_id}

Eliminar cliente

http
DELETE /clients/{client_id}

Atención

No se puede eliminar un cliente que tenga facturas asociadas. Primero deberás cancelar o reasignar las facturas.


Listar productos/servicios

http
GET /products

Parámetros de consulta:

ParámetroTipoDescripción
pageintegerNúmero de página
per_pageintegerResultados por página
searchstringBuscar por nombre, descripción o clave SAT
clave_prod_servstringFiltrar por clave de producto/servicio SAT
sort_bystringname, price, created_at, usage_count

Respuesta:

json
{
  "data": [
    {
      "id": "prod_jkl012",
      "nombre_interno": "Licencia Solerba Business",
      "clave_prod_serv": "43232408",
      "descripcion": "Licencia mensual plataforma de facturación electrónica",
      "clave_unidad": "E48",
      "valor_unitario": 1500.00,
      "objeto_imp": "02",
      "impuestos": {
        "traslados": [
          { "impuesto": "002", "tipo_factor": "Tasa", "tasa": 0.16 }
        ],
        "retenciones": []
      },
      "usage_count": 320,
      "created_at": "2025-06-01T10:00:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total_pages": 1,
    "total_count": 12
  }
}

Scope requerido: catalogs:read

Crear producto/servicio

http
POST /products
json
{
  "nombre_interno": "Consultoría fiscal",
  "clave_prod_serv": "80101500",
  "descripcion": "Servicio de consultoría y asesoría fiscal",
  "clave_unidad": "E48",
  "valor_unitario": 5000.00,
  "objeto_imp": "02",
  "impuestos": {
    "traslados": [
      { "impuesto": "002", "tipo_factor": "Tasa", "tasa": 0.16 }
    ],
    "retenciones": [
      { "impuesto": "001", "tipo_factor": "Tasa", "tasa": 0.10 },
      { "impuesto": "002", "tipo_factor": "Tasa", "tasa": 0.106667 }
    ]
  }
}

Scope requerido: catalogs:read

Obtener producto/servicio

http
GET /products/{product_id}

Actualizar producto/servicio

http
PATCH /products/{product_id}

Eliminar producto/servicio

http
DELETE /products/{product_id}

Búsqueda en catálogos del SAT

Buscar claves de producto/servicio

http
GET /sat-catalogs/products?search={query}

Ejemplo:

bash
curl -X GET "https://api.zelta.dev/v1/solerba/sat-catalogs/products?search=software" \
  -H "Authorization: Bearer {token}"

Respuesta:

json
{
  "data": [
    { "clave": "43232408", "descripcion": "Software de facturación" },
    { "clave": "43231500", "descripcion": "Software funcional específico de la empresa" },
    { "clave": "43232300", "descripcion": "Software de gestión de contenidos" },
    { "clave": "43231600", "descripcion": "Software de planificación de recursos empresariales" }
  ]
}

Buscar claves de unidad

http
GET /sat-catalogs/units?search={query}

Buscar regímenes fiscales

http
GET /sat-catalogs/tax-regimes

Buscar usos del CFDI

http
GET /sat-catalogs/cfdi-uses

Buscar formas de pago

http
GET /sat-catalogs/payment-forms

Scope requerido: catalogs:read


Reportes

Reporte de ingresos

http
GET /reports/income
ParámetroTipoDescripción
periodstringmonth, quarter, year
datedateFecha de referencia (YYYY-MM-DD)
formatstringjson, pdf, xlsx, csv
group_bystringclient, product, month

Ejemplo:

bash
curl -X GET "https://api.zelta.dev/v1/solerba/reports/income?period=month&date=2026-03-01&format=json&group_by=client" \
  -H "Authorization: Bearer {token}"

Respuesta:

json
{
  "data": {
    "period": "2026-03",
    "total_income": 548900.00,
    "total_credit_notes": 18300.00,
    "net_income": 530600.00,
    "invoice_count": 145,
    "breakdown": [
      {
        "client_rfc": "DNA010101ABC",
        "client_name": "Distribuidora Nacional S.A. de C.V.",
        "invoice_count": 8,
        "total": 85200.00,
        "percentage": 15.5
      }
    ]
  }
}

Scope requerido: reports:read

Reporte fiscal (impuestos)

http
GET /reports/taxes
ParámetroTipoDescripción
periodstringmonth, quarter, year
datedateFecha de referencia
formatstringjson, pdf, xlsx

Respuesta:

json
{
  "data": {
    "period": "2026-03",
    "iva_trasladado": {
      "tasa_16": { "base": 421500.00, "importe": 67440.00 },
      "tasa_8": { "base": 63700.00, "importe": 5096.00 },
      "tasa_0": { "base": 48200.00, "importe": 0 },
      "exento": { "base": 15500.00 },
      "total": 72536.00
    },
    "retenciones": {
      "isr": { "base": 125000.00, "importe": 12500.00 },
      "iva_retenido": { "base": 85000.00, "importe": 9066.70 },
      "total": 21566.70
    },
    "invoice_count": 145,
    "credit_note_count": 8
  }
}

Scope requerido: reports:read

Reporte de cancelaciones

http
GET /reports/cancellations
ParámetroTipoDescripción
periodstringmonth, quarter, year
datedateFecha de referencia
formatstringjson, pdf, xlsx

Reporte de cobranza (pagos pendientes)

http
GET /reports/receivables
ParámetroTipoDescripción
statusstringpending, partial, paid
agingstring0-30, 31-60, 61-90, 90+
formatstringjson, pdf, xlsx

Scope requerido: reports:read

Descarga masiva de XML

http
GET /reports/xml-download
ParámetroTipoDescripción
fromdateFecha desde
todateFecha hasta
typestringTipo de comprobante (opcional)

Retorna un archivo ZIP con todos los XML del periodo.

Headers de respuesta:

Content-Type: application/zip
Content-Disposition: attachment; filename="cfdi_2026-03.zip"

Scope requerido: reports:read


Webhooks

Solerba puede notificar a tu aplicación sobre eventos mediante webhooks.

Configurar webhook

http
POST /webhooks
json
{
  "url": "https://tu-app.com/webhooks/solerba",
  "events": [
    "invoice.created",
    "invoice.cancelled",
    "invoice.cancellation_accepted",
    "invoice.cancellation_rejected",
    "payment_receipt.created",
    "certificate.expiring"
  ],
  "secret": "tu_webhook_secret"
}

Eventos disponibles

EventoDescripción
invoice.createdSe timbró una nueva factura
invoice.cancelledUna factura fue cancelada exitosamente
invoice.cancellation_acceptedEl receptor aceptó la cancelación
invoice.cancellation_rejectedEl receptor rechazó la cancelación
payment_receipt.createdSe timbró un complemento de pago
certificate.expiringEl CSD vence en menos de 30 días
batch.completedUn lote de facturación masiva finalizó

Payload del webhook

json
{
  "event": "invoice.created",
  "timestamp": "2026-03-11T10:30:05Z",
  "data": {
    "id": "inv_abc123",
    "uuid": "6128396c-2e3a-4e5b-8d7c-1a2b3c4d5e6f",
    "type": "I",
    "total": 1740.00,
    "receptor_rfc": "DNA010101ABC"
  }
}

Verificación de webhooks

Cada webhook incluye un header X-Solerba-Signature con un HMAC SHA-256 del payload usando tu secret. Verifica esta firma para asegurar que el webhook proviene de Solerba.


Códigos de respuesta

CódigoDescripción
200Solicitud exitosa
201Recurso creado exitosamente (factura timbrada, cliente registrado)
204Recurso eliminado exitosamente
400Solicitud mal formada (JSON inválido, parámetros faltantes)
401No autenticado (token ausente o expirado)
403Sin permisos suficientes (scope insuficiente)
404Recurso no encontrado
409Conflicto (ej: factura ya cancelada, RFC duplicado en catálogo)
422Error de validación (RFC inválido, clave SAT inexistente, cálculo de impuestos incorrecto)
429Límite de tasa excedido
500Error interno del servidor
502Error de comunicación con el PAC (timbrado no disponible temporalmente)

Ejemplo de error de validación

json
{
  "error": "validation_error",
  "message": "Error de validación en los datos de la factura.",
  "details": [
    {
      "field": "receptor.rfc",
      "message": "El RFC 'INVALID' no tiene un formato válido. Debe ser de 12 caracteres (persona moral) o 13 (persona física)."
    },
    {
      "field": "conceptos[0].clave_prod_serv",
      "message": "La clave de producto/servicio '99999999' no existe en el catálogo del SAT."
    }
  ]
}

Integración robusta

Implementa manejo de errores para los códigos 422 (validación) y 502 (PAC no disponible). En caso de error 502, reintenta la petición después de unos segundos. Solerba automáticamente intenta con un PAC secundario si el primario no responde.

Documentación oficial de Zelta