Autenticación y contexto
La API usa HTTP Bearer con la API_KEY de tu ApiAccess.
Authorization: Bearer <API_KEY>Obtener la API_KEY
Sección titulada «Obtener la API_KEY»- Ingresá al panel de Host Factura con tu usuario administrador.
- En Configuración → API, creá un nuevo Access. Ahí mismo elegís los alcances de la credencial (ver más abajo) y, opcionalmente, la asociás a una sucursal específica para que las emisiones queden atribuidas a esa sucursal sin necesidad de header.
- Al crearlo se muestra una sola vez la API_KEY. Guardala en un lugar seguro (por ejemplo, un gestor de secretos como 1Password o AWS Secrets Manager).
- Si la perdés o sospechás filtración, rotala desde el panel: la anterior se invalida en el acto.
Headers comunes
Sección titulada «Headers comunes»| Header | Tipo | Cuándo |
|---|---|---|
Authorization: Bearer <API_KEY> | obligatorio | Siempre |
x-cuenta-id: <uuid> | opcional | Sólo credenciales de revendedor: operar sobre una subcuenta de la cartera |
x-branch-id: <uuid> | opcional | Operar contra una sucursal específica cuando el ApiAccess es global |
x-point-id: <uuid> | opcional | Cuando la sucursal tiene 2+ puntos de emisión activos |
Idempotency-Key: <clave> | opcional | En los POST de /v1/pagos (obligatoria en /v1/pagos/cobrar) |
X-Request-ID: <uuid> | opcional | Si lo enviás se respeta; si no, lo genera el servidor |
Alcances
Sección titulada «Alcances»Cada credencial lleva una lista de alcances y cada operación exige uno o varios. La semántica es OR: alcanza con tener alguno de los que la operación declara.
| Alcance | Qué habilita |
|---|---|
cfe:emitir | Emitir y validar CFE, mandar la representación impresa por correo y emitir el comprobante de un cobro (al cobrar o después). Consume numeración |
cfe:leer | Listar CFE emitidos, consultar su estado en DGI y descargar el PDF. No emite nada |
recibidos:leer | Listar y consultar los CFE que la empresa recibió de sus proveedores y descargar su PDF y su XML firmado. Ver CFE recibidos |
consultas | Consultar un RUT, el padrón de emisores, las cotizaciones del BCU y el echo |
clientes:leer | Listar, buscar y consultar los clientes de la empresa. Sólo lectura |
clientes:escribir | Crear o actualizar un cliente (upsert). Incluye leerlos |
pagos:leer | Listar y consultar links y cobros, el resumen y el comprobante de pago. Sólo lectura |
pagos:cobrar | Crear links, cobrar con tarjeta registrada, anular. Mueve plata real. Pedir el comprobante del cobro exige además cfe:emitir |
pagos:tarjetas | Alta, listado y baja de tarjetas del cliente |
pagos:suscripciones | Planes y suscripciones. Una suscripción activa cobra sola |
webhooks:gestionar | Listar, probar y dar de baja suscripciones de webhook |
En la Referencia OpenAPI, cada operación declara los suyos en la extensión x-alcance. El panel
muestra, debajo de cada permiso, las operaciones que habilita.
Lo que la empresa admite
Sección titulada «Lo que la empresa admite»Además de estar en la credencial, el alcance tiene que estar disponible para la empresa dueña de la credencial. El panel sólo ofrece los disponibles:
| Alcances | Disponibles si… |
|---|---|
cfe:* | La empresa emite comprobantes electrónicos |
pagos:* | La empresa tiene habilitados los cobros con tarjeta |
webhooks:gestionar | La cuenta es proveedora (revendedor) |
consultas, clientes:*, recibidos:leer | Siempre (aunque la empresa no emita) |
Una cuenta proveedora admite todos; lo que puede hacer en cada empresa de su cartera lo sigue decidiendo lo
que esa empresa tenga habilitado. Si una credencial tiene un alcance que su empresa no admite (por ejemplo,
una credencial con acceso total en una empresa que no es proveedora, contra /v1/webhooks), la respuesta es
403 API_ALCANCE_NO_DISPONIBLE, con error.details.alcances y error.details.motivo
(PAGOS_NO_HABILITADO, FACTURACION_NO_HABILITADA o SOLO_REVENDEDOR).
Credenciales anteriores al modelo de alcances
Sección titulada «Credenciales anteriores al modelo de alcances»Una credencial creada antes de que existieran los alcances tiene acceso total y sigue funcionando igual. La restricción es opt-in: hay que editar la credencial en el panel para acotarla, y el panel la muestra como “acceso total (credencial anterior)”.
Una credencial nueva creada sin elegir alcances nace con el preset Solo facturación
(cfe:emitir, cfe:leer, consultas): no puede cobrar ni tocar tarjetas hasta que se lo habilites. Tampoco
trae recibidos:leer: para leer los comprobantes recibidos hay que marcarlo.
Cuando falta un alcance
Sección titulada «Cuando falta un alcance»{ "error": { "code": "API_ALCANCE_INSUFICIENTE", "message": "La credencial de API no tiene ninguno de los alcances necesarios para esta operación (pagos:cobrar)", "requerido": ["pagos:cobrar"] }, "requestId": "3f6b1c2e-9a4d-4f80-bc11-7e2d5a8f0c31"}requerido va dentro de error, al lado de code y message. No reintentes: un 403 de alcance no
se arregla con el tiempo, hay que editar la credencial.
Sucursales y puntos de emisión
Sección titulada «Sucursales y puntos de emisión»- Si tu
ApiAccessestá fijado a una sucursal, todas las emisiones se atribuyen a esa sucursal. Enviarx-branch-idcon otro valor devuelve403 API_ACCESS_BRANCH_MISMATCH. - Si tu
ApiAccesses global, podés enviarx-branch-idpara apuntar a una sucursal; sin el header se asume la casa central. - Si la sucursal resuelta tiene 2 o más puntos de emisión activos,
x-point-ides obligatorio. Con uno solo, se selecciona automáticamente.
La sucursal nunca sale del cuerpo: sucursalId y puntoEmisionId en el JSON no tienen efecto.
Revendedores: operar sobre una subcuenta
Sección titulada «Revendedores: operar sobre una subcuenta»Si tu cuenta es proveedora (revendedor de facturación electrónica), tu credencial puede operar sobre cualquier subcuenta de tu cartera mandando:
x-cuenta-id: <uuid de la subcuenta>La cuenta efectiva del request pasa a ser esa: se emite con sus CAE y su certificado, se cobra con su configuración, y el request queda registrado en su log. Sin la cabecera, operás sobre tu propia cuenta.
- Una subcuenta que no está en tu cartera devuelve
403 API_CUENTA_FUERA_DE_CARTERA— el mismo código exista o no la cuenta. - Tu credencial tiene que ser de cuenta (sin sucursal fijada) para poder delegar.
- Es la única forma de cambiar de cuenta: no hay ningún parámetro ni campo de cuerpo que la elija. Para empresas que no son de tu cartera, usá una API_KEY por empresa.
Idempotencia
Sección titulada «Idempotencia»Todos los POST de /v1/pagos aceptan Idempotency-Key con el mismo contrato. Es opcional en todos
salvo POST /v1/pagos/cobrar, que la exige.
| Situación | Respuesta |
|---|---|
| Sin cabecera | La operación se ejecuta normalmente; cada llamada es nueva |
| Misma clave + mismo cuerpo | Se replica la respuesta original con meta.reusada: true, sin re-ejecutar |
| Misma clave + otro cuerpo, u otro endpoint | 409 PAGOS_IDEMPOTENCY_KEY_CONFLICTO |
| Misma clave con la operación en curso | 409 PAGOS_IDEMPOTENCY_EN_CURSO |
- Forma de la clave: 8 a 128 caracteres de
A-Za-z0-9._:~-. - Ventana: 24 horas.
- Sólo se cachean las respuestas 2xx. Un 4xx/5xx libera la clave: podés corregir el cuerpo y reintentar con la misma clave sin perder la protección.
Habilitaciones de la cuenta
Sección titulada «Habilitaciones de la cuenta»Dos interruptores comerciales que habilita administración y que la API no puede cambiar:
| Gate | Qué corta | Error |
|---|---|---|
| Módulo de cobros | Todo /v1/pagos/**, incluida la configuración | 403 PAGOS_NO_HABILITADO |
| Facturación electrónica | La emisión de CFE | 403 FACTURACION_NO_HABILITADA |
Una cuenta sin facturación electrónica puede cobrar pero no emitir: la única política fiscal posible
es solo_registrar y el papel que se le entrega al comprador es el comprobante de pago no fiscal.
Estructura de respuestas
Sección titulada «Estructura de respuestas»Éxito:
{ "data": {}, "meta": { "paginacion": { "pagina": 1, "porPagina": 20, "totalFilas": 87, "totalPaginas": 5 } } }Error:
{ "error": { "code": "CODIGO_ESTABLE", "message": "Mensaje legible en español", "details": {} }, "requestId": "uuid-de-correlación"}Usá el campo code (SCREAMING_SNAKE_CASE, estable) para lógica condicional; el message puede cambiar entre
versiones. Incluí el requestId en tickets de soporte. La paginación y los filtros van en español:
pagina, porPagina, ordenarPor, orden, busqueda.
Rate limits
Sección titulada «Rate limits»- Cuentas estándar: 60 requests/minuto por
ApiAccess. - Cuentas proveedor: 600 requests/minuto.
Cada respuesta incluye RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset. Al excederlo recibís
429 API_RATE_LIMITED con header Retry-After.
El detalle de todos los códigos de error globales está en la Referencia OpenAPI.