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:

request
GET /api/v6/utilities/ping HTTP/1.1
Host:          developers.hablame.co
Authorization: Bearer hk_TU_API_KEY

The 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:

regex
^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 return 401 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) and urlshortener.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.

a read-only key tries to create a link
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:

  1. 01
    Create the new key

    From the customer portal, with the same scope as the previous one.

  2. 02
    Deploy

    Ship your application with the new key and verify it returns 200.

  3. 03
    Revoke 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:

  1. The token is present and prefixed with Bearer; otherwise, AUTH_REQUIRED.
  2. The token matches hk_[a-f0-9]{32}.
  3. The token hash matches a known key.
  4. The token is not expired.
  5. The creating user is still active.
  6. Their membership in the organization is still active.
  7. The cost center bound to the key is active.
  8. The organization exists and its status is active.
  9. The organization has no active blocks.
  10. 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 in meta.clientIp.
  11. If the endpoint requires a service, the key has it; otherwise, 403 AUTH_SERVICE_NOT_ALLOWED.
  12. 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

Do
Don't
Store keys in a secret manager (Google Secret Manager, AWS Secrets Manager, HashiCorp Vault, 1Password CLI).
Hardcode them in source code or container images.
Inject keys at runtime through environment variables read at boot.
Commit .env files with real keys to version control.
Keep one key per environment (production, staging, testing) and rotate on a cadence.
Share a single key across all environments and the whole team.
Issue a new key when someone leaves the team, and revoke theirs.
Reuse keys after an off-boarding.
Mask the token in your own logs (hk_***).
Log full 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):

  1. Revoke it immediately from the portal. Propagation takes up to 5 minutes; in an emergency, ask support to invalidate it manually.
  2. Issue a replacement key and deploy.
  3. Audit recent usage in the portal activity log. Look for unknown IPs or unusual volumes.
  4. Quote the requestId values of the suspicious calls in your support ticket so we can correlate them.