Authentication
API v6 uses Bearer tokens (RFC 6750). One header, one format, one source of truth. No query string fallbacks, no OAuth flows, no signing rituals.
7 min read
The Bearer scheme
Send the API key in the Authorization header on every request:
GET /api/v6/utilities/ping HTTP/1.1
Host: developers.hablame.co
Authorization: Bearer hk_TU_API_KEYThe header is the only accepted location. Tokens sent in the query string (?token=...) or in the body are ignored, and the call fails with 401 AUTH_REQUIRED.
This is intentional. Tokens in URLs end up in server logs, in browser history and in the Referer header browsers send to third-party domains. A Bearer header shows up in none of those places.
Key format
Every Hablame v6 key matches this expression:
^hk_[a-f0-9]{32}$- The
hk_prefix identifies it as a Hablame v6 key. - 32 lowercase hexadecimal characters (16 bytes of cryptographic randomness, 128 bits of entropy).
- Case-sensitive.
HK_or uppercase hex fail the structural check and return401 AUTH_INVALID_KEY.
The full token is shown only at creation time. The server stores just sha256(token): if you lose the original value it cannot be recovered and you have to issue a new key.
Key lifecycle
Creation
Keys are created from the customer portal. Each one carries:
- A link to an organization: every call with that key operates against that organization.
- A cost center, for usage attribution.
- A creating user: if they are removed from the organization, the key stops working.
- An optional service list (for example
["urlshortener", "tts"]) that limits which endpoints it can call. Utility endpoints under/api/v6/utilities/ignore that list: they are universal. - An optional list of allowed networks: single IPs or CIDR blocks, IPv4 or IPv6. With a list, the key only works from those networks and from any other it returns
403 AUTH_IP_NOT_ALLOWED; without one, it works from any network. The list is set when the key is created. - An optional expiration date. Keys without one never expire.
- Explicitly granted capabilities:
account(financial data),directory(personal data) andurlshortener.write(create, edit, delete and restore short links). Having access to all services does not include them. Like the rest of the scope, they are set when the key is created and cannot be added later.
Reading is not writing: the URL shortener
In the URL shortener, the urlshortener service allows reading: listing and reading links, their statistics, the overview, the domains and the pricing. Writing —creating, editing, deleting and restoring links— also requires the urlshortener.write capability. That way, an integration that only reads, such as a clicks dashboard, does not need a key able to redirect or delete your links if it ever leaks.
Only an owner or an administrator of the organization can create keys with urlshortener.write. Members with the developer role can create read-only URL shortener keys. URL shortener keys issued before this capability existed received it, so they keep writing as before.
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
{
"success": false,
"error": {
"code": "AUTH_CAPABILITY_NOT_ALLOWED",
"type": "https://developers.hablame.co/docs/v6/errors/auth-capability-not-allowed",
"message": "This API key can list and read links, but it cannot create, edit, delete or restore them. Ask an owner or administrator of your organization for an API key that can create and edit links.",
"details": []
},
"meta": {
"requestId": "8f0c0e2a4b1d4c8fae2b7a91e0c5d3f6",
"timestamp": "2026-09-30T15:00:00+00:00",
"responseTimeMs": 0.9
}
}Rotation
There is no rotation endpoint by design. To rotate:
- 01Create the new key
From the customer portal, with the same scope as the previous one.
- 02Deploy
Ship your application with the new key and verify it returns 200.
- 03Revoke the old one
Once you confirm the new one works, revoke the old one from the portal.
Revocation converges within up to 5 minutes: a revoked key may keep authenticating during that window. If the token was exposed, tell support so it can be invalidated immediately.
Expiration
Keys with an expiration date return 401 AUTH_INVALID_KEY from that moment on. The check runs server-side on every request, so a key about to expire fails exactly at the second it crosses the boundary.
What happens on every request
The authentication pipeline runs these checks in order. Any failure short-circuits the rest:
- The token is present and prefixed with
Bearer; otherwise,AUTH_REQUIRED. - The token matches
hk_[a-f0-9]{32}. - The token hash matches a known key.
- The token is not expired.
- The creating user is still active.
- Their membership in the organization is still active.
- The cost center bound to the key is active.
- The organization exists and its status is
active. - The organization has no active blocks.
- If the key has allowed networks, the request comes from one of them; otherwise,
AUTH_IP_NOT_ALLOWED. The IP we saw you calling from comes inmeta.clientIp. - If the endpoint requires a service, the key has it; otherwise,
403 AUTH_SERVICE_NOT_ALLOWED. - If the endpoint requires a capability, the key has it; otherwise,
403 AUTH_CAPABILITY_NOT_ALLOWED. The rejection comes before your usage limit is counted: it does not spend it.
The error catalog lists the specific code each step emits.
Security best practices
.env files with real keys to version control.hk_***).Authorization headers, not even in debug mode.Incident response: exposed token
If you suspect a key leaked (a commit to a public repository, a screenshot, a chat message):
- Revoke it immediately from the portal. Propagation takes up to 5 minutes; in an emergency, ask support to invalidate it manually.
- Issue a replacement key and deploy.
- Audit recent usage in the portal activity log. Look for unknown IPs or unusual volumes.
- Quote the
requestIdvalues of the suspicious calls in your support ticket so we can correlate them.