Early access is openRequest access
Mowa

Developers

The REST reference.

Workspace-scoped JSON over HTTPS at https://mowa.dev/api/v1, authenticated with an API key from the dashboard developer page. Available on every plan, subject to the workspace's plan limits.

Prompts

GET/v1/prompts

List prompts

Every prompt in the key's workspace with version counts, the live version number, and the latest version's status.

Request
curl https://mowa.dev/api/v1/prompts \
  -H "x-api-key: $MOWA_API_KEY"
Response
{
  "prompts": [
    {
      "id": "p9f2...",
      "name": "Support triage",
      "description": "Routes tickets to queues",
      "source": "manual",
      "createdAt": "2026-06-02T09:14:00.000Z",
      "updatedAt": "2026-07-10T16:40:00.000Z",
      "liveVersion": 3,
      "latestVersion": 4,
      "latestStatus": "draft",
      "versionCount": 4
    }
  ]
}
POST/v1/prompts

Create a prompt

Creates the prompt with version 1 as a draft and enqueues AI interface analysis. Poll the returned analysisJobId on /v1/jobs/:jobId for suggested typed inputs and outputs. Returns 201.

Request body

Request body for POST /v1/prompts
FieldTypeNotes
namestringRequired, at least 1 character
contentstringRequired, the prompt template content
descriptionstringOptional
emojistringOptional, 1 to 16 characters
colorstringOptional, defaults to #0044ff
Request
curl -X POST https://mowa.dev/api/v1/prompts \
  -H "x-api-key: $MOWA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support triage",
    "content": "Classify the ticket: {{ticket}}",
    "description": "Routes tickets to queues"
  }'
Response
{
  "id": "p9f2...",
  "versionId": "v1a8...",
  "versionNumber": 1,
  "analysisJobId": "42"
}
GET/v1/prompts/:id

Get a prompt

One prompt with every version, including each version's content, status, notes, and typed input and output interface.

Request
curl https://mowa.dev/api/v1/prompts/p9f2... \
  -H "x-api-key: $MOWA_API_KEY"
Response
{
  "prompt": { "id": "p9f2...", "name": "Support triage", "liveVersionId": "v0d4..." },
  "versions": [
    {
      "id": "v1a8...",
      "versionNumber": 4,
      "content": "Classify the ticket: {{ticket}}",
      "status": "draft",
      "notes": null,
      "inputs": [{ "name": "ticket", "type": "string", "optional": false }],
      "outputs": [{ "name": "queue", "type": "string" }]
    }
  ]
}
POST/v1/prompts/:id/versions

Add a version

Adds a new draft version to an existing prompt. Returns 201.

Request body

Request body for POST /v1/prompts/:id/versions
FieldTypeNotes
contentstringRequired, the new version content
notesstringOptional change notes
Request
curl -X POST https://mowa.dev/api/v1/prompts/p9f2.../versions \
  -H "x-api-key: $MOWA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "New template...", "notes": "Tighter tone" }'
Response
{ "versionId": "v2c1...", "versionNumber": 5 }
POST/v1/versions/:versionId/publish

Publish a version

Publishes a version live and archives the previous live version. The key owner must be an owner or admin of the workspace, otherwise the request fails with 403.

Request
curl -X POST https://mowa.dev/api/v1/versions/v2c1.../publish \
  -H "x-api-key: $MOWA_API_KEY"
Response
{ "versionId": "v2c1...", "versionNumber": 5, "status": "live" }

Datasets

GET/v1/datasets

List datasets

Every dataset in the workspace with row counts.

Request
curl https://mowa.dev/api/v1/datasets \
  -H "x-api-key: $MOWA_API_KEY"
Response
{
  "datasets": [
    {
      "id": "d4k1...",
      "name": "Ticket fixtures",
      "description": null,
      "source": "prompt",
      "promptId": "p9f2...",
      "createdAt": "2026-06-05T11:02:00.000Z",
      "updatedAt": "2026-07-09T08:21:00.000Z",
      "rowCount": 84
    }
  ]
}
GET/v1/datasets/:id

Get a dataset

Typed columns plus a paginated slice of rows.

Query parameters

Query parameters for GET /v1/datasets/:id
FieldTypeNotes
limitinteger1 to 500, defaults to 100
offsetinteger0 or more, defaults to 0
Request
curl "https://mowa.dev/api/v1/datasets/d4k1...?limit=50&offset=0" \
  -H "x-api-key: $MOWA_API_KEY"
Response
{
  "dataset": { "id": "d4k1...", "name": "Ticket fixtures" },
  "columns": [{ "name": "ticket", "type": "string", "optional": false }],
  "rows": [{ "id": "r7m3...", "data": { "ticket": "My invoice is wrong" } }],
  "rowCount": 84,
  "limit": 50,
  "offset": 0
}
POST/v1/datasets/:id/rows

Add a row

Appends one row. Keys must match the dataset's column names, and required columns cannot be omitted. Unknown or missing columns fail with 400. Returns 201.

Request body

Request body for POST /v1/datasets/:id/rows
FieldTypeNotes
dataobjectRequired, row values keyed by column name
Request
curl -X POST https://mowa.dev/api/v1/datasets/d4k1.../rows \
  -H "x-api-key: $MOWA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "ticket": "My invoice is wrong" } }'
Response
{ "id": "r7m3..." }
POST/v1/datasets/:id/generate

Generate rows

Enqueues AI generation of synthetic rows and returns a job id to poll. Runs cap at 50 rows, and 12 rows per run when the dataset has image columns. Returns 202.

Request body

Request body for POST /v1/datasets/:id/generate
FieldTypeNotes
countintegerRequired, 1 to 50
guidancestringOptional, up to 500 characters of generator guidance
Request
curl -X POST https://mowa.dev/api/v1/datasets/d4k1.../generate \
  -H "x-api-key: $MOWA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "count": 25, "guidance": "Edge cases in German" }'
Response
{ "jobId": "43" }

Jobs

GET/v1/jobs/:jobId

Job status

Status for interface analysis and dataset generation jobs started by this workspace. The type is prompt_analyze or dataset_generate, the result is set once the state is completed, and the error is set when it failed.

Request
curl https://mowa.dev/api/v1/jobs/43 \
  -H "x-api-key: $MOWA_API_KEY"
Response
{
  "jobId": "43",
  "type": "dataset_generate",
  "state": "completed",
  "progress": null,
  "result": { "inserted": 25 },
  "error": null
}

Usage

GET/v1/usage

AI usage

30 day workspace AI usage: total calls, tokens, and images, plus a breakdown for the ten most used models.

Request
curl https://mowa.dev/api/v1/usage \
  -H "x-api-key: $MOWA_API_KEY"
Response
{
  "windowDays": 30,
  "totals": { "calls": 128, "inputTokens": 90210, "outputTokens": 51000, "images": 4 },
  "models": [
    {
      "model": "claude-sonnet-4-5",
      "provider": "anthropic",
      "calls": 96,
      "inputTokens": 71000,
      "outputTokens": 40200
    }
  ]
}

Notes

Errors and pagination

Every error uses the envelope { "error": { "code", "message" } } with status 400, 401, 402, 403, 404, 429, or 500. A 402 carries the code plan_limit plus a limit field naming the cap that was hit, see errors and limits. Keys are rate limited to 100 requests per minute and return 429 past that.

Pagination is offset based and currently applies to dataset rows only: pass limit and offset to GET /v1/datasets/:id and walk forward until the returned rows come up short of the limit. The response echoes both values next to the total rowCount. List endpoints for prompts and datasets return the full collection.