anonym.es

API de enlaces

La API crea enlaces cortos anónimos, devuelve sus estadísticas de clics, cambia sus ajustes y los borra. Las peticiones y las respuestas usan JSON. CORS está habilitado, así que las llamadas funcionan también desde código del navegador.

Dirección base:

http://anonym.es/api/v1

Inicio rápido

Para crear un enlace corto, envía la dirección de destino:

curl -X POST http://anonym.es/api/v1/links \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/article"}'

Esta llamada no requiere token. Sin él, el enlace se crea como enlace de invitado dentro de la cuota Free de tu dirección IP.

Con un token de cuenta la misma llamada guarda el enlace en tu panel y lo cuenta en la cuota de tu plan:

curl -X POST http://anonym.es/api/v1/links \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/article"}'

La respuesta contiene la dirección corta, el id del enlace y el token que gestiona este enlace. Guarda el token: hará falta para leer o borrar el enlace más adelante.

{
  "ok": true,
  "link": {
    "id": 4821,
    "short": "http://anonym.es/k7m2q",
    "url": "https://example.com/article",
    "status": "active",
    "password": false,
    "created_at": "2026-09-05T14:02:11Z",
    "expires_at": null,
    "max_hits": null,
    "self_destruct": false,
    "delay": null,
    "no_countdown": false,
    "adult": false,
    "note": null,
    "tags": [],
    "clicks": 0,
    "uniques": 0
  },
  "token": "3f9c1b7e2d4a4c0e9b8f7a6d5c4b3a21",
  "left": 4
}

Campos del objeto enlace

Todos los endpoints que devuelven un enlace usan esta estructura. Las marcas de tiempo son ISO 8601 en UTC. Los contadores clicks y uniques abarcan toda la vida del enlace.

CampoTipoQué hace
idintegerId numérico del enlace, usado por las demás llamadas.
shortstringLa dirección corta para compartir.
urlstring | nullEl destino, null en un enlace de solo nota.
statusstringactive | expired | exhausted (límite de visitas alcanzado) | flagged (destino en una lista de seguridad) | banned.
passwordbooleanLos visitantes deben introducir una contraseña.
created_atstringISO 8601, UTC.
expires_atstring | nullCuándo caduca el enlace, null = sin caducidad.
max_hitsinteger | nullLímite de visitas, null = sin límite.
self_destructbooleanEl enlace se borra solo, de forma definitiva, al alcanzar el límite o la duración.
delayinteger | nullSegundos en la página de reenvío, null = valor del plan, 0 = inmediato.
no_countdownbooleanLa página de reenvío no muestra cuenta atrás y espera un clic en la dirección.
adultbooleanVisitors confirm being 18 or older before the forwarding page.
notestring | nullLa nota mostrada en la página de reenvío.
tagsstring[]Etiquetas, en minúsculas.
clicksintegerVisitas durante toda la vida del enlace.
uniquesintegerVisitantes únicos (uno por dirección y día) durante toda la vida del enlace.

Autorización

Las peticiones autorizadas llevan el token en la cabecera Authorization. Como alternativa se acepta la cabecera X-API-Key. Los tokens nunca se pasan en la query string.

Authorization: Bearer YOUR_TOKEN
TokenDónde obtenerloPara qué sirve
Token de cuentaEn el panelTodos los enlaces de la cuenta, con los derechos del plan
Token de enlaceSe devuelve al crear un enlaceUn enlace concreto, con los derechos del plan Free

Un token de cuenta empieza por anon_. Un token de enlace consta de 32 caracteres. Generar un nuevo token de cuenta invalida el anterior.

Ejemplo:

curl http://anonym.es/api/v1/me \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN"

Generar un token de cuenta en el panel

Endpoints

El cuerpo de la petición puede enviarse como application/json o como application/x-www-form-urlencoded. Los nombres de los parámetros y los códigos de error son idénticos en todos los endpoints.

