curl --request GET \
--url https://api.emissa.com.ar/v1/invoices/search \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.emissa.com.ar/v1/invoices/search"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.emissa.com.ar/v1/invoices/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.emissa.com.ar/v1/invoices/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.emissa.com.ar/v1/invoices/search"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.emissa.com.ar/v1/invoices/search")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.emissa.com.ar/v1/invoices/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "cmt42xaaj000turi4uvmjb298",
"taxpayerId": "cmt42x6jb000curi4sz1gyeij",
"environment": "HOMOLOGACION",
"origin": "API",
"externalReference": null,
"cbteTipo": 1,
"cbteTipoNombre": "FACTURA_A",
"letra": "A",
"concepto": 1,
"conceptoNombre": "PRODUCTOS",
"salePoint": 1,
"number": 1,
"comprobante": "0001-00000001",
"issueDate": "2026-08-22",
"emitter": {
"cuit": "20000000001",
"name": "Estudio Contable SRL",
"vatStatus": "Responsable Inscripto",
"address": "Av. Corrientes 1234, CABA",
"grossIncomeTax": "901-123456-01",
"activityStartDate": "2020-03-01"
},
"receiver": {
"docTipo": 80,
"docTipoNombre": "CUIT",
"docNro": "30000000007",
"name": "Cliente Mayorista SA",
"vatConditionId": 1,
"vatConditionNombre": "IVA_RESPONSABLE_INSCRIPTO",
"address": null
},
"currency": "PES",
"exchangeRate": "1",
"totals": {
"netAmount": "1000.00",
"nonTaxedAmount": "0.00",
"exemptAmount": "0.00",
"vatAmount": "210.00",
"otherTaxesAmount": "0.00",
"totalAmount": "1210.00"
},
"vatBreakdown": [
{
"vatRateId": 5,
"vatRatePercent": 21,
"baseAmount": "1000.00",
"vatAmount": "210.00"
}
],
"taxes": [],
"saleCondition": null,
"saleConditionNombre": null,
"servicePeriod": null,
"status": "AUTHORIZED",
"cae": "70001000000001",
"caeExpiresAt": "2026-09-01",
"cancelledByInvoiceId": null,
"associations": [],
"optionals": [],
"observations": [],
"rechazoArca": null,
"items": [
{
"position": 1,
"description": "Servicio de consultoría",
"unit": "UNIDADES",
"quantity": "1",
"unitPrice": "1000",
"tratamiento": "GRAVADO",
"vatRateId": 5,
"vatRatePercent": 21,
"netAmount": "1000.00",
"vatAmount": "210.00"
}
],
"customer": {
"id": "cmt42x8pf000ruri4bt2gjtai",
"documentType": "CUIT",
"documentNumber": "30000000007",
"name": "Cliente Mayorista SA",
"vatCondition": "IVA_RESPONSABLE_INSCRIPTO"
},
"arcaMetadata": {
"service": "wsfev1",
"resultado": "A",
"authorized": true,
"observaciones": 0
},
"createdAt": "2026-08-22T07:51:14.780Z"
}
],
"pagination": {
"limit": 25,
"hasMore": false,
"nextCursor": null
}
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}Listar comprobantes
Paginación keyset, ordenada por fecha de creación descendente. Para la página siguiente se manda el pagination.nextCursor tal cual vino, en ?cursor=.
No hay offset a propósito: quien factura mientras pagina movería las filas debajo del cursor y vería un comprobante dos veces mientras se pierde otro. Con keyset eso no pasa.
Se filtra por tipo, estado (?status=PENDING&status=UNKNOWN), punto de venta, número y rango de fechas, y se busca por texto con ?q= contra el número, el receptor, su documento y el CAE.
?withTotal=true agrega pagination.total. No viene por defecto: es un COUNT(*) sobre el histórico filtrado y no hace falta para paginar. Conviene pedirlo en la primera página, no en cada una.
Scope de API key: invoice:read. Una key sin ese scope recibe 403 API_KEY_INSUFFICIENT_SCOPE, aunque el rol de quien la creó lo permita: el permiso efectivo es la intersección de los dos.
curl --request GET \
--url https://api.emissa.com.ar/v1/invoices/search \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.emissa.com.ar/v1/invoices/search"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.emissa.com.ar/v1/invoices/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.emissa.com.ar/v1/invoices/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.emissa.com.ar/v1/invoices/search"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.emissa.com.ar/v1/invoices/search")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.emissa.com.ar/v1/invoices/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "cmt42xaaj000turi4uvmjb298",
"taxpayerId": "cmt42x6jb000curi4sz1gyeij",
"environment": "HOMOLOGACION",
"origin": "API",
"externalReference": null,
"cbteTipo": 1,
"cbteTipoNombre": "FACTURA_A",
"letra": "A",
"concepto": 1,
"conceptoNombre": "PRODUCTOS",
"salePoint": 1,
"number": 1,
"comprobante": "0001-00000001",
"issueDate": "2026-08-22",
"emitter": {
"cuit": "20000000001",
"name": "Estudio Contable SRL",
"vatStatus": "Responsable Inscripto",
"address": "Av. Corrientes 1234, CABA",
"grossIncomeTax": "901-123456-01",
"activityStartDate": "2020-03-01"
},
"receiver": {
"docTipo": 80,
"docTipoNombre": "CUIT",
"docNro": "30000000007",
"name": "Cliente Mayorista SA",
"vatConditionId": 1,
"vatConditionNombre": "IVA_RESPONSABLE_INSCRIPTO",
"address": null
},
"currency": "PES",
"exchangeRate": "1",
"totals": {
"netAmount": "1000.00",
"nonTaxedAmount": "0.00",
"exemptAmount": "0.00",
"vatAmount": "210.00",
"otherTaxesAmount": "0.00",
"totalAmount": "1210.00"
},
"vatBreakdown": [
{
"vatRateId": 5,
"vatRatePercent": 21,
"baseAmount": "1000.00",
"vatAmount": "210.00"
}
],
"taxes": [],
"saleCondition": null,
"saleConditionNombre": null,
"servicePeriod": null,
"status": "AUTHORIZED",
"cae": "70001000000001",
"caeExpiresAt": "2026-09-01",
"cancelledByInvoiceId": null,
"associations": [],
"optionals": [],
"observations": [],
"rechazoArca": null,
"items": [
{
"position": 1,
"description": "Servicio de consultoría",
"unit": "UNIDADES",
"quantity": "1",
"unitPrice": "1000",
"tratamiento": "GRAVADO",
"vatRateId": 5,
"vatRatePercent": 21,
"netAmount": "1000.00",
"vatAmount": "210.00"
}
],
"customer": {
"id": "cmt42x8pf000ruri4bt2gjtai",
"documentType": "CUIT",
"documentNumber": "30000000007",
"name": "Cliente Mayorista SA",
"vatCondition": "IVA_RESPONSABLE_INSCRIPTO"
},
"arcaMetadata": {
"service": "wsfev1",
"resultado": "A",
"authorized": true,
"observaciones": 0
},
"createdAt": "2026-08-22T07:51:14.780Z"
}
],
"pagination": {
"limit": 25,
"hasMore": false,
"nextCursor": null
}
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}{
"statusCode": 401,
"errorCode": "UNAUTHORIZED",
"message": "No autorizado",
"timestamp": "2026-07-26T18:30:00.000Z",
"path": "/v1/invoices/authorize",
"details": "<string>",
"retryable": false,
"retryAfterSeconds": 43200,
"requestId": "0f2c1a5e-1d9b-4c7a-9a55-7f1a2b3c4d5e"
}Authorizations
API key de integración. El modo va en el prefijo: emi_test_ opera contra homologación, emi_live_ contra producción. Después, 64 hexadecimales.
Headers
El producto que origina el pedido (inmos, por ejemplo). Opcional, sólo con API key. Formato ^[a-z0-9-]{1,32}$; otro valor da 400 INVALID_INPUT. Queda en el comprobante, en el consumo y en el registro de pedidos.
Con una key sin producto es sólo atribución: no autoriza ni restringe nada. Con una key atada a un producto el pedido se etiqueta con el de la key aunque no mandes la cabecera, y si mandás otro valor la respuesta es 403 API_KEY_PRODUCTO_DISTINTO.
^[a-z0-9-]{1,32}$"inmos"
Query Parameters
Contribuyente sobre el que se opera. Obligatorio. Uno solo: repetirlo en el query string es 400 INVALID_INPUT.
"cmfa1b2c30000"
El código de ARCA, no la etiqueta.
1, 2, 3, 6, 7, 8, 11, 12, 13 1
Uno o varios. Se repite el parámetro (?status=PENDING&status=UNKNOWN) o se separan con comas. Un estado que no existe da 400, no una lista vacía.
PENDING y UNKNOWN juntos son los comprobantes sin resolver: el número ya está tomado y no se sabe si ARCA lo autorizó.
DRAFT, PENDING, AUTHORIZED, REJECTED, UNKNOWN, CANCELLED ["PENDING", "UNKNOWN"]
x >= 11
x >= 17
Resuelve contra el número del comprobante (7 o 0001-00000007), el nombre del receptor, su documento y el CAE.
Los identificadores se buscan completos; el nombre, por fragmento y sin distinguir mayúsculas. El CUIT se puede escribir con guiones: se normaliza antes de comparar.
El Request ID no entra acá: hoy no se guarda en el comprobante, así que no hay contra qué resolverlo.
120"20-43713669-7"
Resuelve por igualdad exacta contra la referencia que mandaste al emitir. Devuelve 0 o 1 comprobante: es única por contribuyente y ambiente. Para buscar por fragmento está q.
64"COBRO-8842"
Por dónde entró: API lo emitió una integración, PANEL se cargó a mano. Los comprobantes emitidos antes de que se registrara el origen no aparecen bajo ningún valor: no se sabe por dónde entraron. Sin el filtro siguen listándose.
API, PANEL "API"
El producto que originó el comprobante (X-Emissa-Producto al emitir). Los emitidos sin la cabecera, desde el panel o antes de que existiera no aparecen bajo ningún valor; sin el filtro siguen listándose.
32^[a-z0-9-]{1,32}$"inmos"
Cuántos comprobantes por página. Cada uno trae sus items, su desglose de IVA y sus asociaciones, así que el tope no es arbitrario.
1 <= x <= 100El pagination.nextCursor de la respuesta anterior, tal cual vino. Es opaco: no lo interpretes ni lo construyas a mano. Un cursor ilegible da 400 INVALID_CURSOR.
Fecha de emisión desde, inclusive.
"2026-01-01"
Fecha de emisión hasta, inclusive.
"2026-12-31"
Agrega pagination.total con cuántos comprobantes matchean la consulta, ignorando el cursor.
Cuesta un COUNT(*) sobre el histórico filtrado, así que hay que pedirlo. Conviene en la primera página —para mostrar "248 resultados" u ofrecer "seleccionar los 248"— y no en cada página siguiente: el total no cambia mientras se pagina.