Documentation menu

Authentication

The API authenticates with JWT bearer tokens issued by POST /auth/login and renewed with POST /auth/refresh. Every endpoint except /health, the docs, and the two auth endpoints requires a token.

Obtaining tokens

Log in with an account's email and password to receive a token bundle. Both auth endpoints are rate-limited to 30 requests per 15 minutes — cache tokens, don't log in per request.

curl -X POST https://api.carbon-calculator.eventzero.io/api/v2/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "svc-integration@your-org.com", "password": "<password>"}'
FieldTypeRequiredDescription
accessTokenstringoptionalAWS Cognito access token; send it on subsequent v2 requests as the `Authorization: Bearer <accessToken>` header.
idTokenstringoptionalAWS Cognito ID token carrying the authenticated user's identity claims.
refreshTokenstringoptionalAWS Cognito refresh token used to obtain new access tokens; returned by POST /auth/login but NOT by POST /auth/refresh (the original refresh token stays valid until it expires).
expiresInintegeroptionalLifetime of the access token in seconds, after which it must be refreshed.
tokenTypestringoptionalToken type for the Authorization header; always "Bearer".

Using the access token

curl https://api.carbon-calculator.eventzero.io/api/v2/events \
  -H "Authorization: Bearer <accessToken>"

Send the access token as a bearer header on every request. When it expires (after expiresIn seconds), a request returns 401 UNAUTHENTICATED — refresh and retry.

Refreshing

curl -X POST https://api.carbon-calculator.eventzero.io/api/v2/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refreshToken": "<refreshToken>"}'

The refresh endpoint returns a new access and ID token but no new refresh token — the original refresh token remains valid until it expires, at which point the integration must log in again with credentials.

Service accounts and credential handling

The API does not issue API keys and has no OAuth client_credentials flow today: the only way to authenticate is with a user's email and password. For integrations, we recommend:

  • Use a dedicated service-account user provisioned for the integration (ask your EventZero contact to set one up) — never a person's login.
  • Give it the least role that works: most reads and record-writes work as a standard user; creating events and running review/approve require a manager role. See Roles & permissions.
  • Store the credentials in a secret manager, inject them at runtime, and rotate them on your normal credential-rotation schedule.
MFA: Accounts with MFA or a pending password challenge cannot authenticate through this API — the login endpoint returns 401 for any challenged sign-in. Service accounts should be provisioned without MFA.