Authenticate
Every request carries
Authorization: Bearer mx_live_… and X-Organization-ID.Pick an SDK
Official JavaScript and Python clients wrap every operation on this page.
Handle errors
Three error-envelope shapes, including the billing
DenialEnvelope.Stream results
Long-running runs stream over Server-Sent Events, not a polling loop.
Base URL
All API requests go to a single host. There is no separate path prefix for the API: routers mount directly at their resource path.Base URL
- JavaScript:
DEFAULT_BASE_URL = 'https://api.modulex.dev', overridable with thebaseUrlclient option. - Python:
DEFAULT_BASE_URL = "https://api.modulex.dev", overridable with thebase_urlargument or theMODULEX_BASE_URLenvironment variable.
POST https://api.modulex.dev/workflows/run.
Trailing-slash redirects are disabled (
redirect_slashes=False). Call /workflows, not /workflows/ — a trailing slash is not auto-corrected and will not match the route. The SDKs build paths correctly for you.No /v1 in the path
ModuleX does not put a version segment in the URL. There is no /v1, /api, or /api/v1 prefix anywhere in the routing scheme — paths are exactly their resource name.
/v1 you may have copied from another API. A versioned path returns 404 Not Found because the route is not registered.
Breaking changes are communicated through the changelog and SDK release notes rather than through a URL version. See Base URLs & versioning for how ModuleX evolves the API without a path version.
Request lifecycle
Every authenticated call follows the same path. Authentication and organization context are resolved as route dependencies — there is no separate request-id or auth middleware to account for.You send a request
Set the method and resource path, attach the two required headers (
Authorization: Bearer and X-Organization-ID), and send a JSON body for write operations.Credentials are verified
A
Bearer token that starts with mx_live_ is treated as an API key; any other Bearer token is treated as a Clerk session JWT (used by the app). A missing or invalid token returns 401.Organization context is applied
For org-scoped operations, ModuleX reads
X-Organization-ID and checks your membership and role. A missing header returns 400; a non-member or a role too low for the operation returns 403. See Roles & permissions.Rate limits and the billing gate run
API-key traffic is rate limited per key and per user, and org traffic is rate limited per organization. Operations that consume managed usage also pass the usage gate before any work begins. Either check can stop the request with a
429, 403, or 402.The operation runs and responds
The handler executes and returns a JSON body. For most operations that is the final result. For runs and agent turns, the response returns immediately with run metadata and the result streams separately over SSE.
🎬 MEDIA PLACEHOLDER · MX-MEDIA-1180 · [IMAGE]
[IMAGE_DESCRIPTION]: Request lifecycle diagram for a ModuleX API call.
[IMAGE_DETAILS]: A left-to-right flow with five stages matching the Steps above — Client request (showing the two required headers) → Auth (Bearer mx_live_* vs Clerk JWT branch) → Org context (X-Organization-ID, role check) → Rate limit + usage gate (showing the 429 / 403 / 402 exit) → Handler → JSON response, with a side branch from the handler labeled “SSE stream” for runs and agent turns. Annotate each guard with its failure status code. 16:9, light theme, ModuleX brand palette, no drop shadows.
Authentication recap
Authentication is the same on every operation, so it is documented in full on one page. Each request needs two headers:| Header | Value | Required |
|---|---|---|
Authorization | Bearer mx_live_… (your API key) | Yes |
X-Organization-ID | The organization UUID the call acts on | Yes for org-scoped operations |
X-API-KEY header as an alternative to Authorization: Bearer, but the SDKs and all examples in these docs use Authorization: Bearer. The header is X-Organization-ID (capital ID); there is no X-Authorization header.
For the full authentication model — how to create and scope keys, the difference between API keys and Clerk JWTs, and every auth-related status code — see Authentication and Auth model: JWT vs API key.
Content types and conventions
Send
application/json for request bodies. Document upload to a knowledge base is the exception: those endpoints accept multipart/form-data.Responses are JSON by default. Streaming endpoints return
text/event-stream (Server-Sent Events) instead.Request and response bodies use
snake_case on the wire (for example workflow_id, created_at, run_id). The Python SDK uses snake_case end to end. The JavaScript SDK accepts camelCase in method parameters and converts to snake_case before sending, but leaves responses in snake_case — so a JS response field is run_id, not runId.Timestamps are ISO 8601 strings in UTC, for example
2026-06-21T12:00:00Z.Resource identifiers are strings. Note that
run_id carries distinct meanings across layers — see Workflows & runs for the three run-id identities.One operation, three ways, plus a playground
Each operation is documented once. Instead of separate per-language pages, you get a singleCodeGroup with three tabs — cURL, Python, JavaScript — that all perform the same call, plus an interactive playground for the underlying endpoint.
cURL
The raw HTTP request: exact method, path, headers, and JSON body.
Python
The async
modulex-python client (v1.0.0).JavaScript
The
modulex-js client (v1.0.0).subscriptions resource that exists only in the Python SDK.
Example: run a workflow
This is what the three-way pattern looks like. Running a deployed workflow is a singlePOST /workflows/run. The synchronous response returns immediately with run metadata while the result streams over SSE.
The per-execution identifier. Use it to stream events and to look up run status. A new
run_id is minted on each run and on each resume of an interrupted run.The status of the synchronous portion. For a streaming run this is
"running"; terminal statuses (completed, failed, cancelled, interrupted) are observed over the SSE stream or the run-history endpoints, not here.Live playground
Endpoint reference pages include a live “Try it” playground generated from the ModuleX OpenAPI specification. Enter your API key and organization ID once, fill in parameters, and send a real request from the browser to see the actual response. The playground exercises the same routes documented above — for examplePOST /workflows/run, GET /workflows, and POST /knowledge-bases/{knowledge_id}/search.
🎬 MEDIA PLACEHOLDER · MX-MEDIA-1181 · [SCREENSHOT]
[SCREENSHOT_DESCRIPTION]: The interactive API playground for an endpoint, mid-request.
[SCREENSHOT_DETAILS]: Capture a generated endpoint reference page (for example
POST /workflows/run) showing the auth fields populated with Authorization: Bearer mx_live_… and X-Organization-ID, the request-body editor with the example body filled in, and a successful JSON response panel below the Send button. Crop to the playground panel. Light theme, ModuleX docs chrome, redact any real key value.Errors
Operations return standard HTTP status codes. ModuleX has three error-envelope shapes, and you should branch on all of them. The shape depends on the surface that produced the error.The common FastAPI shape, used by plain CRUD and org-settings routes. The
detail is a human-readable string, for example { "detail": "X-Organization-ID header is required" }.A dict-valued
detail, used by the organization rate-limit deny (code: "rate_limited") and the wallet paid-gate 402.The flat billing/credit/rate/quota envelope returned by the usage gate, with no
detail wrapper: { code, layer, key, current, limit, reason }.DenialEnvelope whose layer field maps to the status code:
layer | HTTP status | Meaning |
|---|---|---|
rate | 429 | Rate limit exceeded (also carries X-RateLimit-* and Retry-After headers) |
quota | 403 | A plan quota was exceeded |
credit | 402 | Plan credit allowance exhausted, or an upgrade payment failed |
wallet | 402 | Overage is disabled, or the prepaid wallet has insufficient balance |
{detail} HTTPException shape instead. For the complete status-code taxonomy, every error code, and which surface emits each shape, see Errors & status codes, Rate limiting, and Usage gating & limits.
Where to go next
Authentication
Create keys, scope them to an organization, and authenticate every call.
SDKs overview
Install the JavaScript or Python client and use every operation from code.
Run a workflow
A full REST and SDK walkthrough, from key to streamed result.
Errors & status codes
The three envelope shapes and the billing
DenialEnvelope in detail.