Referencia de la API

Acceso programático a las declaraciones de aduana de Uruguay. URL base https://uytrades.com/api/v1. Requiere una cuenta Pro.

Autenticación

Creá un token en /account y enviálo como token Bearer. El token se muestra una sola vez al crearlo y no se puede recuperar después — guardalo como si fuera una contraseña.

curl -H "Authorization: Bearer uytr_a1b2c3d4_xxxxxxxxxxxx" \
     "https://uytrades.com/api/v1/me"

El token hereda el plan de su dueño, así que si la suscripción vence el token deja de funcionar en los endpoints Pro sin necesidad de revocarlo.

Las cookies de sesión también sirven, por eso estos endpoints se pueden abrir en un navegador con sesión iniciada. Los scripts siempre deberían usar un token.

Límites de uso

Los límites son por cuenta, no por token — crear más claves no aumenta tu presupuesto.

Endpoints Por minuto Por hora
/dua, /dua/summary 20 60
/me, /dua/meta 60 600
Sin autenticar (solo /dua/meta es accesible) 10 60

Los dos grupos tienen presupuestos separados: agotar el de consultas no bloquea los endpoints baratos. El número por minuto es un freno de ráfaga, no el techo de throughput — ese es el de por hora.

Cada respuesta incluye tu situación actual, así el cliente nunca tiene que adivinar:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1755792000
X-RateLimit-Limit-Minute: 20
X-RateLimit-Remaining-Minute: 19

Pasado el límite recibís un 429 con un Retry-After real — los segundos que faltan para que se reinicie la ventana, no un número fijo:

HTTP/1.1 429 Too Many Requests
Retry-After: 412

{
  "error": {
    "code": "rate_limited",
    "message": "60 requests/hour exceeded.",
    "limit": 60,
    "window": "hour",
    "reset": 1755792000
  }
}

Endpoints

GET /api/v1/me

Confirma que un token funciona y qué habilita. Es la primera llamada habitual de un script, y lo más barato para consultar seguido.

curl -H "Authorization: Bearer $TOKEN" "https://uytrades.com/api/v1/me"

{"id": 42, "email": "you@example.com", "tier": "pro",
 "is_pro": true, "pro_until": "2027-01-14T00:00:00+00:00"}

GET /api/v1/dua/meta

Opciones de filtro, topes de filas y nombres de columnas. Es el único endpoint que no requiere autenticación, así un cliente puede conocer el esquema antes de que compres.

curl "https://uytrades.com/api/v1/dua/meta"

{"row_limit_max": 10000, "default_limit": 100,
 "regimens": ["ALL", "EXPORT", "IMPORT", "TRANSIT"],
 "columns": ["anio", "fecha_dua", "aduana_ing_egr", ...],
 "requires_pro": true, "is_pro": false}

GET /api/v1/dua

Filas de declaraciones filtradas, paginadas. Solo Pro.

Parámetro Obligatorio Descripción
yearEntero, desde 2016 en adelante.
regimenUno de IMPORT, EXPORT, TRANSIT, ALL.
aduananoCódigo de aduana de tres dígitos. Omitilo para todo el país.
searchnoBusca por nombre de empresa o prefijo NCM. Máximo 100 caracteres.
limitnoFilas por página, de 1 a 10,000. Por defecto 100.
offsetnoFilas a saltear. Se usa junto con limit para paginar.
curl -H "Authorization: Bearer $TOKEN" \
  "https://uytrades.com/api/v1/dua?year=2026&regimen=IMPORT&limit=100"

{"data": [{"anio": 2026, "fecha_dua": "2026-03-04", "nombre": "ACME SA", ...}],
 "pagination": {"limit": 100, "offset": 0, "returned": 100, "has_more": true},
 "query": {"year": 2026, "aduana": null, "regimen": "IMPORT", "search": null},
 "meta": {"elapsed_ms": 84.2}}

has_more es exacto: paginá hasta que sea false y nunca vas a pedir una página vacía.

GET /api/v1/dua/summary

Totales de un conjunto de filtros sin transferir las filas. Mucho más rápido que paginar todo cuando solo necesitás un conteo o una suma.

curl -H "Authorization: Bearer $TOKEN" \
  "https://uytrades.com/api/v1/dua/summary?year=2026&regimen=IMPORT"

{"row_count": 148230, "total_usd": 2841993022.14,
 "by_aduana": [{"aduana": "001", "rows": 91204, "usd": 1922841003.5}],
 "by_regimen": [{"regimen_tipo": "I", "rows": 148230}],
 "query": {"year": 2026, "aduana": null, "regimen": "IMPORT", "search": null}}

GET POST DELETE /api/v1/keys

Listá, creá y revocá tus propios tokens, para que CI y los procesos ETL puedan rotar credenciales sin pasar por el navegador. El token creado se devuelve una sola vez en el cuerpo de la respuesta.

curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name": "nightly-etl"}' \
  "https://uytrades.com/api/v1/keys"

{"id": 7, "name": "nightly-etl", "prefix": "a1b2c3d4",
 "created_at": "2026-08-21T16:04:11+00:00", "last_used_at": null,
 "token": "uytr_a1b2c3d4_xxxxxxxxxxxx"}

curl -X DELETE -H "Authorization: Bearer $TOKEN" \
  "https://uytrades.com/api/v1/keys/7"

Hasta 20 claves activas por cuenta. Revocá una para hacer lugar.

Errores

Todos los errores son JSON con el mismo formato — nunca una página HTML:

{"error": {"code": "unauthorized", "message": "Authentication required. ..."}}
Estado code Cuándo
400bad_requestFalta un parámetro o está mal formado. El mensaje indica cuál.
401unauthorizedSin token, o con un token mal formado, revocado o de una cuenta deshabilitada.
402Autenticado, pero el endpoint requiere Pro. El cuerpo incluye un upgrade_url.
404not_foundNo existe ese endpoint o recurso.
429rate_limitedLímite de uso excedido. Respetá el Retry-After.
500server_errorAlgo se rompió de nuestro lado.

Un 401 es un 401 de verdad: la API nunca redirige a una página de login, así que un script con un token muerto recibe un error que puede detectar y no una página HTML con un 200 encima.

Descargas masivas

La API JSON está pensada para consultas acotadas — una empresa, un producto, una aduana, un año. Con 60 requests por hora y 10,000 filas cada uno, no es la herramienta para bajar un año entero.

Para eso está la exportación CSV en /app/export, que entrega hasta 1,000,000 filas en un solo request y acepta el mismo token Bearer. Un año entero son un par de llamadas allá en vez de cientos acá.

curl -H "Authorization: Bearer $TOKEN" \
  "https://uytrades.com/app/export?year=2026&regimen=IMPORT&search=ACME" \
  -o acme-2026.csv

Qué es estable

Los endpoints documentados en esta página son un contrato estable. No vamos a cambiar la forma de sus respuestas ni a quitar campos sin avisar.

Todo lo demás bajo /api/v1 existe para nuestra propia aplicación web. No está versionado ni documentado, y puede cambiar o desaparecer en cualquier momento:

  • /api/v1/alerts
  • /api/v1/watches
  • /api/v1/views
  • /api/v1/export-schedules

Son visibles desde un navegador con sesión iniciada y con tu token, pero construir contra ellos es bajo tu propio riesgo.