Authentication
Hablame v6 uses Bearer tokens (RFC 6750). A single header, a single format, a single source of truth. No query-string fallbacks, no OAuth flow, no signing rituals.
The Bearer scheme
Pass 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_YOUR_API_KEY
The header is the only accepted location. Tokens sent in the URL query (?token=…) or in the request body are ignored and the call fails with 401 AUTH_REQUIRED.
This is intentional. Tokens in URLs leak into nginx access logs, Cloud Logging exports, browser history and the Referer header that browsers send to third-party domains. The Bearer header never appears in any of those.
Key format
Every Hablame v6 token starts with the hk_ prefix followed by a unique random identifier.
- The
hk_prefix lets you spot a Hablame v6 key in logs and code. - Tokens are case-sensitive; an altered prefix or character is rejected with
401 AUTH_INVALID_KEY.
The full token is shown only at creation time. If you lose it, it cannot be recovered: issue a new one instead.
Key lifecycle
Creation
Keys are minted from the dashboard. Each key carries:
- An organization binding: every call counts against this organization.
- A cost center, for billing attribution.
- A creator user: if the user is removed from the organization, the key stops working.
- An optional service list (e.g.
["sms", "whatsapp"]) that scopes which module endpoints the key may call. Utility endpoints (/api/v6/utilities/*) ignore this list and are universal. - An optional expiry date. Keys with no expiry never time out.
Rotation
There is no rotate endpoint by design. To rotate:
- Mint a new key in the dashboard.
- Deploy your application with the new key.
- Once you've confirmed the new key works, revoke the old one from the dashboard.
The cache layer converges within 5 minutes; a revoked key may continue to authenticate during that window. For incident response (token exposure), tell your organization manager: they can flush the cache entry immediately.
Expiration
Keys with expires_at set return 401 AUTH_INVALID_KEY after that timestamp. The check runs server-side at every request, so an expiring key fails atomically the second it crosses the boundary.
What happens on every request
The API validates every request in stages. If any stage fails you get a specific error code so you can fix the root cause quickly:
- The
Authorizationheader is present and uses theBearerscheme → otherwiseAUTH_REQUIRED. - The token is a valid Hablame v6 API key.
- The token has not expired.
- The user that owns the key is still active.
- The user is still active on the organization.
- The cost center linked to the key is active.
- The organization is active and not blocked.
- If the endpoint targets a specific service, the key has access to that service.
See the error catalog for the specific code each stage emits.
Security best practices
| Do | Don't |
|---|---|
| Store keys in a secret manager (Google Secret Manager, AWS Secrets Manager, HashiCorp Vault, doppler, 1Password CLI). | Hardcode keys in source code or container images. |
| Inject keys into the runtime via environment variables read at boot. | Commit .env files with real keys to version control. |
| Have one key per environment (prod, staging, sandbox) and rotate on a schedule. | Share a single key across all environments and engineers. |
| Mint a new key when a teammate leaves the team and revoke the one they had access to. | Re-use keys after off-boarding. |
Mask the token in your own application logs (hk_***). |
Log full Authorization headers, even at debug level. |
Incident response: exposed token
If you suspect a key has been exposed (committed to a public repo, leaked in a screenshot, posted in a chat):
- Revoke immediately from the dashboard. The cache flush happens within 5 minutes; for emergencies, ask support to invalidate it manually.
- Mint a replacement key and deploy.
- Audit recent usage in the dashboard's activity log. Look for unfamiliar IPs or unusual TPS patterns.
- Quote the request IDs of suspicious calls in your support ticket: ops can correlate them with our infrastructure logs.