Skip to main content
Every request to the ModuleX REST API is authenticated with a ModuleX API key sent in the Authorization header, and — for any organization-scoped endpoint — scoped to one organization with the X-Organization-ID header. The two SDKs send exactly these headers for you.
The API does not read a header named X-Authorization. There is no such header anywhere in the backend or in either SDK. Use Authorization: Bearer (preferred) or the X-API-KEY fallback, both described below.

The two headers you send

A minimal authenticated request looks like this:
Authenticated request
The base URL is https://api.modulex.dev and there is no /v1 path segment — routers are mounted at the root. See Base URLs & versioning for environments and the versioning policy, and the API overview for the full request lifecycle.

API keys

A ModuleX API key is a per-user secret used by SDKs and any programmatic caller. It is distinct from the Clerk session token (JWT) that the web app uses — see Auth model: JWT vs API key for how the two paths differ.

Key format

The backend distinguishes credentials by prefix: a token starting with mx_live_ is treated as an API key; anything else presented as a bearer token is treated as a Clerk JWT.
The full key is returned only in the response to creating it. List and detail endpoints return a masked value (mx_live_2J9vK4xM********). Store the key in a secret manager when you create it — there is no way to recover it later. If you lose it, revoke the key and create a new one.

Create a key

Create keys in the app (Settings → API keys) or via the API. Creating a key requires an authenticated, already-provisioned user — you can present either a Clerk JWT or an existing mx_live_ API key, so one key can create another. Only the very first key needs a JWT-provisioned account to bootstrap from.
string
required
A label for the key. 1–255 characters.
string
Scope the key to a single organization. The caller must be an active member of that organization. When omitted (the default), the key works across all of your organizations and you choose the organization per request with X-Organization-ID.
string
An ISO 8601 timestamp. When omitted (the default), the key never expires.
integer
default:"60"
Per-key request budget, 1–1000.
The create response (HTTP 201) is the only response that includes the full key:
string
UUID of the key record.
string
The label you set.
string
The full mx_live_… key. Returned only here.
string
The first 8 characters of the random part, for display.
string
mx_live_{hint}******** — what list/detail endpoints return.
string | null
The org the key is scoped to, or null for all orgs.
string | null
Expiry timestamp, or null for never.
boolean
Whether the key is past its expiry.
boolean
Whether the key is active (not revoked).
integer
The per-key budget.
string | null
When the key was last used, or null.
string
Creation timestamp.
string | null
When the key was revoked, or null.

Key limits

Revoke a key

Revoking is permanent and immediate; the record is kept for audit. A revoked key returns 401 on its next use.
Revoke a key

Sending the key

You can present the key two ways. Both are accepted by the backend.
This is what both SDKs send, and what you should use.
The backend resolves credentials in this order:
1

Authorization: Bearer

If present and the token starts with mx_live_, it is used as an API key. Otherwise it is verified as a Clerk JWT.
2

X-API-KEY

Consulted only if no bearer credential resolved, and only if the value starts with mx_live_.
3

Neither

A 401 is returned: Authentication required. Provide Authorization: Bearer token or X-API-KEY header.

Organization scope

ModuleX is multi-tenant. Identity (your key) and organization (the tenant you act in) are two separate axes: the key says who you are; X-Organization-ID says which organization the request runs against. Most resources — workflows, runs, knowledge bases, credentials, integrations, the composer, the assistant, and schedules — are organization-scoped and require the header. Identity-only endpoints such as GET /auth/me and GET /auth/invitations/my do not.
Org-scoped request
On an org-scoped endpoint, the backend checks the header in this order:
1

Header present

Missing X-Organization-ID on an org-scoped route returns 400: X-Organization-ID header is required.
2

Key scope matches

If the key is scoped to a specific organization (you set organization_id when creating it), the header must name that same organization, or you get 403: API key is scoped to a different organization.
3

Membership

You must be a member of the named organization, or you get 403: User is not a member of organization {id}.
4

Role

Some surfaces require a privileged role (see below).
Find the organizations you belong to — and their ids — with GET /auth/me/organizations. The header value is the organization’s id. For the full org-context model see Org context & X-Organization-ID and the concept page on organizations, roles & membership.
A few request bodies also carry an organization_id field (for example, when creating an org-scoped API key). That field sets which organization owns the new resource. It is independent of the X-Organization-ID header, which sets which organization you are acting in. Do not conflate the two.

Roles

The live organization roles are owner and admin. The member role is retired and is not a current role — document and design against owner/admin only. A handful of surfaces require owner or admin rather than plain membership: the composer, the assistant, and the organization-settings and member-management endpoints. A membership-only call to one of these returns 403. See Roles & permissions for the per-endpoint matrix.

Authenticating with the SDKs

Both official SDKs send Authorization: Bearer <key> and add X-Organization-ID whenever an organization is resolved. The default base URL is https://api.modulex.dev; pass baseUrl / base_url to target another environment.
You can override the organization per call without changing the client default:
Environment-variable fallback differs between the SDKs. The Python SDK reads MODULEX_API_KEY, MODULEX_ORGANIZATION_ID, and MODULEX_BASE_URL when the matching argument is omitted. The JavaScript SDK has no such fallback — you must pass apiKey (and organizationId) to the constructor explicitly, or it throws. Any process.env.* usage in JS examples is your own caller code, not SDK behavior.
See the JavaScript SDK and Python SDK pages for installation and full configuration, and SDKs overview for how each operation maps across cURL, Python, and JavaScript.

Error responses

Authentication and organization-scope failures use the standard FastAPI envelope, {"detail": "<message>"}.
401 example

Rate-limit responses

When you exceed a key’s per-minute budget or the across-keys per-user budget, the per-key limiter returns 429 with a string detail and rate-limit headers:
429 (per-key / per-user limiter)
The organization-level api-class limiter can also return 429, but with a dict-valued detail:
429 (org api-class limiter)
A third 429 shape — the flat billing-gate DenialEnvelope — appears only on run and managed-usage surfaces (workflow runs, composer, assistant, managed knowledge), never on a CRUD or settings route. The same surfaces can also return 402 and 403 billing denials. See Usage gating & limits for the gate, Rate limiting for all three 429 shapes, and Errors & status codes for the complete envelope reference.

Security notes

  • Treat the key like a password. Send it only over HTTPS; never embed it in client-side code, a public repository, or a URL query string.
  • Use X-API-KEY only if you cannot set AuthorizationAuthorization: Bearer is the supported path.
  • Scope keys to one organization and set a tight rate_limit_per_minute for automation, so a leaked key has limited blast radius.
  • Rotate by creating a new key, switching traffic, then revoking the old one. Revocation is immediate.
  • The Clerk JWT used by the web app and the mx_live_ API key used by code are different credentials with different lifecycles. See Auth model: JWT vs API key for which path to use where.

Next steps

Quickstart

Get a key and make your first authenticated call.

Org context & X-Organization-ID

How organization scope is resolved and enforced.

Errors & status codes

Every error envelope and what produces it.

Glossary

Canonical terms: API key, Clerk JWT, organization, role.