POST/api/v6/urlshortener/links

Crear un enlace corto

Publica un enlace corto con código generado o alias propio. Se cobra al crearlo, salvo que tu plan lo incluya.

Alcance y límites

Alcance

API key con el servicio urlshortener habilitado y la capacidad urlshortener.write concedida

Límite de uso

35 solicitudes por segundo

Idempotencia

Admite Idempotency-Key

  • La URL de destino admite hasta 2048 caracteres; el cuerpo, hasta 64 KiB.
  • Se rechazan destinos en localhost, *.local, *.internal o en IP privadas o reservadas; destinos que ya son un enlace corto (nuestros dominios o acortadores como bit.ly, tinyurl.com o t.co); destinos con usuario o clave antes del dominio (usuario@); dominios con tildes, eñes u otros alfabetos (también en xn--), y URL con caracteres invisibles.
  • Con plan: hasta 100.000 altas por día de Colombia (cupo diario).

Crea un enlace corto en uno de los dominios disponibles para tu organización. Si no envías code, el servicio genera uno de 7 caracteres (0-9a-z); si lo envías, queda como alias (isAlias: true). Los códigos son únicos por dominio, y el de un enlace eliminado no se puede volver a usar para otro enlace: si era tuyo, puedes restaurarlo durante 90 días.

Cada enlace creado se cobra al precio vigente de tu organización (consúltalo con `GET /api/v6/urlshortener/pricing`). Si tu organización tiene un plan mensual del acortador vigente, crear enlaces no se cobra, y entonces rige un cupo diario de altas (100.000 por día de Colombia, salvo que tengas otro pactado): al llegar, la API responde 429 URLSHORTENER_LINK_QUOTA_EXCEEDED hasta la medianoche. Sin plan no hay cupo diario: sin saldo disponible la API responde 402 y el enlace no se crea.

Reintenta sin duplicar con `Idempotency-Key`. Si un alta se corta (un timeout, un 5xx) y la repites con la misma llave y el mismo cuerpo, recibes el mismo enlace —201 con Idempotency-Status: replayed— sin crear otro ni cobrarlo dos veces, aunque la primera todavía se esté procesando. La misma llave con otro cuerpo responde 422 IDEMPOTENCY_KEY_REUSED. En este endpoint la llave queda asociada al enlace para siempre. Sin llave, cada reintento crea y cobra otro enlace.

El cuerpo se valida antes de comprobar el saldo: una URL, un alias, un dominio o un vencimiento inválidos responden su error sin tocar tu saldo.

Pide una key que pueda escribir

Además del servicio urlshortener, la API key necesita la capacidad urlshortener.write, y solo la concede un propietario o un administrador de tu organización al crear la key. Sin ella, la key lista y consulta enlaces, estadísticas, el resumen, los dominios y la tarifa, y aquí recibe 403 AUTH_CAPABILITY_NOT_ALLOWED.

¿Muchos enlaces a la vez, por ejemplo para una campaña? Usa el alta en lote: hasta 1.000 por petición, con las mismas reglas y un solo cobro por lo que se creó.

Cabeceras

Idempotency-Key
stringopcional
Llave de idempotencia opcional (1 a 255 caracteres de A-Za-z0-9_-), única por organización. Si repites el alta con la misma llave y el mismo cuerpo, recibes el enlace que ya se creó, sin crear otro ni cobrarlo otra vez. Ver la guía de idempotencia.

Cuerpo de la petición

application/jsonSolo se aceptan estos cuatro campos. Uno que no existe —por ejemplo `url` o `alias`, del contrato anterior— se rechaza con `400` nombrando el campo.
longUrl
stringobligatorio
URL de destino. Absoluta http o https con host, máximo 2048 caracteres. Los parámetros (UTM incluidos) van dentro de la URL tal cual: el redirector lleva exactamente a esta dirección. No puede ser otro enlace corto, ni llevar usuario antes del dominio, ni un dominio con tildes o caracteres invisibles.
domain
stringopcional
Dominio donde publicar, uno de `GET /api/v6/urlshortener/domains`. Si lo omites, se usa el predeterminado de tu organización o, si no tiene uno verificado, el de la plataforma. Un dominio propio sin verificar responde 409 DOMAIN_NOT_VERIFIED.
code
stringopcional
Alias opcional: 3 a 32 caracteres entre minúsculas, dígitos, - y _ (las mayúsculas se pasan a minúsculas). Debe estar libre en el dominio y no ser una palabra reservada (api, admin, stats, docs, login, status…). En los dominios de la plataforma, que comparten todas las organizaciones, tampoco se admiten alias que se parezcan a una marca, un banco, un medio de pago o una entidad pública (bancolombia-seguro, pago-pse, dian…); en un dominio propio, sí.
expiresAt
stringopcional
Vencimiento opcional, siempre futuro. Acepta RFC 3339 y también AAAA-MM-DD HH:MM:SS, AAAA-MM-DDTHH:MM o AAAA-MM-DD. Sin zona horaria se interpreta en hora de Colombia (`-05:00`); con zona, se respeta la que envíes. Al vencer, el enlace deja de redirigir (el visitante recibe 404) y conserva status: active.
{
  "longUrl": "https://example.com/landing?utm_source=sms",
  "domain": "h0b.co",
  "code": "promo-septiembre",
  "expiresAt": "2026-12-31T23:59:59-05:00"
}