MétodoRutaTokenCosteQué hace
GET/api/v1opcional 1Sobre esta API: versión, direcciones de la documentación y del esquema.
POST/api/v1/linksopcional 5 + 1/urlCrear un enlace, o hasta 50 a la vez. Sin token: como invitado, con la cuota Free. Devuelve el enlace con su token.
GET/api/v1/names/checkopcional 2¿Está disponible este nombre propio? Sugerencias cuando está ocupado.
GET/api/v1/linksde cuenta 2Los enlaces de la cuenta, los más nuevos primero.
GET/api/v1/links/lookupde enlace o de cuenta 1Encontrar uno de tus enlaces por su dirección corta.
GET/api/v1/links/{id}de enlace o de cuenta 1Un enlace: ajustes, estado, clics y visitantes únicos de toda su vida. Los tokens de cuenta pueden añadir un informe de estadísticas.
PATCH/api/v1/links/{id}de enlace o de cuenta 3Cambiar ajustes. Solo cambian los campos enviados. Planes de pago (un token de enlace tiene derechos Free y no puede editar).
DELETE/api/v1/links/{id}de enlace o de cuenta 2Borrar el enlace. El nombre vuelve a quedar libre.
GET/api/v1/links/{id}/qrde enlace o de cuenta 3El código QR de la dirección corta como imagen (PNG o SVG). Necesita token, así que conviene al código del servidor.
GET/api/v1/qropcional 3El código QR de una dirección corta como imagen, sin token: la propia dirección es la clave. Pensado para etiquetas <img>.
GET/api/v1/mede cuenta 1La cuenta: plan, límites, cuota restante, dominios extra, lo que permite el plan.
GET/api/v1/openapi.jsonopcional 1Esta API como documento OpenAPI 3.1.

El coste se indica en unidades del límite de ritmo, véase Límites de ritmo.

Crear un enlace

POST /api/v1/links

La petición mínima contiene solo el campo url:

curl -X POST http://anonym.es/api/v1/links \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/article"}'

Con un token de cuenta el enlace pertenece a la cuenta y se cuenta en la cuota de su plan. Sin token es un enlace de invitado en la cuota de la IP:

curl -X POST http://anonym.es/api/v1/links \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/article"}'

Una petición correcta devuelve el estado 201 junto con el enlace, su token y el número de enlaces que quedan en el periodo de cuota actual.

Campos de la respuesta:

CampoTipoQué hace
linkobjectEl enlace creado.
tokenstringEl token de enlace (32 caracteres), gestiona este enlace.
leftinteger | nullEnlaces que quedan en el periodo de cuota actual, null cuando el plan no tiene límite.
qrobjectEl código QR, presente cuando se envió qr=true.
batchbooleantrue cuando se enviaron varias direcciones.
resultsarrayUna entrada por dirección, en el orden enviado: {ok: true, link, token, qr} o {ok: false, url, error, message, field}.

Enlace con nombre propio

La dirección corta recibe el nombre my-article si está libre y cumple las reglas siguientes.

curl -X POST http://anonym.es/api/v1/links \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/article","name":"my-article"}'

Reglas de los nombres:

Un nombre puede comprobarse antes de crear el enlace:

curl "http://anonym.es/api/v1/names/check?name=my-article"

Campos de la respuesta de comprobación:

CampoTipoQué hace
availablebooleantrue cuando el nombre puede usarse.
namestringEl nombre comprobado.
errorstringPor qué el nombre no está disponible: taken, reserved, too_short y los demás errores de nombre.
messagestringEl motivo en palabras.
fieldstringSiempre name.
suggestarrayAlternativas libres cuando el nombre está ocupado.

Varios enlaces a la vez

El campo urls acepta hasta 50 direcciones, como array JSON o como texto con una dirección por línea. Cada dirección se convierte en su propio enlace con su propio token, y los demás campos se aplican a todos. El nombre propio no está disponible en un lote.

curl -X POST http://anonym.es/api/v1/links \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://example.com/a","https://example.com/b","https://example.com/c"]}'

La respuesta contiene batch: true y un array results con una entrada por dirección, en el orden enviado. Una dirección defectuosa produce una entrada con ok: false y el código de error sin detener el resto.

Ajustes adicionales

curl -X POST http://anonym.es/api/v1/links \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/article",
    "name": "my-article",
    "expires_days": 30,
    "max_hits": 1000,
    "self_destruct": true,
    "password": "secret",
    "note": "Available until the end of the month",
    "delay": 5,
    "tags": "blog,promo",
    "qr": true,
    "qr_size": 300,
    "qr_format": "png"
  }'

Las opciones marcadas como de pago se ignoran para invitados y en el plan Free. La respuesta refleja los ajustes que el enlace recibió realmente.

