Olympus Platform API
Download OpenAPI (platform.yaml) · Base URL https://api.olympus.new-odyssey.com
Accounts, organizations, API keys and usage for Olympus, government data infrastructure by New Odyssey.
Console endpoints (/v1/auth/*, /v1/me, /v1/organizations/*) are used by the developer console. They authenticate with an HttpOnly session cookie set by POST /v1/auth/login. Every state-changing console request (POST, PATCH, DELETE), signed in or not, must send the X-Olympus-CSRF header (any non-empty value); browsers must also send an Origin (or Referer) that is an allowed console origin.
Customer endpoints (/v1/usage and every product under /v1/<product>/...) authenticate with an API key in X-API-Key or Authorization: Bearer. Product requests also require the organization's plan to include the product, and count against its monthly quota.
Every response carries X-Request-Id. Errors share the Error body. Responses never reveal whether an email address is registered.
Health
Liveness
/healthAuthentication: None
Responses
| 200 | The process is serving. | Health |
Liveness
/health/liveAuthentication: None
Responses
| 200 | The process is serving. | Health |
Readiness (database and Redis)
/health/readyAuthentication: None
Responses
Auth
Create an account
/v1/auth/signupCreates a user, a personal organization owned by the user and a Free plan subscription, then emails a verification link. Always answers 202 for a well-formed request; if the address is already registered, its owner is emailed a notice instead. Sign in with POST /v1/auth/login afterwards.
Authentication: X-Olympus-CSRF header
Request body
application/json — SignupRequest
Responses
Verify an email address
/v1/auth/verify-emailConsumes a single-use verification token from the emailed link.
Authentication: X-Olympus-CSRF header
Request body
application/json — TokenRequest
Responses
Resend the verification email
/v1/auth/resend-verificationAuthentication: Console session cookie + X-Olympus-CSRF header
Responses
Sign in
/v1/auth/loginSets the session cookie. Unknown addresses and wrong passwords both answer 401 INVALID_CREDENTIALS. Attempts are throttled per address and per client IP.
Authentication: X-Olympus-CSRF header
Request body
application/json — LoginRequest
Responses
| 200 | Signed in. | LoginResponse |
| 400 | Malformed request ( | Error |
| 401 | Invalid email or password ( | Error |
| 403 | CSRF check failed ( | Error |
| 429 | Too many attempts ( | Error |
Sign out
/v1/auth/logoutRevokes the current session and clears the cookie.
Authentication: Console session cookie + X-Olympus-CSRF header
Responses
Request a password reset email
/v1/auth/forgot-passwordAlways answers 202 for a valid address, whether or not an account exists.
Authentication: X-Olympus-CSRF header
Request body
application/json — object
Responses
Set a new password with a reset token
/v1/auth/reset-passwordConsumes the single-use token, sets the password, verifies the email address and revokes every session of the user.
Authentication: X-Olympus-CSRF header
Request body
application/json — object
Responses
The signed-in user and their organizations
/v1/meAuthentication: Console session cookie
Responses
Organizations
List my organizations
/v1/organizationsAuthentication: Console session cookie
Responses
| 200 | Organizations the user belongs to. | |
| 401 | No valid session ( | Error |
Get an organization with its plan and entitlements
/v1/organizations/{org_id}Authentication: Console session cookie
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
Responses
| 200 | The organization. | OrganizationDetail |
| 401 | No valid session ( | Error |
| 404 | Not found, or not visible to the caller ( | Error |
Members
List members
/v1/organizations/{org_id}/membersAuthentication: Console session cookie
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
Responses
Change a member's role
/v1/organizations/{org_id}/members/{user_id}Owners and admins may change roles; only owners may grant the owner role or change an owner. The last owner cannot be demoted.
Authentication: Console session cookie + X-Olympus-CSRF header
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
| user_idrequired | path | string (uuid) |
Request body
application/json — object
Responses
| 200 | The updated member. | Member |
| 400 | Invalid fields ( | Error |
| 401 | No valid session ( | Error |
| 403 | Insufficient role ( | Error |
| 404 | Not found, or not visible to the caller ( | Error |
| 409 | The organization must keep at least one owner ( | Error |
Remove a member
/v1/organizations/{org_id}/members/{user_id}Any member may remove themselves. Owners and admins may remove others; only owners may remove an owner. The last owner cannot be removed.
Authentication: Console session cookie + X-Olympus-CSRF header
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
| user_idrequired | path | string (uuid) |
Responses
API keys
List API keys (secrets are never returned)
/v1/organizations/{org_id}/api-keysAuthentication: Console session cookie
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
Responses
Create an API key
/v1/organizations/{org_id}/api-keysOwners and admins with a verified email address only. The response contains the secret; it is shown once and cannot be retrieved again. At most 50 unrevoked keys per organization.
Authentication: Console session cookie + X-Olympus-CSRF header
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
Request body
application/json — object
Responses
| 201 | The new key, with its secret. | CreatedAPIKey |
| 400 | Invalid fields ( | Error |
| 401 | No valid session ( | Error |
| 403 | Insufficient role ( | Error |
| 404 | Not found, or not visible to the caller ( | Error |
| 409 | Too many keys ( | Error |
Revoke an API key
/v1/organizations/{org_id}/api-keys/{key_id}The key stops working immediately. Its record is kept for usage history and the audit log.
Authentication: Console session cookie + X-Olympus-CSRF header
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
| key_idrequired | path | integer (int64) |
Responses
Rotate an API key
/v1/organizations/{org_id}/api-keys/{key_id}/rotateCreates a key with the same name and environment and revokes the old one, atomically. The new secret is shown once.
Authentication: Console session cookie + X-Olympus-CSRF header
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
| key_idrequired | path | integer (int64) |
Responses
| 201 | The replacement key, with its secret. | CreatedAPIKey |
| 401 | No valid session ( | Error |
| 403 | Insufficient role ( | Error |
| 404 | Not found, or not visible to the caller ( | Error |
| 409 | The API key is already revoked ( | Error |
Usage
Organization usage (console)
/v1/organizations/{org_id}/usageAuthentication: Console session cookie
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
| from | query | string (date) | First UTC day (inclusive). Defaults to 29 days before |
| to | query | string (date) | Last UTC day (inclusive). Defaults to today. The range may cover at most 90 days. |
| product | query | string | Only this product (e.g. |
| api_key_id | query | integer (int64) | Only this API key of the organization. |
Responses
| 200 | Usage summary. | UsageSummary |
| 400 | Invalid fields ( | Error |
| 401 | No valid session ( | Error |
| 404 | Not found, or not visible to the caller ( | Error |
Usage for the API key's organization
/v1/usageMetered requests across every product and key of the caller's organization. Requests to this endpoint are themselves metered as product platform.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| from | query | string (date) | First UTC day (inclusive). Defaults to 29 days before |
| to | query | string (date) | Last UTC day (inclusive). Defaults to today. The range may cover at most 90 days. |
| product | query | string | Only this product (e.g. |
| api_key_id | query | integer (int64) | Only this API key of the organization. |
Responses
| 200 | Usage summary. | UsageSummary |
| 400 | Invalid fields ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/usage" \
-H "X-API-Key: $OLYMPUS_API_KEY"Audit
List audit events (owners and admins)
/v1/organizations/{org_id}/audit-logAuthentication: Console session cookie
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| org_idrequired | path | string (uuid) | Organization ID. Organizations the caller does not belong to answer 404. |
| before | query | integer (int64) | Return events older than this event ID (the previous page's |
| limit | query | integer |
Responses
| 200 | Events, newest first. | |
| 400 | Invalid fields ( | Error |
| 401 | No valid session ( | Error |
| 403 | Insufficient role ( | Error |
| 404 | Not found, or not visible to the caller ( | Error |
Schemas
Error object
The error body shared by every Olympus service.
| Field | Type | Description |
|---|---|---|
| error * | string | Human-readable message. |
| code * | string | Stable machine-readable code. |
| product | string | Product that produced the error, when applicable. |
| details | object |
Health object
| Field | Type | Description |
|---|---|---|
| status * | enum: ok | degraded | |
| product * | string | |
| version * | string | |
| timestamp * | string (date-time) | |
| checks | object |
SignupRequest object
| Field | Type | Description |
|---|---|---|
| email * | string (email) | |
| password * | string | Common passwords, simple sequences and passwords containing the email name are rejected. |
| name | string | |
| organization_name | string | Name of the personal organization. Defaults to "<name>'s workspace". |
TokenRequest object
| Field | Type | Description |
|---|---|---|
| token * | string |
LoginRequest object
| Field | Type | Description |
|---|---|---|
| email * | string (email) | |
| password * | string |
LoginResponse object
| Field | Type | Description |
|---|---|---|
| user * | User | |
| session_expires_at * | string (date-time) |
User object
| Field | Type | Description |
|---|---|---|
| id * | string (uuid) | |
| email * | string (email) | |
| name * | string | |
| email_verified * | boolean | |
| email_verified_at * | string (date-time) | null | |
| created_at * | string (date-time) | |
| last_login_at * | string (date-time) | null |
Me object
| Field | Type | Description |
|---|---|---|
| user * | User | |
| organizations * | array of object |
Role enum: owner | admin | member
owneradminmember
Organization object
| Field | Type | Description |
|---|---|---|
| id * | string (uuid) | |
| name * | string | |
| is_personal * | boolean | |
| status * | enum: active | suspended | |
| created_at * | string (date-time) | |
| role * | Role | The caller's role. |
OrganizationDetail object
| Field | Type | Description |
|---|---|---|
| id * | string (uuid) | |
| name * | string | |
| is_personal * | boolean | |
| status * | enum: active | suspended | |
| created_at * | string (date-time) | |
| role * | Role | The caller's role. |
| subscription | Subscription | |
| entitlements * | Entitlement [] | |
| quota | QuotaUsage |
QuotaUsage object
Monthly quota use in the period the quota is currently counted for. After the stored subscription period ends, periods continue monthly from its start. Omitted when the organization has no subscription.
| Field | Type | Description |
|---|---|---|
| period_start * | string (date-time) | |
| period_end * | string (date-time) | |
| products * | array of object |
Subscription object
| Field | Type | Description |
|---|---|---|
| plan * | enum: free | developer | growth | business | enterprise | |
| plan_name * | string | |
| monthly_price_cents * | integer | |
| status * | enum: trialing | active | past_due | canceled | |
| current_period_start * | string (date-time) | |
| current_period_end * | string (date-time) |
Entitlement object
| Field | Type | Description |
|---|---|---|
| product * | string | |
| monthly_request_quota * | integer (int64) | null | Null means unlimited. |
| rate_limit_per_minute * | integer | |
| historical_access * | boolean | |
| bulk_access * | boolean |
Member object
| Field | Type | Description |
|---|---|---|
| user_id * | string (uuid) | |
| email * | string (email) | |
| name * | string | |
| role * | Role | |
| joined_at * | string (date-time) |
APIKey object
| Field | Type | Description |
|---|---|---|
| id * | integer (int64) | |
| name * | string | |
| prefix * | string | The first characters of the secret, for recognising the key. |
| environment * | enum: live | test | |
| product * | string | null | The one product the key is scoped to; null for every product on the plan. |
| status * | enum: active | expired | revoked | |
| created_by_user_id * | string (uuid) | null | |
| created_at * | string (date-time) | |
| last_used_at * | string (date-time) | null | Updated at most about once a minute. |
| expires_at * | string (date-time) | null | |
| revoked_at * | string (date-time) | null |
CreatedAPIKey object
| Field | Type | Description |
|---|---|---|
| id * | integer (int64) | |
| name * | string | |
| prefix * | string | The first characters of the secret, for recognising the key. |
| environment * | enum: live | test | |
| product * | string | null | The one product the key is scoped to; null for every product on the plan. |
| status * | enum: active | expired | revoked | |
| created_by_user_id * | string (uuid) | null | |
| created_at * | string (date-time) | |
| last_used_at * | string (date-time) | null | Updated at most about once a minute. |
| expires_at * | string (date-time) | null | |
| revoked_at * | string (date-time) | null | |
| secret * | string | The full key. Returned only in this response. |
AuditEvent object
| Field | Type | Description |
|---|---|---|
| id * | integer (int64) | |
| actor_user_id * | string (uuid) | null | |
| actor_api_key_id * | integer (int64) | null | |
| action * | string | |
| target_type * | string | |
| target_id * | string | |
| metadata * | object | |
| ip * | string | |
| created_at * | string (date-time) |
UsageSummary object
| Field | Type | Description |
|---|---|---|
| organization_id | string (uuid) | |
| api_key_id | integer (int64) | |
| product | string | |
| from * | string (date) | |
| to * | string (date) | |
| total_requests * | integer (int64) | |
| by_day * | array of object | |
| by_product * | array of object | |
| by_endpoint * | array of object |
* required field