curl --request DELETE \
--url https://api.emissa.com.ar/v1/arca/credentials/{id} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.emissa.com.ar/v1/arca/credentials/{id}"
headers = {"X-API-Key": "<api-key>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.emissa.com.ar/v1/arca/credentials/{id}', 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/arca/credentials/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
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/arca/credentials/{id}"
req, _ := http.NewRequest("DELETE", 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.delete("https://api.emissa.com.ar/v1/arca/credentials/{id}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.emissa.com.ar/v1/arca/credentials/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "cmt42x6k6000furi4veejuoyl",
"taxpayerId": "cmt42x6jb000curi4sz1gyeij",
"environment": "HOMOLOGACION",
"status": "REVOKED",
"cuit": "20000000001",
"certificateSubject": "CN=emissa-e2e, O=Emissa, C=AR, serialNumber=CUIT 20000000001",
"certificateIssuer": "CN=emissa-e2e, O=Emissa, C=AR, serialNumber=CUIT 20000000001",
"certificateSerial": "01",
"certificateFingerprint": "04790c756e83825857aa2a007df482eef4af7e5b4177b7d28d629f45a803e9ec",
"notBefore": "2026-08-21T07:51:04.000Z",
"notAfter": "2027-08-22T07:51:04.000Z",
"diasParaVencer": 364,
"createdAt": "2026-08-22T07:51:09.942Z",
"supersededAt": null,
"revokedAt": "2026-08-22T07:51:17.139Z"
}{
"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"
}Revocar una credencial
Es un DELETE en la ruta pero no borra la fila: la marca REVOKED. Perder el rastro de qué certificado estuvo activo sería perder la única forma de reconstruir con qué se firmó cada comprobante.
Scope de API key: credential:write. 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 DELETE \
--url https://api.emissa.com.ar/v1/arca/credentials/{id} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.emissa.com.ar/v1/arca/credentials/{id}"
headers = {"X-API-Key": "<api-key>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.emissa.com.ar/v1/arca/credentials/{id}', 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/arca/credentials/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
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/arca/credentials/{id}"
req, _ := http.NewRequest("DELETE", 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.delete("https://api.emissa.com.ar/v1/arca/credentials/{id}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.emissa.com.ar/v1/arca/credentials/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "cmt42x6k6000furi4veejuoyl",
"taxpayerId": "cmt42x6jb000curi4sz1gyeij",
"environment": "HOMOLOGACION",
"status": "REVOKED",
"cuit": "20000000001",
"certificateSubject": "CN=emissa-e2e, O=Emissa, C=AR, serialNumber=CUIT 20000000001",
"certificateIssuer": "CN=emissa-e2e, O=Emissa, C=AR, serialNumber=CUIT 20000000001",
"certificateSerial": "01",
"certificateFingerprint": "04790c756e83825857aa2a007df482eef4af7e5b4177b7d28d629f45a803e9ec",
"notBefore": "2026-08-21T07:51:04.000Z",
"notAfter": "2027-08-22T07:51:04.000Z",
"diasParaVencer": 364,
"createdAt": "2026-08-22T07:51:09.942Z",
"supersededAt": null,
"revokedAt": "2026-08-22T07:51:17.139Z"
}{
"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"
Path Parameters
Id de la credencial.
Query Parameters
Contribuyente sobre el que se opera. Obligatorio. Uno solo: repetirlo en el query string es 400 INVALID_INPUT.
"cmfa1b2c30000"
Response
La credencial, ya revocada.
Id de la credencial. Es lo que se usa para revocarla.
"cms5182zi00heurgsh49sgxwv"
A qué contribuyente pertenece.
"cms5182yf00gxurgsa7fzew8p"
Contra qué ambiente de ARCA sirve. Un certificado de homologación no funciona en producción: son trámites distintos y certificados distintos.
HOMOLOGACION, PRODUCCION "HOMOLOGACION"
ACTIVE es la que se usa para emitir. Cargar una nueva deja la anterior en SUPERSEDED; revocarla la deja en REVOKED. El historial no se borra: la trazabilidad de con qué certificado se emitió cada comprobante depende de que queden todas.
"ACTIVE"
El CUIT leído del certificado, no el declarado. Si no coincide con el del contribuyente, la carga se rechaza.
"20437136697"
El subject del certificado, tal como lo emitió ARCA. De ahí se lee el CUIT.
"CN=emissa, SERIALNUMBER=CUIT 20437136697"
Quién lo emitió. El de homologación dice Computadores Test; el de producción, no.
"CN=Computadores Test, O=AFIP"
Número de serie del certificado, en hexadecimal.
"3c9a1f2b4d5e6071"
SHA-256 del certificado. Sirve para identificarlo sin abrirlo.
"a4:1f:9c:2b:..."
Desde cuándo vale el certificado. Uno cargado antes de esta fecha no sirve para emitir todavía.
"2026-01-15T00:00:00.000Z"
Cuándo vence. Pasada esta fecha ARCA rechaza todo, así que hay que renovarlo antes: es la causa más común de que un sistema que venía facturando deje de hacerlo de un día para el otro.
"2028-01-15T00:00:00.000Z"
Días hasta notAfter. Puede ser negativo si ya venció: no se recorta a cero para que un certificado vencido se distinga de uno que vence hoy.
540
Cuándo se cargó en Emissa, en UTC.
"2026-01-20T14:05:00.000Z"
Cuándo la reemplazó otra. null mientras sea la vigente.
Cuándo se revocó a mano. null si no se revocó.