← Playground

MESU generation API

Local beta. Create a key in Developer API. Keys expire after 90 days, are stored as hashes, and default to read-only. Enable generation explicitly to submit paid tasks. Never put a key in a public webpage or URL.

Download OpenAPI 3.1 schema · 每个 API key 支持累计积分上限;预留计入用量,确认释放/退款恢复额度。

Protocol

MethodPathPurpose
GET/api/mesu/v1/modelsModel capability definitions
POST/api/mesu/v1/jobsSubmit a paid generation
GET/api/mesu/v1/jobs?kind=image&cursor=…Owned task history; nextCursor is opaque
GET/api/mesu/v1/jobs/{id}Task, measured metadata, related generations
GET/api/mesu/v1/jobs/{id}/mediaAuthenticated original media; supports Range

All requests use Authorization: Bearer MESU_API_KEY. Maximum 60 requests/minute/key. Each key has a lifetime MESU credit limit: reservations and completed charges count, confirmed releases/refunds restore allowance. HTTP 402 can indicate either wallet balance or key quota. Read-only keys cannot submit tasks or access account/worker routes. Provider credentials are never returned.

Request structure

{
  "requestKey": "UUID retained for this submission",
  "kind": "image | video",
  "model": "exact ID from GET models",
  "prompt": "Your description",
  "ratio": "1:1",
  "resolution": "1k",
  "duration": 4,
  "count": 1,
  "mode": "text",
  "references": [{"id":"owned asset ID","role":"reference_image"}]
}

count: 1, 2 or 4. Model-specific modes, ratios, duration, resolution and reference limits come from the shared model catalog. Only use references owned by your account. Seedance 2.5 final uses draftJobId; edit/extend require source_video. See the Playground for allowed combinations. An accepted response contains job and batchId; batch children appear in history.

Retain requestKey before submitting. Reuse it to recover the same request after a network failure; a new key means a new purchase. A batch runs serially. queued/running/submitted are active; completed/failed/cancelled are terminal; uncertain requires reconciliation and must not be blindly resubmitted.

cURL

# Set MESU_API_KEY in your local environment. This POST costs credits.
curl "$MESU_BASE/api/mesu/v1/jobs" \
  -H "Authorization: Bearer $MESU_API_KEY" \
  -H 'Content-Type: application/json' \
  --data @request.json

JavaScript

// Server-side Node. Persist requestKey before calling.
const response = await fetch(`${process.env.MESU_BASE}/api/mesu/v1/jobs`, {
  method: 'POST',
  headers: {Authorization: `Bearer ${process.env.MESU_API_KEY}`,
            'Content-Type': 'application/json'},
  body: JSON.stringify({requestKey, kind:'image', model:'gpt-image-2.5-flare',
    prompt:'A silver paper bird', ratio:'1:1', resolution:'1k', count:1})
});
const data = await response.json();
if (!response.ok) throw Error(data.error);
// Poll GET /jobs/{data.job.id}; do not repeat a paid POST with a new key.

Python

import os, requests
response = requests.post(os.environ['MESU_BASE'] + '/api/mesu/v1/jobs',
    headers={'Authorization': 'Bearer ' + os.environ['MESU_API_KEY']},
    json={'requestKey': request_key, 'kind': 'image',
          'model': 'gpt-image-2.5-flare', 'prompt': 'A silver paper bird',
          'ratio': '1:1', 'resolution': '1k', 'count': 1}, timeout=30)
response.raise_for_status()
job = response.json()['job']

Errors and credits

400 invalid parameters, 401 missing/expired/revoked key, 403 scope or cross-origin rejection, 402 insufficient MESU credits, 409 conflicting active task/dependency, 429 rate limited, 503 unavailable engine/storage. MESU credits are reserved atomically for all children, captured on completion, and released on confirmed failure/cancellation. Uncertain tasks retain the hold. Provider USD charges are separate; estimates are not final bills.

Signed webhooks

Register up to three public HTTPS endpoints. Save the signing secret once. Headers: X-Mesu-Signature: t=UNIX_SECONDS,v1=HEX_DIGEST. The digest is HMAC-SHA256(secret, timestamp + "." + raw_body). Verify using constant-time comparison, reject timestamps older than 5 minutes and deduplicate payload.id. Delivery is at least once, with up to five attempts. A response in the 200–299 range acknowledges delivery. Redirects and private-network destinations are rejected.

{"id":"event UUID","type":"generation.completed","created_at":0,
 "data":{"id":"job UUID","kind":"image","model":"model ID","status":"completed"}}

Event types: generation.completed, generation.failed, generation.uncertain. No account details, reference media, provider secrets or billing are sent in the event.