CampoTipoQué hace
urlstring, obligatorioEl destino. O urls: varias direcciones, una por línea o como array JSON (hasta 50), cada una recibe su propio enlace.
namestringNombre propio para un solo enlace (comprobado con las reglas y el filtro de nombres).
domainstringOne of the alias domains, random, or random-alias (random among the alias domains only). Paid plans; default is random: links never sit on the main domain. Free and guests: anonymes.click.
subbooleanForma name.alias en lugar de alias/name. Plan Max, solo en los dominios extra.
expires_daysintegerDuración en días. Planes de pago.
max_hitsintegerLímite de visitas. Planes de pago.
self_destructbooleanBorrar el enlace de forma definitiva al alcanzar el límite de visitas o la duración (requiere max_hits o expires_days).
passwordstringContraseña que deben introducir los visitantes. Planes de pago.
notestringTexto mostrado en la página de reenvío. Planes de pago, longitud según el plan.
note_onlybooleanEl enlace abre la propia nota, sin destino. Pro+ y superiores.
delayintegerSegundos en la página de reenvío, 0 = inmediato. Planes de pago.
no_countdownbooleanSin cuenta atrás en la página de reenvío: sin temporizador ni reenvío automático, el visitante pulsa la dirección. Planes de pago.
adultbooleanAdult content (18+): visitors confirm their age on a page of its own before anything else is shown. Every plan.
tagsstringEtiquetas separadas por comas (hasta 5, de 24 caracteres cada una). Tokens de cuenta en planes de pago.
qrbooleanIncluir en la respuesta el código QR de la dirección corta (base64).
qr_sizeintegerLado de la imagen QR en píxeles, 100–1000 (por defecto 300, el PNG se redondea a módulos enteros).
qr_formatstringpng (por defecto) o svg.
qr_logobooleanfalse = código sin logotipo. Solo planes de pago, en caso contrario se ignora.

Listar enlaces

GET /api/v1/links

Requiere un token de cuenta.

Requiere un token de cuenta. Los enlaces se devuelven de más nuevo a más antiguo.

curl "http://anonym.es/api/v1/links?page=1&per=50" \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN"
CampoTipoQué hace
pageintegerNúmero de página (por defecto 1).
perintegerEnlaces por página, 1–100 (por defecto 50).
qstringBúsqueda en el nombre corto, el dominio y el destino (una lista plana, hasta 50).
tagstringSolo enlaces con esta etiqueta.

La búsqueda y el filtro por etiqueta pueden combinarse:

curl "http://anonym.es/api/v1/links?q=example&tag=promo" \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN"

Campos de la respuesta:

CampoTipoQué hace
pageintegerPágina actual.
perintegerEnlaces por página.
totalintegerNúmero de enlaces encontrados.
pagesintegerNúmero de páginas.
linksarrayObjetos enlace, los más nuevos primero.

Buscar un enlace por su dirección corta

Un enlace se identifica por su id numérico (el campo id, por ejemplo 4821), no por el nombre de la dirección corta. Cuando solo se conoce la dirección corta, el id puede obtenerse con cualquier token que gestione ese enlace:

curl --get http://anonym.es/api/v1/links/lookup \
  -H "Authorization: Bearer YOUR_TOKEN" \
  --data-urlencode "short=http://anonym.es/k7m2q"

Detalles del enlace y estadísticas

GET /api/v1/links/{id}

Devuelve los ajustes del enlace, su estado, el número de visitas y el número de visitantes únicos durante toda su vida:

curl http://anonym.es/api/v1/links/4821 \
  -H "Authorization: Bearer YOUR_TOKEN"

Con un token de cuenta, el parámetro stats añade un informe de visitas:

curl "http://anonym.es/api/v1/links/4821?stats=day" \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN"
ValorPeriodo del informe
dayÚltimos 30 días, por día
weekÚltimas 26 semanas, por semana ISO
monthÚltimos 24 meses, por mes

Campos de la respuesta: stats

CampoTipoQué hace
modestringday, week o month.
fromstringPrimer día del informe, AAAA-MM-DD.
tostringÚltimo día del informe.
seriesarrayUna entrada por periodo, los más antiguos primero: [from, to, visits, uniques].
summaryobjectcur (el periodo actual), prev (el anterior), avg (la media de los periodos anteriores al actual), cada uno con hits y uniq.
dimsobjectDesglose del rango: ref, country, device, os, browser, hour, cada uno una lista de [valor, visitas].

Editar un enlace

PATCH /api/v1/links/{id}

Solo cambian los campos enviados:

curl -X PATCH http://anonym.es/api/v1/links/4821 \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"max_hits": 2000, "delay": 3, "tags": "blog,updated"}'

La edición requiere un plan de pago. Un token de enlace tiene los derechos del plan Free y no puede cambiar ajustes.