Respuestas

201

Enlace creado. Con Idempotency-Key repetida y el mismo cuerpo, es el enlace de la primera vez (Idempotency-Status: replayed): no se creó otro ni se cobró de nuevo.

{
  "success": true,
  "data": {
    "domain": "h0b.co",
    "code": "a1b2c3d",
    "shortUrl": "https://h0b.co/a1b2c3d",
    "longUrl": "https://example.com/landing?utm_source=sms",
    "isAlias": false,
    "status": "active",
    "domainStatus": "active",
    "expiresAt": null,
    "createdAt": "2026-09-23T15:04:05Z",
    "clicks": 0,
    "uniqueClicks": 0,
    "firstClickAt": null,
    "lastClickAt": null
  },
  "meta": {
    "requestId": "8f0c0e2a4b1d4c8fae2b7a91e0c5d3f6",
    "timestamp": "2026-09-23T18:30:00+00:00",
    "responseTimeMs": 7.2
  }
}
400

Cuerpo inválido: URL de destino, alias, vencimiento o dominio, un campo que no existe, JSON mal formado, o una Idempotency-Key con otra forma.

401

Credenciales inválidas o faltantes.

402

Tu organización no tiene saldo disponible para crear el enlace (o no tiene cuenta de facturación activa), o crearlo superaría un tope de gasto que ella misma configuró (URLSHORTENER_SPEND_LIMIT_REACHED: se ajusta en los topes de gasto, recargar no lo resuelve). El enlace no se crea.

403

La API key no tiene habilitado el acortador (o está apagado para tu organización), no tiene la capacidad urlshortener.write para crear y editar enlaces, no se puede usar desde la red de la petición, o la organización no está activa.

409

El alias ya está en uso en ese dominio, es una palabra reservada o una marca en un dominio compartido, o es el de un enlace tuyo eliminado (ALIAS_RETIRED: restáuralo); el dominio propio no está verificado; o el acortador no tiene precio para la moneda de tu organización, o tu organización todavía no tiene moneda. En los dos últimos casos no se arregla reintentando.

422

La Idempotency-Key ya se usó para crear un enlace con otro cuerpo. Usa una llave nueva para un enlace nuevo.

429

Se excedió el límite de solicitudes, o —con plan— el cupo diario de altas. En el segundo caso Retry-After dice cuánto falta para la medianoche de Colombia.

500

No se pudo generar un código libre. Reintenta.

503

No se pudo comprobar el saldo en este momento. El enlace no se crea; puedes reintentar (mejor con Idempotency-Key).

Errores posibles

Códigos que este endpoint puede devolver en error.code. El detalle completo está en el catálogo.

