Skip to Content
APIAuthentication

Authentication

The Curate-Me API uses JWT (JSON Web Tokens) for authentication. Access tokens are short-lived and refresh tokens allow you to obtain new access tokens without re-authenticating.

Token Lifetimes

TokenLifetimePurpose
Access token30 minutesAuthorize API requests
Refresh token7 daysObtain new access tokens

Register

Create a new user account.

POST /api/v1/auth/register

Request:

{ "email": "user@example.com", "password": "securePassword123", "name": "Jane Doe" }

Response (201):

{ "user": { "id": "usr_abc123", "email": "user@example.com", "name": "Jane Doe", "created_at": "2026-01-15T10:30:00Z" }, "access_token": "eyJhbGciOiJIUzI1NiIs...", "refresh_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "bearer", "expires_in": 1800 }

Login

Authenticate with email and password.

POST /api/v1/auth/login

Request:

{ "email": "user@example.com", "password": "securePassword123" }

Response (200):

{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "refresh_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "bearer", "expires_in": 1800 }

Refresh Token

Exchange a valid refresh token for a new access token.

POST /api/v1/auth/refresh

Request:

{ "refresh_token": "eyJhbGciOiJIUzI1NiIs..." }

Response (200):

{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "bearer", "expires_in": 1800 }

Logout

Invalidate the current access and refresh tokens.

POST /api/v1/auth/logout

Headers:

Authorization: Bearer {access_token}

Request:

{ "refresh_token": "eyJhbGciOiJIUzI1NiIs..." }

Response (204): No content.

Using Tokens

Include the access token in the Authorization header on all authenticated requests:

curl -X GET https://api.curate-me.ai/api/v1/user/profile \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

B2B Organization Context

For B2B API requests, include the X-Org-ID header to specify the organization context. The middleware resolves organization identity in the following priority order:

  1. JWT claimsorg_id and org_role embedded in the token payload.
  2. X-Org-ID header — Passed explicitly by the dashboard client.
  3. URL path parameter — Extracted from /organizations/{org_id}/... routes.
curl -X GET https://api-admin.curate-me.ai/api/v1/admin/agents/status \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "X-Org-ID: org_xyz789"

B2B API Keys

For server-to-server integrations, you can create long-lived API keys instead of using JWT tokens.

Create an API Key

POST /api/v1/b2b/api-keys

Headers:

Authorization: Bearer {access_token} X-Org-ID: org_xyz789

Request:

{ "name": "Production Integration", "scopes": ["agents:read", "workflows:read", "workflows:execute", "costs:read"] }

Response (201):

{ "id": "key_abc123", "name": "Production Integration", "key": "cm_live_sk_abc123def456...", "scopes": ["agents:read", "workflows:read", "workflows:execute", "costs:read"], "created_at": "2026-01-15T10:30:00Z" }

The full key value is only returned once at creation time. Store it securely.

Using API Keys

Pass the API key in the X-API-Key header:

curl -X GET https://api-admin.curate-me.ai/api/v1/admin/agents/status \ -H "X-API-Key: cm_live_sk_abc123def456..."

API keys are scoped to a specific organization and do not require the X-Org-ID header.