Primeros pasos
Cinco pasos para pasar de cero a un CAE de prueba. Todo esto ocurre en homologación, así que no emitís nada con validez fiscal y podés equivocarte sin consecuencias.
Necesitás un certificado digital de AFIP para homologación, en formato .pfx o .p12, con su clave privada y autorizado para el servicio wsfe. Se genera desde el Administrador de Certificados Digitales en el portal de AFIP.
-
Crear una cuenta y obtener el token
El registro devuelve directamente tu primer token de API. Guardalo: es lo que vas a mandar en cada request de acá en adelante.
POST /api/auth/register Sin tokenbashcurl -X POST https://api.tudominio.com/api/auth/register \ -H "Content-Type: application/json" \ -d '{ "email": "sistema@miempresa.com", "password": "MiPassword123", "companyName": "Mi Empresa SRL", "requestsLimit": 1000 }'csharpvar http = new HttpClient { BaseAddress = new Uri("https://api.tudominio.com") }; var res = await http.PostAsJsonAsync("/api/auth/register", new { email = "sistema@miempresa.com", password = "MiPassword123", companyName = "Mi Empresa SRL", requestsLimit = 1000 }); var auth = await res.Content.ReadFromJsonAsync<AuthResponse>(); http.DefaultRequestHeaders.Add("X-Api-Token", auth.Token);pythonimport requests BASE = "https://api.tudominio.com" r = requests.post(f"{BASE}/api/auth/register", json={ "email": "sistema@miempresa.com", "password": "MiPassword123", "companyName": "Mi Empresa SRL", "requestsLimit": 1000, }) token = r.json()["token"]Respuesta:
json{ "ok": true, "token": "abc123XYZ...", "userId": 1, "message": null } -
Cargar el certificado de AFIP
El certificado se guarda asociado a un CUIT y un ambiente. Se envía como Base64 dentro del JSON, junto con la clave del
.pfx.POST /api/empresas/{cuit}/certificado TokenPrimero convertí el archivo a Base64:
bash# Linux / macOS base64 -w 0 certificado.pfx # Windows PowerShell [Convert]::ToBase64String([IO.File]::ReadAllBytes("certificado.pfx"))Y después subilo:
bashcurl -X POST https://api.tudominio.com/api/empresas/20409378472/certificado \ -H "X-Api-Token: abc123XYZ..." \ -H "Content-Type: application/json" \ -d '{ "ambiente": "homologacion", "razonSocial": "Mi Empresa SRL", "certificadoBase64": "MIIKXAIBAzCCChQGCSqGSIb3DQEHA...", "password": "clave_del_pfx" }'json{ "ok": true, "id": 3, "message": "Certificado guardado correctamente en base de datos", "venceEn": "15/04/2027", "diasRestantes": 455, "advertencia": null }Un certificado por ambienteEl certificado de homologación y el de producción son distintos y se cargan por separado, con el mismo CUIT pero distinto
ambiente. Si el certificado ya venció, la carga devuelve400. -
Verificar que AFIP responde
Antes de emitir, comprobá que el certificado autentica correctamente. Este endpoint hace el login WSAA real contra AFIP y devuelve el ticket.
POST /api/auth/afip/login Tokenbashcurl -X POST https://api.tudominio.com/api/auth/afip/login \ -H "X-Api-Token: abc123XYZ..." \ -H "Content-Type: application/json" \ -d '{ "ambiente": "homologacion", "servicio": "wsfe", "cuit": "20409378472" }'Si devuelve
success: truecon un token y un sign, el certificado está bien cargado y autorizado.Si acá recibís un error mencionando el certificado, revisá que esté autorizado en AFIP para el servicio
wsfe. La autorización es por servicio: tener el certificado creado no alcanza. -
Consultar el último número autorizado
AFIP exige numeración correlativa sin saltos. Consultá cuál fue el último comprobante autorizado para ese punto de venta y tipo, y emití el siguiente.
POST /api/facturacion/ultimo-numero Tokenbashcurl -X POST https://api.tudominio.com/api/facturacion/ultimo-numero \ -H "X-Api-Token: abc123XYZ..." \ -H "Content-Type: application/json" \ -d '{ "ambiente": "homologacion", "cuit": "20409378472", "puntoVenta": 1, "tipoComprobante": 6 }'json{ "success": true, "errorMessage": null, "puntoVenta": 1, "tipoComprobante": 6, "ultimoNumero": 41 }El próximo comprobante será el 42.
-
Emitir el primer comprobante
Una factura B a consumidor final por $1.210 (neto $1.000 + IVA 21%). Si no mandás
numeroComprobante, la API toma el siguiente disponible.POST /api/facturacion/emitir Tokenbashcurl -X POST https://api.tudominio.com/api/facturacion/emitir \ -H "X-Api-Token: abc123XYZ..." \ -H "Content-Type: application/json" \ -d '{ "ambiente": "homologacion", "cuit": "20409378472", "puntoVenta": 1, "tipoComprobante": 6, "concepto": 1, "tipoDocumento": 99, "numeroDocumento": 0, "fechaComprobante": "2026-08-20", "importeTotal": 1210.00, "importeNetoGravado": 1000.00, "importeExento": 0, "importeIVA": 210.00, "importeTributos": 0, "monedaId": "PES", "monedaCotizacion": 1.0, "condicionIVAReceptorId": 5, "ivas": [ { "id": 5, "baseImponible": 1000.00, "importe": 210.00 } ] }'Y ahí está el CAE:
json{ "success": true, "errorMessage": null, "cae": "76234567890123", "caeVencimiento": "2026-08-30T00:00:00", "numeroComprobante": 42, "puntoVenta": 1, "tipoComprobante": 6, "fechaProceso": "2026-08-20T14:32:11", "resultado": "A", "observaciones": [], "errores": [], "esConsultaExistente": false }Listoresultado: "A"significa aprobado. Si viene"R", el comprobante fue rechazado y el motivo está enerrores[].
Datos de prueba para homologación
Para probar sin un certificado propio, AFIP publica un CUIT de testing:
| Dato | Valor |
|---|---|
| CUIT de prueba | 20409378472 |
| Puntos de venta habituales | 1, 2, 3, 4, 5 |
| Tipo de comprobante | 6 (Factura B) |
| Receptor | tipoDocumento: 99, numeroDocumento: 0 (consumidor final) |
Pasar a producción
Cuando el circuito funciona en homologación, para ir a producción hace falta:
- Generar el certificado de producción en el portal de AFIP (es otro trámite, distinto del de testing).
- Autorizarlo para cada web service que uses.
- Dar de alta los puntos de venta en producción.
- Subir el certificado con
"ambiente": "produccion". - Cambiar el campo
ambientede tus requests.
Un comprobante autorizado en producción existe ante AFIP y solo se revierte con una nota de crédito. Verificá el ambiente de cada request antes del primer despliegue.