Madoo Public API — Developer Guide (v1)
Welcome. This guide is everything you need to integrate Madoo into your own product or backend. It is written for developers who have never seen Madoo before: by the end of this page you will understand what Madoo does, how an integration is shaped, and where to go next for the details.
You do not need to read our source code, and you do not need to understand how the engine works internally. You only need to understand a handful of concepts — and this page introduces all of them.
1. What is Madoo?
Section titled “1. What is Madoo?”Madoo is a workflow engine for AI-powered media generation — images, video, audio, 3D, text and print-ready documents — for marketing, advertising, publishing, e-commerce and more. A workflow is a pipeline that someone has designed in Madoo’s visual editor: it takes some inputs (a product photo, a brand description, a title…), runs them through a series of AI steps, and produces some outputs (a hero image, a piece of marketing copy, a video…).
The Public API lets your application do, programmatically, what a person would otherwise do by hand in the Madoo dashboard:
- Discover the workflows available to you and learn exactly what each one expects.
- Run a workflow by submitting inputs.
- Track the run as it progresses.
- Retrieve the generated outputs.
A useful mental model: a workflow is like a function, and the Public API is how you call that function over HTTP. The function’s signature — its parameters and its return values — is what we call the workflow’s interface (see §4). Your job as an integrator is to read that interface, fill in the inputs, call the function, and collect the results.
One workflow, run thousands of times. Workflows are designed once (by you or by a Madoo author) and then executed repeatedly with different inputs. That is the whole point: a “newsletter hero image” workflow is built once and then run for every product in a catalog.
2. The core mental model: Organization → Workspace → API key
Section titled “2. The core mental model: Organization → Workspace → API key”Everything in Madoo is scoped by a two-level tenancy model. You must understand it because it determines what your API calls can see and do.
Organization (your company / account — billing lives here) └── Workspace (a project / brand / environment inside the org) └── API key (credentials your app uses — scoped to a workspace) └── Workflows, Executions, Assets… (everything you touch via the API)- An Organization is the top-level account. Your plan, credits, and billing belong to the organization.
- A Workspace is a subdivision of the organization — think of it as a project or a brand. All resources (workflows, executions, uploaded files) live inside a workspace.
- An API key is the credential your application uses. Every API key is bound to a single workspace. When you authenticate, the resulting access token already “knows” which organization and workspace it belongs to — so your calls automatically operate inside that workspace, and cannot see another workspace’s data.
This is why workspace context is mandatory for almost every endpoint: the API needs to know which workspace you are acting in, and that information comes from your API key. (The only exception is the token endpoint itself, which is how you authenticate in the first place.)
There are two flavours of API key — workspace-level (bound to one specific workspace) and organization-level (which resolves to the organization’s default workspace). For most integrations a workspace-level key is the right choice. See 01-authentication.md for how to create one.
3. How an integration is shaped (the request lifecycle)
Section titled “3. How an integration is shaped (the request lifecycle)”Almost every Madoo integration follows the same five-step shape. The whole guide is organised around it.
┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 1. Get a │ │ 2. Discover │ │ 3. Submit an │ │ 4. Poll until│ │ 5. Read the │ │ token │──▶│ the │──▶│ execution │──▶│ it is │──▶│ outputs │ │ │ │ workflow │ │ (inputs) │ │ finished │ │ │ └─────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ auth/token GET workflows/{id} POST executions GET executions/{id} (status loop)- Authenticate — exchange your
client_id+client_secretfor a short-lived bearer token. → 01-authentication.md - Discover the workflow — read its interface to learn the exact input keys, their types, and which are required. → 03-workflows.md
- Submit an execution — POST the inputs. You get back an execution ID immediately (the work runs in the background). → 04-executions.md
- Wait for completion — poll the execution, or configure an outbound completion webhook for a push notification. → 04-executions.md, 11-webhooks.md
- Read the outputs — download URLs, inline text/JSON, and image thumbnails. → 04-executions.md
If your inputs include files (images, video…), there is a half-step between 2 and 3: upload the file first to get a storage path, then reference that path in your inputs. → 05-assets.md
The 02-quickstart.md runs through all five steps end-to-end with working copy-paste examples. If you like to learn by doing, start there and come back here for the concepts.
4. The most important concept: the workflow interface
Section titled “4. The most important concept: the workflow interface”This is the idea that makes Madoo integrable in a parametric way, so it deserves its own section even in the overview. (The full treatment, with examples, is in 03-workflows.md.)
A workflow does not accept arbitrary data. It declares what it accepts and what it produces, through special input nodes and output nodes placed on its canvas by the author. Together, those declarations form the workflow’s interface — the contract between your code and the workflow.
When you call GET /api/v1/workflows/{id}, the response contains an interface object describing
exactly:
- which inputs the workflow expects — each with a
name(the key you use), atype(text,image,number…), whether it isrequired, and an optionaldefault_value; - which outputs the workflow produces — each with a
nameand atype.
{ "id": "wf_53fb2f6576fa4bc9a6d3c91a7e84de47", "name": "Newsletter Hero", "interface": { "inputs": [ { "name": "block_title", "type": "text", "label": "Block Title", "required": true }, { "name": "product_image_0", "type": "image", "label": "Product Image 0", "required": true }, { "name": "product_image_1", "type": "image", "label": "Product Image 1", "required": false } ], "outputs": [ { "name": "hero_image", "type": "image", "label": "Hero Image" }, { "name": "copy_json", "type": "text", "label": "Copy JSON" } ] }}The golden rule that follows from this:
Never hard-code input keys. Always read
GET /api/v1/workflows/{id}first and use thenamevalues it returns. A workflow’s interface is the source of truth; it can change between versions, and guessing keys is the #1 cause of broken integrations.
On top of the auto-generated default interface, a workflow author can also publish one or more
custom interfaces — curated, named subsets of inputs/outputs (with friendlier field keys,
constraints, and defaults) tailored to a specific use case. You select one at execution time by its
id. Custom interfaces are fully explained in 03-workflows.md.
5. Environments
Section titled “5. Environments”Madoo runs in several environments. They are completely isolated — credentials, workflows, executions, and uploaded assets in one environment do not exist in another. An API key you create in Testing only works against Testing.
Pick the environment you are integrating against and use its base URL everywhere. Every endpoint
in this guide is written as a path (e.g. POST /api/v1/executions); prepend the base URL of your
environment to form the full URL.
| Environment | Base URL | Notes |
|---|---|---|
| Development | https://localhost:5001 |
Local machine only. Uses a self-signed TLS certificate — pass -k to curl / disable cert validation in your HTTP client. |
| Testing | https://testing-api.madoo.ai |
Shared, stable test deployment. The right place to build and validate your integration. |
| Pre-prod | https://preprod-api.madoo.ai |
Production-like staging for final verification. |
| Production | https://api.madoo.ai |
Live environment. Real credits are consumed. |
Full URL example (creating an execution in Testing):
https://testing-api.madoo.ai/api/v1/executions└──────────── base URL ─────┘└──── endpoint path ────┘Throughout the rest of this guide we use a BASE_URL placeholder in examples. Set it once:
BASE_URL="https://testing-api.madoo.ai" # change to match your environmentInteractive docs & OpenAPI spec
Section titled “Interactive docs & OpenAPI spec”Each environment also serves a live, browsable API reference and a machine-readable spec:
- Interactive docs (Scalar UI):
{BASE_URL}/docs - OpenAPI/Swagger JSON:
{BASE_URL}/swagger/public-v1/swagger.json
The OpenAPI document (group public-v1) is generated directly from the code, so it is always an
exact, up-to-date description of the request/response shapes. This guide is the narrative layer on
top of it: use the guide to understand concepts and flows, and the OpenAPI spec to generate clients
or check the precise schema of any field.
6. Conventions used across the whole API
Section titled “6. Conventions used across the whole API”These rules apply to every endpoint. Knowing them up front means you will not be surprised later. The exhaustive reference (status codes, error code catalogue, rate-limit details) is in 08-reference.md.
Resource IDs are prefixed strings
Section titled “Resource IDs are prefixed strings”Madoo exposes resource IDs as prefixed, opaque strings (Stripe-style), not raw numbers. The prefix tells you the resource type at a glance:
| Prefix | Resource | Example |
|---|---|---|
wf_ |
Workflow | wf_53fb2f6576fa4bc9a6d3c91a7e84de47 |
run_ |
Execution (a “run”) | run_b4c8d3e29f5a4b6c8d1e2f3a4b5c6d7e |
bat_ |
Batch execution | bat_9a1c… |
emb_ |
Embed token | emb_7f2e… |
Treat them as opaque: pass back whatever the API gave you. (Under the hood they are a prefix plus a GUID in compact hex form, but you should not need to parse them.)
Authentication header
Section titled “Authentication header”Every endpoint except the token endpoint requires a bearer token:
Authorization: Bearer <access_token>JSON, snake_case, ISO 8601
Section titled “JSON, snake_case, ISO 8601”Request and response bodies are JSON. Field names are snake_case (e.g. created_at,
asset_path). Timestamps are ISO 8601 / RFC 3339 strings in UTC (e.g.
2026-05-27T14:32:10.123+00:00).
Pagination (cursor-based)
Section titled “Pagination (cursor-based)”List endpoints return a consistent envelope and page with a cursor, not an offset:
{ "data": [ /* … items … */ ], "has_more": true, "next_cursor": "wf_…", // pass this as ?starting_after= to get the next page "total_count": 137}limit— items per page (1–100, default 25).starting_after— pass the previous page’snext_cursorto fetch the next page.- Stop when
has_moreisfalse.
Errors (RFC 7807 Problem Details)
Section titled “Errors (RFC 7807 Problem Details)”Every error response uses the same JSON shape, the RFC 7807 “Problem Details” format:
{ "type": "https://docs.madoo.ai/public-api/errors/workflow-not-found", "title": "Not Found", "status": 404, "detail": "Workflow wf_… not found.", "code": "workflow_not_found", // machine-readable — branch on this "instance": "/api/v1/executions", "request_id": "0HMÉ…" // quote this when contacting support}Branch your error handling on the code field (stable, machine-readable), not on detail
(human prose, may change). The full status-code and error-code catalogue is in
08-reference.md.
Rate limiting
Section titled “Rate limiting”API calls are rate-limited per organization/plan (a sliding window; the fallback is 60 requests per
minute). The token endpoint is limited more strictly. Responses carry an X-RateLimit-Limit header,
and exceeding the limit returns HTTP 429 with a Problem Details body (code: too_many_requests).
Build a short backoff-and-retry into your client. Details and exact limits: 08-reference.md.
7. Document map
Section titled “7. Document map”Read in order for a guided path, or jump straight to what you need.
| Document | What it covers |
|---|---|
| 01-authentication.md | The two auth modes: API key / client-credentials (create a key, obtain the bearer token) and the OAuth connector flow (Authorization Code + PKCE, zero-paste) for pre-registered app connectors. |
| 02-quickstart.md | A complete, copy-paste, end-to-end run: token → discovery → upload → execute → poll → outputs. curl and JavaScript/TypeScript. |
| 03-workflows.md | Listing workflows, reading the interface in depth, required/optional inputs, defaults, custom interfaces, and version pinning. |
| 04-executions.md | Submitting executions (the value vs asset_path rule, JSON double-encoding), polling, reading outputs (URLs, thumbnails, the GUID-suffix gotcha), cancelling, ZIP export. |
| 05-assets.md | Uploading files, structured-data inspection, and composing/validating portable multi-asset bundle manifests. |
| 06-advanced-batch.md | (Advanced) Running the same workflow over many input sets at once. |
| 07-advanced-embed.md | (Advanced) External embeds: workflow runtime widget, embedded workflow editor, embed tokens, iframe URLs, and postMessage contracts. |
| 08-reference.md | The reference appendix: HTTP status codes, error-code catalogue, rate-limit specifics, ID prefixes, status enums, plan & storage endpoints, machine discovery (/.well-known/api-catalog, agent-skills index). |
| 09-catalog.md | Catalog discovery: node types, the models behind each node (with the effective per-workspace default and credit costs), presets and effects. |
| 10-authoring.md | Workflow authoring: the public definition schema 1.0, creating/updating/validating workflows headlessly, definition export/import, metadata and deletion, lifecycle (publish/archive/revert/clone), versions, credit estimate, ETag/If-Match concurrency and Idempotency-Key retries. |
| 11-design-templates.md | DD7 DesignDocument discovery and authoring: portable IDs, immutable revisions, semantic commands, PDF/JPEG rendering, REST v1 and MCP parity. |
| 11-webhooks.md | Reliable completion notifications: endpoint setup, show-once signing secret, signature verification, tests, activation, logs, retry and replay. |
For the complete cross-surface explanation of bundles—including the visual editor, REST v1, MCP, Madoo AI Agent, and the in-editor AI Assistant—see the canonical Bundle manifest authoring guide.
| 12-mcp-server.md | The MCP server: connecting Claude, Claude Code, ChatGPT, Codex, Cursor, VS Code, Lovable and other AI clients (OAuth, zero setup) or automation (API key), what the assistant can do, scopes and troubleshooting. |
Section titled “| 12-mcp-server.md | The MCP server: connecting Claude, Claude Code, ChatGPT, Codex, Cursor, VS Code, Lovable and other AI clients (OAuth, zero setup) or automation (API key), what the assistant can do, scopes and troubleshooting. |”8. The shortest possible example
Section titled “8. The shortest possible example”To make the shape concrete, here is the entire lifecycle in eight lines of shell. (Each step is explained properly in the linked documents — this is just to show you the silhouette.)
BASE_URL="https://testing-api.madoo.ai"WF="wf_53fb2f6576fa4bc9a6d3c91a7e84de47"
# 1. Token (HTTP Basic with your client_id:client_secret)TOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \ -d "grant_type=client_credentials" "$BASE_URL/api/v1/auth/token" | jq -r .access_token)
# 2. Discover the interface (what inputs does it want?)curl -s -H "Authorization: Bearer $TOKEN" "$BASE_URL/api/v1/workflows/$WF" | jq .interface
# 3. Submit an executionRUN=$(curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d "{\"workflow\":\"$WF\",\"inputs\":{\"block_title\":{\"value\":\"\\\"Spring in Bloom\\\"\"}}}" \ "$BASE_URL/api/v1/executions" | jq -r .id)
# 4. Poll until terminal, then 5. read outputscurl -s -H "Authorization: Bearer $TOKEN" "$BASE_URL/api/v1/executions/$RUN" | jq '.status, .outputs'Notice the
\"\\\"Spring in Bloom\\\"\"in step 3 — text input values are JSON-encoded strings, so the literalSpring in Bloomis sent as the JSON string"Spring in Bloom". This “double encoding” trips up almost everyone the first time; it is explained carefully in 04-executions.md.
Ready? Head to 01-authentication.md to get your first token.