API key not working
Calls to the TimeTuna API come back 401, 402, or 429 rather than the data you asked for.
Symptom
- Every call returns
401 unauthorized, even though you just created the key. - Calls return
402 upgrade_requiredalthough you can sign in to the dashboard normally. - A script that worked starts returning
429 rate_limitedin bursts.
Why it happens
401 is almost always the header. The key must be sent as a Bearer token, and the whole key, including the tt_sk_ prefix. A revoked key also returns 401, as does an old key after you rotated it.
402 means the account behind the key is not on an Executive plan and has no AppSumo lifetime deal. This fires on a downgrade or a failed renewal, so a key that worked last month can start returning 402 without anything changing in your code.
429 means more than 120 requests in a minute on one key. An agent looping over availability day by day reaches that quickly.
How to fix
- Check the header shape. It is
Authorization: Bearer tt_sk_..., notX-Api-Keyand not the bare key.bashA working key returns your account. This is the fastest way to tell a bad key from a bad request.curl https://timetuna.com/api/v1/me \ -H "Authorization: Bearer $TIMETUNA_API_KEY" - Confirm the key is still listed under API and webhooks. A revoked key disappears from that list. Create a new one if it is gone.
- Watch for whitespace. A key pasted into an environment variable with a trailing newline fails with 401 and looks correct on screen.
- On 402, open your subscription and check the plan is active. The API needs Executive or a lifetime deal, the same bar as webhooks and Zapier.
- On 429, wait the 60 seconds the
Retry-Afterheader asks for, then space the calls out. Ask for availability once over the whole booking window instead of once per day:/available-timeswithout adatereturns the full window in one call.
Still not working
If GET /api/v1/me succeeds but a specific endpoint fails, read the message field: it names the field that is wrong. The full list of codes is in the API reference. If the call still fails, with the endpoint, the status code, and the error value. Never send us the key itself.