OAuth 2.0 & API Access

Authenticate with Evergreen using OAuth 2.0 access tokens or long-lived API keys.

Evergreen supports two ways for external applications and integrations to authenticate against its API:

MethodToken prefixBest for
Long-lived API keyevg_Server-to-server integrations, personal scripts
OAuth 2.0 access tokenevg_at_Third-party apps that act on behalf of a user

Both token formats are accepted in the same Authorization: Bearer header — Evergreen detects the format automatically based on the prefix.


OAuth 2.0 Authorization Code Flow

Evergreen implements the RFC 6749 Authorization Code Grant with PKCE and supports dynamic client registration (RFC 7591).

Discovery endpoints

EndpointURL
Authorization server metadata/.well-known/oauth-authorization-server
Protected resource metadata/.well-known/oauth-protected-resource

These follow standard OAuth 2.0 discovery conventions and allow compatible clients to configure themselves automatically.

Step 1 — Register your client

Send a POST request to /api/oauth/register with a JSON body:

{
  "client_name": "My App",
  "redirect_uris": ["https://myapp.example.com/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}

Required fields:

  • client_name — Human-readable name shown on the consent screen.
  • redirect_uris — One or more callback URLs. Each URI must use https or point to localhost.

Optional fields:

FieldDefault
grant_types["authorization_code", "refresh_token"]
response_types["code"]
token_endpoint_auth_method"none" (public client)
scopeAll available scopes

The response contains your client_id and, for confidential clients, a client_secret. Store the secret securely — it is shown only once.

Step 2 — Redirect the user to /oauth/authorize

Construct an authorization URL:

https://app.evergreen.so/oauth/authorize
  ?response_type=code
  &client_id=evg_client_…
  &redirect_uri=https://myapp.example.com/callback
  &scope=read:projects%20read:analytics
  &state=<random-state>
  &code_challenge=<base64url-sha256-of-verifier>
  &code_challenge_method=S256

The user will see a consent screen listing the requested scopes and registered client name. After they approve, Evergreen redirects back to your redirect_uri with a short-lived authorization code (valid for 10 minutes).

Step 3 — Exchange the code for tokens

Send a POST request to /api/oauth/token:

{
  "grant_type": "authorization_code",
  "code": "<auth-code>",
  "redirect_uri": "https://myapp.example.com/callback",
  "client_id": "evg_client_…",
  "code_verifier": "<pkce-verifier>"
}

A successful response returns:

{
  "access_token": "evg_at_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "evg_rt_…",
  "scope": "read:projects read:analytics"
}
  • Access tokens (evg_at_) expire after 1 hour.
  • Refresh tokens expire after 30 days.

Step 4 — Call the API

Include the access token as a Bearer token in every request:

Authorization: Bearer evg_at_…

Step 5 — Refresh the access token

When the access token expires, obtain a new one using the refresh token:

{
  "grant_type": "refresh_token",
  "refresh_token": "evg_rt_…",
  "client_id": "evg_client_…"
}

Available Scopes

ScopeAccess granted
read:projectsList and read project details
read:pagesRead page-level data
read:analyticsRead analytics data
read:performanceRead performance metrics
read:structureRead site structure data

If no scope is specified, all available scopes are granted by default. Requests for unlisted scopes are silently dropped.


Long-Lived API Keys

API keys use the evg_ prefix. They do not expire and are suitable for automated server-side workflows. You can manage API keys from Settings → MCP Server.

Note: API keys grant the same scopes as OAuth tokens but are not tied to a specific user authorization flow. Use OAuth when building apps that act on behalf of individual users.


Error Codes

Token endpoint errors follow RFC 6749 §5.2 and return a JSON body:

{
  "error": "invalid_grant",
  "error_description": "…"
}

Common error codes:

CodeMeaning
invalid_requestA required parameter is missing or malformed
invalid_clientClient authentication failed
invalid_grantThe authorization code or refresh token is invalid or expired
unauthorized_clientThe client is not permitted to use this grant type
unsupported_grant_typeThe requested grant type is not supported
invalid_scopeThe requested scope is invalid