Documentación técnica

API externa de emisión de comprobantes

Integrá tu sistema con FACTUskill para emitir comprobantes con CAE de ARCA (AFIP) automáticamente, sin carga manual. Disponible para empresas con plan Avanzado o Empresas.

Autenticación y requisitos

Antes de integrar, confirmá con tu estudio contable que se cumplen estos tres requisitos:

  1. Plan habilitado. La empresa debe tener asignado un plan de FACTUskill que incluya la API externa (hoy: planes «Avanzado» y «Empresas»).
  2. Plan vigente. La fecha de vigencia del plan no puede estar vencida.
  3. Empresa activa dentro del sistema.

Si alguno de estos tres no se cumple, todas las requests devuelven 403.

API Key. El administrador del estudio contable genera la key desde el panel de FACTUskill (edición de la empresa). Solo existe una key activa por empresa a la vez — generar una nueva revoca automáticamente la anterior. La key se muestra en texto plano una única vez, al generarla; después solo se ve su prefijo.

Cada request debe incluir:

Authorization: Bearer <api_key>
Content-Type: application/json

Request

POST https://admin.factuskill.com.ar/api/v1/comprobantes/emitir
CampoTipoObligatorioDescripción
referencia_externastringIdentificador único propio de esta operación (pedido, venta, etc.). Es la clave de idempotencia — ver más abajo.
cbte_tipointTipo de comprobante AFIP (ver catálogo).
conceptointNo (default 2)1 = Productos, 2 = Servicios, 3 = Productos y Servicios.
fecha_emisionstring (AAAA-MM-DD)No (default hoy)
doc_tipointTipo de documento del receptor (ver catálogo).
doc_nrostringNúmero de documento del receptor (solo dígitos).
cliente_idintNoId de Cliente ya cargado en FACTUskill, si se conoce.
cliente_nombrestringRazón social o nombre del receptor.
cliente_domiciliostringNo
cliente_emailstringNo
cliente_telefonostringNo
fecha_serv_desde, fecha_serv_hasta, fecha_vto_pagostring (AAAA-MM-DD)Sí si concepto > 1Obligatorias para Servicios.
itemsarraySí (mín. 1)Ver tabla de abajo.

Cada elemento de items:

CampoTipoObligatorioDescripción
descripcionstring
cantidadfloatNo (default 1)
precio_unitariofloatPrecio con IVA incluido.
iva_idintNo (default 5 = 21%)Ver catálogo.
unidad_medidastringNo (default 07 = unidades)

Ejemplo de body:

{
  "referencia_externa": "pedido-00458",
  "cbte_tipo": 11,
  "concepto": 1,
  "doc_tipo": 99,
  "doc_nro": "0",
  "cliente_nombre": "Consumidor Final",
  "items": [
    {
      "descripcion": "Servicio de consultoría",
      "cantidad": 1,
      "precio_unitario": 15000,
      "iva_id": 5
    }
  ]
}

Respuestas

201 — Emitido con éxito (primera vez):

{
  "ok": true,
  "comprobante_id": 4995,
  "cae": "86383707667201",
  "cae_vto": "2026-09-28",
  "nro_formateado": "1001-00000089",
  "url_publica": "https://admin.factuskill.com.ar/comprobante/ver?h=...",
  "imp_total": 15000,
  "cliente_email": null,
  "cliente_tel": null
}

200 — Idempotente (ya se había procesado esa referencia_externa antes; no se volvió a tocar AFIP):

{ "ok": true, "idempotente": true, "comprobante_id": 4995, "cae": "86383707667201", "...": "..." }

200 con ok: false — AFIP rechazó el comprobante (no es un error HTTP, la request en sí era válida):

{
  "ok": false,
  "error": "AFIP rechazó el comprobante.",
  "error_code": 10000,
  "observaciones": "[10000] NO AUTORIZADO A EMITIR COMPROBANTES..."
}

Errores HTTP:

CódigoCausa
400Falta referencia_externa, faltan datos obligatorios, body no es JSON válido, o la condición IVA del receptor no es compatible con el tipo de comprobante (normativa RG 5616).
401Falta el header Authorization, o la API Key es inválida / fue revocada.
403Empresa inactiva, sin plan asignado, plan sin la API habilitada, plan vencido, o límite mensual de comprobantes del plan alcanzado.
429Se superó el límite de requests por minuto de esta API Key.
500Error consultando AFIP (timeout, certificado, etc.) o error interno. Es seguro reintentar con la misma referencia_externa.

Idempotencia y rate limiting

Idempotencia. referencia_externa debe ser única por empresa (un pedido, una venta, un cobro — lo que identifique la operación en tu sistema). Si se repite una request con la misma referencia_externa, FACTUskill no vuelve a emitir en AFIP: devuelve la misma respuesta que generó la primera vez, marcada con "idempotente": true. Esto es lo que permite reintentar con seguridad ante un timeout o un corte de red sin arriesgarse a duplicar una factura real.

Rate limiting. Cada API Key tiene un límite de requests por minuto, configurable por el estudio contable al generarla (si no se configura, aplica el default del sistema). Al superarlo, la respuesta es 429 con el límite vigente en el mensaje. Se recomienda esperar antes de reintentar (backoff) en vez de reintentar inmediatamente.

Ejemplo completo

cURL:

curl -X POST https://admin.factuskill.com.ar/api/v1/comprobantes/emitir \
  -H "Authorization: Bearer TU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "referencia_externa": "pedido-00458",
    "cbte_tipo": 11,
    "concepto": 1,
    "doc_tipo": 99,
    "doc_nro": "0",
    "cliente_nombre": "Consumidor Final",
    "items": [{ "descripcion": "Servicio", "cantidad": 1, "precio_unitario": 15000, "iva_id": 5 }]
  }'

PowerShell:

$headers = @{ "Authorization" = "Bearer TU_API_KEY" }
$body = @{
    referencia_externa = "pedido-00458"
    cbte_tipo = 11
    concepto = 1
    doc_tipo = 99
    doc_nro = "0"
    cliente_nombre = "Consumidor Final"
    items = @(@{ descripcion = "Servicio"; cantidad = 1; precio_unitario = 15000; iva_id = 5 })
} | ConvertTo-Json

Invoke-RestMethod -Uri "https://admin.factuskill.com.ar/api/v1/comprobantes/emitir" -Method Post -Headers $headers -ContentType "application/json" -Body $body

Manejo de errores recomendado:

  • Generá siempre referencia_externa de forma determinística a partir de tu propia operación (no un valor aleatorio en cada intento) — así un reintento automático después de un timeout es seguro.
  • Ante 500 o timeout de red: reintentar con la misma referencia_externa es seguro gracias a la idempotencia.
  • Ante 400, 401 o 403: no reintentar sin corregir la causa (son errores de la request, no van a resolverse solos).
  • Ante 429: esperar y reintentar con backoff, respetando el límite indicado en el mensaje.
  • Un 200 con "ok": false significa que AFIP rechazó el comprobante en sí (dato incorrecto, receptor no habilitado, etc.) — revisá observaciones antes de reintentar.
¿Tu empresa todavía no tiene la API habilitada, o necesitás ayuda para integrarla? Consultanos.