Skip to main content
If your first request to the Theo API returns 401 Unauthorized, it is almost always one of the causes below. Work through them in order.

1. The apex → www redirect (most common)

https://hitheo.ai 307-redirects to https://www.hitheo.ai. Most HTTP clients — including Node 18’s built-in fetch, curl without --location-trusted, and several language runtimes — strip the Authorization header on 3xx responses as a security precaution. That leaves the redirected request unauthenticated and the server correctly returns 401 invalid_api_key. Fix: use the canonical www host directly. The SDK defaults to https://www.hitheo.ai as of @hitheo/sdk@0.2.0; if you pinned baseUrl manually, update it:
path=null start=null
// Before
new Theo({ apiKey, baseUrl: "https://hitheo.ai" })

// After
new Theo({ apiKey, baseUrl: "https://www.hitheo.ai" })
// or: omit baseUrl entirely to pick up the default.
For raw curl:
# Use www directly
curl -H "Authorization: Bearer $THEO_API_KEY" https://www.hitheo.ai/api/v1/models
The CLI diagnostic command catches this automatically:
theo status   # probes both apex and www, warns when your baseUrl is a redirect target
theo verify   # machine-readable JSON diagnostic you can pipe into CI

2. Missing or malformed API key

Every request (except GET /api/v1/health) needs an Authorization: Bearer theo_sk_... header. Check:
  • The header name is exactly Authorization, not authorization: with a stray colon or X-API-Key.
  • The token is prefixed with theo_sk_ (there is no theo_sk_test_ variant — all keys are live).
  • No leading/trailing whitespace in the token — a trailing newline from a .env file is a common cause.
  • The key has not been revoked. Check the API Keys dashboard.

3. Wrong scope on the key

API keys carry scopes (completions, skills, tools, connectors, billing). A key without the completions scope returns 403 missing_scope, not 401. If you see a 403 specifically: re-issue the key with the scopes you need, or ask the key’s creator to update it.

4. Key expired (grace period ended)

When you rotate a key, the old one enters a grace window (configurable, default 60 min) then gets revoked. Requests against an expired key return 401 key_expired. Rotate on the dashboard or via POST /api/v1/keys/rotate and swap the new token into your secret store.

5. Clock skew breaking HMAC on webhooks

Unrelated to API key auth, but sometimes reported as “401 on webhooks”: webhook signature verification uses the Theo-Signature header which is HMAC-SHA256 over the request body. If your server’s clock is more than 5 minutes out of sync, the signature won’t match. Run ntpdate -q pool.ntp.org to check.

Still stuck?

  • Call theo verify (or await theo.verify() in the SDK) and share the output with support.
  • Include the X-Request-Id response header in your ticket — every v1 response carries one, and successful responses also expose it as request_id in the JSON body. Support can look the request up in logs.
  • Check status.hitheo.ai for active incidents.