Name
Update a short link
Change the destination, the status or the expiry. Domain and code do not change.
HTTP method and path
/ api/ v6/ urlshortener/ links/ {domain}/ {code}https:
What happens when you run it
- Changes your organization’s data.
- The call is not charged.
- If this change makes the link redirect again (you reactivate it, or extend or remove its expiry), every visit by a person is charged again (visits by bots and link previews are not).
What it does
Changes the destination URL (longUrl, revalidated as on creation), the status (status) or the expiry (expiresAt). Send only what you want to change; at least one field is required. Domain and code cannot change: that would break every short URL already handed out. Editing is free.
Every change is recorded with the previous value, the new one and who made it (the API key or the portal user). A link blocked by Hablame (status:) cannot be edited: it returns 409 LINK_BLOCKED.
Availability and prerequisites
- Published and available in the production API v6.
- Every path starts at
https:./ / developers. hablame. co - You need a Hablame API key to call it.
Authentication and permissions
- Send your API key in the
Authorizationheader with the Bearer scheme.
Who can call it: An API key with the urlshortener service enabled.
Limits and operational notes
Usage limit: 35 requests per second.
Path parameters
| Name | Type | Description and rules |
|---|---|---|
domainRequired | string | Domain of the link, as the API returns it in Example: |
codeRequired | string | Code or alias of the link. Compared in lowercase. Example: |
Query parameters
| Name | Type | Description and rules |
|---|---|---|
domainStatusOptional | string | With Allowed values: |
HTTP headers
| Name | Type | Description and rules |
|---|---|---|
AuthorizationRequired | string | Your API key with the Bearer scheme. Example: |
Content-TypeRequired | string | Type of the body you send. Fixed value: |
Request body
Content type:application/jsonRequired
| Name | Type | Description and rules |
|---|---|---|
longUrlOptional | string | New destination URL. Same rules as on creation. Format: |
statusOptional | string |
Allowed values: |
expiresAtOptional | string | New expiry, always in the future. Without a time zone it is read in Colombia time ( Format: |
{
"status": "disabled"
}Successful responses
200
Link updated, as it ended up.
{
"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": "8f0c0e2a4b1d4c8f",
"clientIp": "203.0.113.45",
"timestamp": "2026-09-23T18:30:00+00:00",
"responseTimeMs": 7.2
}
}The example values are illustrative.
Response fields
| Name | Type | Description and rules |
|---|---|---|
successAlways present | boolean | |
dataAlways present | object | |
data.Always present | string | Domain of the link, lowercase. If the domain no longer belongs to your organization ( |
data.Always present | string | Link code, lowercase: 7 |
data.Always present | string | The full short URL: always Format: |
data.Always present | string | Destination URL. Format: |
data.Always present | boolean |
|
data.Always present | string |
Allowed values: |
data. | string | Whether the domain lets the link open, apart from its own Allowed values: |
data.Always present | string | Expiry in UTC, or May come as Format: |
data.Always present | string | Creation date, in UTC. Format: |
data.Always present | integer | Lifetime visits of the link. A background process consolidates them: a visit can take from seconds to a few minutes to show up. Bots and the previews generated by social networks and chat apps are not counted. |
data.Always present | integer | Sum of each day’s unique visits: the first visit of the day from each browser. Not distinct people over the life of the link. |
data.Always present | string | First visit, in UTC. May come as Format: |
data.Always present | string | Last visit, in UTC. May come as Format: |
metaAlways present | object | Response metadata. |
meta.Always present | string | Unique request identifier (16 hexadecimal characters). It matches the Example: |
meta.Always present | string | IP the API saw your request come from. Useful if your API key only accepts certain networks. Example: |
meta.Always present | string | Date and time the response was built (ISO 8601 with offset). Format: |
meta.Always present | number | Time (ms) the server took to process the request. Example: |
Error codes
Every error response has the same shape: success set to false and an error object whose code says what happened. They are grouped here by kind, with the codes this endpoint can return.
Shape of an error response
| Name | Type | Description and rules |
|---|---|---|
successAlways present | boolean | Fixed value: |
metaAlways present | object | Response metadata. |
meta.Always present | string | Unique request identifier (16 hexadecimal characters). It matches the Example: |
meta.Always present | string | IP the API saw your request come from. Useful if your API key only accepts certain networks. Example: |
meta.Always present | string | Date and time the response was built (ISO 8601 with offset). Format: |
meta.Always present | number | Time (ms) the server took to process the request. Example: |
errorAlways present | object | |
error.Always present | string | Stable UPPER_SNAKE_CASE identifier. Clients branch on this value. Example: |
error. | integer | Legacy v5 numeric code, only when a bridge exists. Omitted for codes born in v6. Example: |
error.Always present | string | URL to the error documentation. Format: |
error.Always present | string | Human readable text, in English. It is for the developer log, not the end user: do not parse it. |
error.Always present | array<object> | Structured context (validation issues, affected resource). Empty array when there is no extra context. |
Validation
- 400Nothing to change was sent, a field has the wrong type, or a value is invalid.
No updatable fields were sent.
Message the API returns: No updatable fields were provided.
400VALIDATION_INVALID_PARAMETER
A parameter or a body field is not valid.
400URL_INVALID
The destination URL is malformed.
Message the API returns: The destination URL is not valid. Provide an absolute `http`/`https` URL with a host.
Only http/https destinations are allowed.
Message the API returns: Only `http` and `https` destination URLs are allowed.
400URL_TOO_LONG
The destination URL exceeds the maximum length.
Message the API returns: The destination URL exceeds the maximum allowed length.
The destination host is private or reserved.
Message the API returns: The destination host is not allowed (private, reserved, or loopback addresses are blocked).
expiresAtmust be a future ISO date-time.Message the API returns: `expiresAt` must be a future ISO-8601 date-time.
Authentication
- 401Invalid or missing credentials.
No Bearer token was sent, and every call requires one.
Message the API returns: Authentication is required. Send your API key as `Authorization: Bearer <token>`.
The API key is not recognized: wrong format, revoked or expired.
Message the API returns: The provided API key is invalid or has expired. Please verify the value sent in the `Authorization: Bearer` header.
Permissions
- 403The API key does not have the URL shortener enabled (or it is turned off for your organization), the key cannot be used from the request network, or the organization is not active.
The key is not allowed to use the service behind this endpoint.
Message the API returns: This API key is not authorized to use the requested service.
The key only works from certain networks and your IP is not one of them.
Message the API returns: This API key cannot be used from this IP address. The address we saw is in `meta.clientIp`: call from one of the networks allowed for the key, or use a key that allows this one.
Your organization is suspended or closed.
Message the API returns: The organization associated with this API key is not active. Please contact support.
Usage limits
- 429Request limit exceeded.
You exceeded your organization quota for this endpoint.
Message the API returns: You have exceeded the allowed request rate for this endpoint. Please wait before retrying.
Resource not found
- 404No link of your organization with that domain and code (or it was deleted). A link from another organization also returns
404: its existence is not disclosed.
No link with that domain and code.
Message the API returns: No short link was found for that domain and code.
Internal errors and availability
This endpoint does not declare responses of this kind.
Other responses
- 409The link is blocked by Hablame and cannot be changed.
409LINK_BLOCKED
The link is blocked for security.
Special considerations
Keys it does not recognize are ignored: a body like {"active": (from the previous contract) changes nothing and returns 400 NOTHING_TO_UPDATE. To disable, send {"status":.
A key with the URL shortener also creates and deletes
The urlshortener service grants the whole URL shortener: with it, the API key lists and reads links, and also creates them (each creation is charged), edits, deletes and restores them. There are no read-only keys. Only the owner of your organization creates keys: if one must not create links, do not give it this service. Without it, the key gets 403 AUTH_SERVICE_NOT_ALLOWED.