401AUTH_REQUIREDNo se envió un token Bearer y cada llamada lo requiere.401AUTH_INVALID_KEYLa API key no se reconoce: formato equivocado, revocada o vencida.403AUTH_SERVICE_NOT_ALLOWEDLa key no tiene permitido el servicio detrás de este endpoint.403AUTH_IP_NOT_ALLOWEDLa key solo funciona desde ciertas redes y tu IP no está entre ellas.403ACCOUNT_NOT_ACTIVETu organización está suspendida o cerrada.403AUTH_CAPABILITY_NOT_ALLOWEDLa key tiene el servicio, pero no la capacidad que exige este endpoint.400VALIDATION_INVALID_PARAMETERUn parámetro o un campo del cuerpo no es válido.400IDEMPOTENCY_KEY_INVALIDLa llave de idempotencia no cumple el formato.422IDEMPOTENCY_KEY_REUSEDLa llave ya existe, pero con un cuerpo distinto.400URL_INVALIDLa URL de destino está mal formada.400URL_SCHEME_NOT_ALLOWEDSolo se admiten destinos http y https.400URL_TOO_LONGLa URL de destino supera el largo máximo.400URL_BLOCKED_HOSTEl host de destino es privado o reservado.400ALIAS_INVALIDEl alias no cumple el formato permitido.409ALIAS_TAKENEl alias ya se usó en este dominio.409ALIAS_RESERVEDEl alias es una palabra reservada.409ALIAS_RETIREDEl alias es de un enlace tuyo que eliminaste.400EXPIRES_AT_INVALID`expiresAt` debe ser una fecha ISO futura.400DOMAIN_NOT_ALLOWEDEl dominio elegido no está disponible para tu cuenta.409DOMAIN_NOT_VERIFIEDTu dominio todavía no está verificado.402URLSHORTENER_INSUFFICIENT_FUNDSTu organización no tiene saldo para crear el enlace.402URLSHORTENER_SPEND_LIMIT_REACHEDSe alcanzó un tope de gasto que tu organización configuró.403ACCOUNT_CONFIG_NOT_FOUNDNo pudimos cargar la organización de tu key.409URLSHORTENER_NOT_PRICEDEl acortador no tiene precio configurado para tu moneda.409URLSHORTENER_CURRENCY_UNDEFINEDTu organización todavía no tiene moneda definida.429URLSHORTENER_LINK_QUOTA_EXCEEDEDTu organización llegó al cupo diario de enlaces de su plan.429RATE_TPS_EXCEEDEDExcediste el cupo de tu organización para este endpoint.500INTERNAL_SERVER_ERRORAlgo salió mal de nuestro lado.503SERVICE_UNAVAILABLE503 genérico: un servicio del que dependemos no responde.
Ver el catálogo completo
POST /api/v6/urlshortener/links
curl -X POST 'https://developers.hablame.co/api/v6/urlshortener/links' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer hk_TU_API_KEY' \
  -H 'Content-Type: application/json' \
  --data '{"longUrl":"https://example.com/landing?utm_source=sms","domain":"h0b.co","code":"promo-septiembre","expiresAt":"2026-12-31T23:59:59-05:00"}'

Try-It

Ejecuta la petición contra la API real con tu propia API key.

La key se usa solo en tu navegador para esta petición. No se guarda ni se envía a ningún otro lado.

Parámetros

Llave de idempotencia opcional (1 a 255 caracteres de A-Za-z0-9_-), única por organización. Si repites el alta con la misma llave y el mismo cuerpo, recibes el enlace que ya se creó, sin crear otro ni cobrarlo otra vez. Ver la guía de idempotencia.

Cuerpo de la petición

URL de destino. Absoluta http o https con host, máximo 2048 caracteres. Los parámetros (UTM incluidos) van dentro de la URL tal cual: el redirector lleva exactamente a esta dirección. No puede ser otro enlace corto, ni llevar usuario antes del dominio, ni un dominio con tildes o caracteres invisibles.

Dominio donde publicar, uno de `GET /api/v6/urlshortener/domains`. Si lo omites, se usa el predeterminado de tu organización o, si no tiene uno verificado, el de la plataforma. Un dominio propio sin verificar responde 409 DOMAIN_NOT_VERIFIED.

Alias opcional: 3 a 32 caracteres entre minúsculas, dígitos, - y _ (las mayúsculas se pasan a minúsculas). Debe estar libre en el dominio y no ser una palabra reservada (api, admin, stats, docs, login, status…). En los dominios de la plataforma, que comparten todas las organizaciones, tampoco se admiten alias que se parezcan a una marca, un banco, un medio de pago o una entidad pública (bancolombia-seguro, pago-pse, dian…); en un dominio propio, sí.

Vencimiento opcional, siempre futuro. Acepta RFC 3339 y también AAAA-MM-DD HH:MM:SS, AAAA-MM-DDTHH:MM o AAAA-MM-DD. Sin zona horaria se interpreta en hora de Colombia (`-05:00`); con zona, se respeta la que envíes. Al vencer, el enlace deja de redirigir (el visitante recibe 404) y conserva status: active.

POST https://developers.hablame.co/api/v6/urlshortener/links

Respuesta

Todavía no has enviado ninguna petición.