CampoTipoQué hace
urlstringNuevo destino. Pro+ y superiores.
namestringNuevo nombre (mismas reglas que un nombre propio).
expires_daysintegerNueva duración en días, vacío = sin caducidad.
max_hitsintegerNuevo límite de visitas, vacío = sin límite.
self_destructbooleanBorrar de forma definitiva al alcanzar el límite o la duración, false lo desactiva.
passwordstringNueva contraseña, una cadena vacía elimina la contraseña.
notestringNueva nota, vacío la elimina (un enlace de solo nota sigue necesitando una).
delayintegerSegundos en la página de reenvío, vacío = valor por defecto del plan.
no_countdownbooleantrue = sin cuenta atrás en la página de reenvío, false vuelve a activarla.
adultbooleantrue = age confirmation (18+) before the forwarding page; false removes it.
tagsstringNueva lista de etiquetas separadas por comas, vacío elimina todas las etiquetas.

Vaciar un valor

curl -X PATCH http://anonym.es/api/v1/links/4821 \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"password": "", "note": "", "expires_days": null, "max_hits": null, "delay": 0}'

Borrar un enlace

DELETE /api/v1/links/{id}
curl -X DELETE http://anonym.es/api/v1/links/4821 \
  -H "Authorization: Bearer YOUR_TOKEN"

Tras el borrado, el nombre propio vuelve a quedar libre. Las estadísticas se borran junto con el enlace.

Campos de la respuesta:

CampoTipoQué hace
deletedintegerEl id del enlace borrado.

Código QR

Para una etiqueta img de HTML, solicita el código por la dirección corta. Este endpoint no necesita token: la propia dirección corta es la clave, y cualquiera que la tenga puede generar el mismo código.

<img
  src="http://anonym.es/api/v1/qr?short=http%3A%2F%2Fanonym.es%2Fk7m2q&qr_size=400"
  alt="QR code"
>

El código del lado del servidor también puede solicitar la imagen por id con un token, o recibirla en JSON codificada en base64 añadiendo qr=true a la llamada de creación o de detalles:

curl "http://anonym.es/api/v1/links/4821/qr?qr_size=400&qr_format=svg" \
  -H "Authorization: Bearer YOUR_TOKEN" -o qr.svg

Parámetros de ambos endpoints de imagen:

CampoTipoQué hace
shortstring, obligatorioLa dirección corta, por ejemplo https://anonym.es/abc12.
qr_sizeintegerLado de la imagen QR en píxeles, 100–1000 (por defecto 300, el PNG se redondea a módulos enteros).
qr_formatstringpng (por defecto) o svg.
qr_logobooleanfalse = código sin logotipo. Solo planes de pago, en caso contrario se ignora.

El miembro qr en las respuestas JSON:

CampoTipoQué hace
formatstringpng o svg.
mimestringimage/png o image/svg+xml.
sizeintegerLongitud del lado solicitada en píxeles.
logobooleanSi el logotipo se dibuja en el centro.
base64stringLa imagen, codificada en base64.

Detalles de la cuenta

GET /api/v1/me

Requiere un token de cuenta. Devuelve el plan, sus límites y la cuota restante:

curl http://anonym.es/api/v1/me \
  -H "Authorization: Bearer anon_YOUR_ACCOUNT_TOKEN"
CampoTipoQué hace
loginstringEl login de la cuenta.
planstringClave del plan: free, pro, pro_plus, max o enterprise.
plan_labelstringEl nombre del plan tal como se muestra en el sitio.
untilstring | nullCuándo termina el plan de pago, ISO 8601. null en Free o sin fecha de fin.
limitsobjectlinks (por periodo), per (day o month), ai_hourly (nombres propios por hora), name_min (nombre propio más corto), note_max (longitud de la nota), api_units (presupuesto de API por minuto).
leftinteger | nullEnlaces que quedan en el periodo de cuota actual, null sin límite.
aliasesarrayLos dominios extra que puede usar el plan.
canobjectUn booleano por opción: password, ttl, edit, edit_url, tags, note, note_only, alias, sub, instant, qr_no_logo.

Errores

Los errores se devuelven en un único formato JSON:

{
  "ok": false,
  "error": "taken",
  "message": "This name is already taken.",
  "field": "name",
  "suggest": ["my-article-26", "my-my-article", "my-article-link"]
}

field contiene el nombre del parámetro incorrecto, o null cuando el error no se refiere a un campo concreto. Un nombre ocupado añade suggest, una opción de pago añade upgrade, las cuotas y los límites de ritmo añaden la cabecera Retry-After.

