Skip to content
Browse all articles

Authenticating with the API

How to get an access token with OAuth 2.0, which scopes exist, and what the legacy API keys are.

Last updated 15 August 2026

Every API request carries a bearer token:

Authorization: Bearer <token>

Two kinds of token work. OAuth 2.0 access tokens are the recommended kind; legacy API keys exist for older clients.

Scopes

Scope Grants
temponia:read Every GET endpoint
temponia:write Creating, updating and deleting time entries and expenses

A request without the scope it needs gets 403 with {"error":"insufficient_scope"}. A missing, expired or revoked token gets 401.

The OAuth 2.0 flow

Temponia implements the standard authorization code flow, and PKCE is required. First register a custom OAuth application to get a client id and secret.

1. Send the user to authorize

Generate a random code_verifier, derive the S256 code_challenge from it, and open:

https://app.temponia.com/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_REDIRECT_URI
  &response_type=code
  &scope=temponia:read temponia:write
  &state=RANDOM_STATE
  &code_challenge=YOUR_CODE_CHALLENGE
  &code_challenge_method=S256

The user signs in to Temponia if needed, sees what your app is asking for, and authorises it. We then redirect to your redirect_uri with ?code=... and your state.

2. Exchange the code for tokens

curl -X POST https://app.temponia.com/oauth/token \
  -d grant_type=authorization_code \
  -d code=THE_CODE \
  -d redirect_uri=YOUR_REDIRECT_URI \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_CLIENT_SECRET \
  -d code_verifier=YOUR_CODE_VERIFIER

The response holds an access_token, a refresh_token, and expires_in. Access tokens last 2 hours.

3. Call the API

curl https://app.temponia.com/api/v1/projects \
  -H "Authorization: Bearer THE_ACCESS_TOKEN"

4. Refresh when it expires

curl -X POST https://app.temponia.com/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token=THE_REFRESH_TOKEN \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_CLIENT_SECRET

Legacy API keys

Older clients exchange an email and password for a permanent key:

curl -X POST https://app.temponia.com/api/v1/authenticate \
  -d [email protected] \
  -d password=... \
  -d application=my-script

The key in the response works as a bearer token with full access, and it does not expire. It also stops working the moment the user is deactivated. Prefer OAuth applications for anything new: they are scoped, revocable one by one, and never see the user's password. Note that users who sign in with Google, Microsoft or Xero have no password to use here, so OAuth is also the only option that works for everyone.

Still stuck?

Open a support ticket and tell us your workspace name and what you were trying to do. A real person answers, usually within one working day.