HTTPSignificado
400Error en los parámetros de la petición
401Token ausente o no válido
403El plan o el tipo de token no permiten esta llamada
404El enlace no existe o pertenece a otra persona
405Método no permitido para esta ruta
409El nombre propio está ocupado
429Límite de ritmo o cuota agotados, véase Retry-After
501PNG no está disponible en este servidor, solicita svg
Todos los códigos de error
CódigoHTTPCampoQué hace
bad_request400Petición mal formada.
bad_url400urlFalta la dirección o no es una URL http(s) válida.
blocked400urlNo se puede enlazar a este destino.
bad_name400nameEste nombre no está permitido.
dirty400nameEste nombre no está permitido.
brand400nameEste nombre parece una marca y no puede usarse.
reserved400nameEste nombre está reservado.
too_short400nameEl nombre es demasiado corto para tu plan.
sub_format400nameUn nombre de subdominio tiene de 3 a 32 letras, dígitos o guiones.
sub_main400domainLos enlaces de subdominio solo existen en los dominios extra.
name_batch400nameUn nombre propio sirve para una sola dirección, no para un lote.
taken409nameEste nombre ya está ocupado.
note_long400noteLa nota es más larga de lo que permite tu plan.
note_required400noteUn enlace de solo nota necesita una nota.
bad_tag400tagsEtiquetas: hasta 5, cada una de hasta 24 caracteres.
pro_only403Esta opción requiere un plan de pago.
max_only403Los enlaces de subdominio requieren el plan Max.
account_only403Esta llamada requiere un token de cuenta.
limit429La cuota de enlaces de este periodo está agotada.
domain_limit429urlEl límite diario de enlaces a este sitio sin cuenta se ha agotado.
ai_limit429nameDemasiados nombres propios en esta hora, inténtalo más tarde.
rate_limited429Demasiadas peticiones, reduce el ritmo.
busy429Se están creando demasiados enlaces a la vez, reinténtalo en un momento.
auth401Token ausente o no válido.
not_found404No existe ese enlace.
no_route404No existe ese endpoint.
method405Método no permitido.
fetch500No se pudo crear el enlace, inténtalo de nuevo.
qr_unavailable501qr_formatLos códigos QR en PNG no están disponibles en este servidor, solicita svg.

Límites de ritmo

Cada llamada cuesta unidades y cada plan dispone de un presupuesto de unidades por minuto (véase Planes y límites). Una lectura cuesta 1 unidad, una página de lista 2, un código QR 3, una edición 3, un borrado 2, una creación 5 más 1 por dirección. Cada respuesta lleva estas cabeceras:

CabeceraValor
X-RateLimit-LimitPresupuesto de unidades por minuto
X-RateLimit-RemainingUnidades que quedan en el minuto actual
X-RateLimit-ResetSegundos hasta que se renueva el presupuesto
Retry-AfterCon 429: segundos que esperar antes de reintentar

En cualquier ventana de 10 segundos puede gastarse como máximo un cuarto del presupuesto por minuto, con un mínimo de 20 unidades. Cuando el presupuesto se agota, la API responde con el estado 429.

Planes y límites

Los límites exactos de cada plan. Los enlaces se cuentan por día y dirección IP en Free, y por mes y cuenta en los planes de pago. La última columna enumera los ajustes que puede usar cada plan.

PlanEnlacesNombres propios por horaNombre más cortoLongitud de la notaUnidades por minutoAjustes
Free 5 al día por dirección IP 5 5 0 60 ninguno
Pro 500 al mes 10 3 300 150 password, expires_days, max_hits, edit, tags, note, domain, delay, qr_logo
Pro+ 2,000 al mes 50 3 2,000 400 password, expires_days, max_hits, edit, edit url, tags, note, note_only, domain, delay, qr_logo
Max 50,000 al mes 200 3 5,000 1,000 password, expires_days, max_hits, edit, edit url, tags, note, note_only, domain, sub, delay, qr_logo
Enterprise sin límite sin límite 3 5,000 2,500 password, expires_days, max_hits, edit, edit url, tags, note, note_only, domain, sub, delay, qr_logo

Sin token de cuenta, la creación se contabiliza en la cuota Free de la dirección IP: 5 enlaces al día. Los enlaces a un dominio registrado hace menos de un año comparten un único cupo de invitado de 5 al día, quienquiera que los cree. Por cada llamante pueden estar creándose como máximo 2 enlaces al mismo tiempo.

Especificación OpenAPI

La descripción técnica completa como documento OpenAPI 3.1: http://anonym.es/api/v1/openapi.json

Contiene esquemas y ejemplos de todas las peticiones y respuestas, los límites de los planes, las reglas de los nombres y los códigos de error. Sirve para Swagger UI, Postman, Insomnia y generadores de clientes.