Current API Specs

Integration reference for the current MaYi's MaaS public API. The page covers authentication, capability grants, request contracts, response shapes, async job polling, and error formats.

Production: https://maas.flyingant.win

AI Agent Quickstart

  1. Get an admin-provided API key

    API key must come from a MaaS admin. Ask for a maas_test_ or maas_live_ key with the capability permissions required by the endpoint you will call.

  2. Choose the base URL

    External agents should use the Production base URL: https://maas.flyingant.win.

  3. Send the bearer header

    Every protected /api/v1 route requires Authorization: Bearer <api-key>. JSON routes also require Content-Type: application/json.

  4. Smoke-test authentication first

    Call GET /api/v1/health/auth-check before capability calls. A successful response confirms the key, consumer, capability, and permission wiring.

  5. Call the capability endpoint

    Use the endpoint cards or OpenAPI JSON for the exact request fields. Match your key permissions to the capability key listed for that endpoint.

  6. Poll async jobs when returned

    Image, video, and audio create routes return a jobId instead of final output. Send Idempotency-Key on the create request. Poll GET /api/v1/jobs/{jobId} with the same bearer key until the job reaches a terminal status.

First Authenticated Call

curl -i https://maas.flyingant.win/api/v1/health/auth-check \
  -H "Authorization: Bearer <api-key>"

JSON Route Pattern

curl -i https://maas.flyingant.win/api/v1/<capability-route> \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{...}'

Capability Matrix

Capability Key

health.auth-check

Checks that API key, consumer, capability, and permission wiring are valid.

GET /api/v1/health/auth-check

Capability Key

file.upload

Uploads supported files to public Cloudflare R2 through the MaaS server.

POST /api/v1/files/upload

Capability Key

slack.notify

Posts manual API-triggered messages to a requested Slack channel.

POST /api/v1/slack/notify

Capability Key

chat

Runs controlled single-turn chat calls through MaaS LLM providers.

POST /api/v1/chat

Capability Key

responses.create

Runs controlled Responses API calls with MaaS-allowlisted tools.

POST /api/v1/responses

Capability Key

text.polish

Polishes submitted text through the MaaS text-polish provider path.

POST /api/v1/text/polish

Capability Key

information.extract

Extracts information from text and image URLs into Markdown.

POST /api/v1/information/extract

Capability Key

image.generate

Generates images through Doubao Ark or OpenAI image providers.

POST /api/v1/images/generate

Capability Key

video.generate

Creates async Seedance video generation jobs.

POST /api/v1/videos/generate

Capability Key

audio.transcribe

Creates async Doubao ASR transcription jobs.

POST /api/v1/audio/transcriptions

API Index

Common Error Response

Protected route failures use a stable JSON error envelope with a trace id. The HTTP status depends on the error code; examples include 401 for missing or invalid API keys, 403 for denied permissions, 429 for quota failures, 502 for upstream provider failures, and 504 for provider timeouts.

{
  "error": {
    "code": "PERMISSION_DENIED",
    "message": "API key does not have permission for this capability."
  },
  "traceId": "9f4d8f4c-7f57-4f4e-a684-7a99a8b4f2a0"
}

Endpoints

GET
/api/health

Basic deployment health check.

Auth

None

Content Type

application/json

Capability

None

Success Response

{
  "ok": true
}

Notes

  • Use this for deployment liveness only. It does not verify Payload or database connectivity.
GET
/api/health/db

Payload and database readiness check.

Auth

None

Content Type

application/json

Capability

None

Success Response

{
  "database": "ready",
  "ok": true
}

Relevant Error Codes

503 database unavailable

Notes

  • This route loads Payload and runs a minimal admin-users query.
  • A failed database check returns status 503 with ok: false.
GET
/api/v1/health/auth-check

Verify protected API authentication and permission wiring.

Auth

Bearer API key plus enabled health.auth-check permission

Content Type

application/json

Capability

health.auth-check

Required Headers

Authorization: Bearer <maas_test_or_live_key>

Success Response

{
  "capabilityKey": "health.auth-check",
  "consumerId": 12,
  "ok": true,
  "traceId": "9f4d8f4c-7f57-4f4e-a684-7a99a8b4f2a0"
}

Relevant Error Codes

MISSING_API_KEYINVALID_API_KEYDISABLED_API_KEYCONSUMER_DISABLEDPERMISSION_DENIED

Notes

  • Use this as the first integration smoke test after creating a consumer, credential, capability, and permission grant.
  • The response includes the resolved consumer id and trace id for support.
POST
/api/v1/files/upload

Upload a public integration file to R2.

Auth

Bearer API key plus enabled file.upload permission

Content Type

multipart/form-data

Capability

file.upload

Required Headers

Authorization: Bearer <maas_test_or_live_key>

Request Fields

file

File

Required
Multipart file. Supported images, audio, video, text, PDF, JSON, CSV, XLS, XLSX, and DOCX content types are accepted.
prefix

string

Optional

Default: uploads

Optional storage prefix. Sanitized and nested under maas/.

Request Example

curl -i https://maas.flyingant.win/api/v1/files/upload \
  -H "Authorization: Bearer <api-key>" \
  -F "file=@./sample.pdf;type=application/pdf" \
  -F "prefix=documents/contracts"

Success Response

{
  "success": true,
  "url": "https://cdn.example.test/maas/documents/contracts/2026-05-20T10-00-00-000Z-a1b2c3d4e5f6.pdf"
}

Relevant Error Codes

FILE_REQUIREDFILE_TOO_LARGEUNSUPPORTED_FILE_TYPESTORAGE_NOT_CONFIGUREDSTORAGE_UPLOAD_FAILEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • The file part is required and must use one of the supported content types.
  • Maximum upload size is 4,194,304 bytes.
  • prefix is optional. It is normalized under the maas/ root, so reports/raw becomes maas/reports/raw.
  • Successful uploads return a public R2 URL. File bytes are not stored in Payload.
POST
/api/v1/slack/notify

Post a manual Slack notification.

Auth

Bearer API key plus enabled slack.notify permission

Content Type

application/json

Capability

slack.notify

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json

Request Fields

channel

string

Required
Slack channel id to post to. For private channels, the bot must be a member.
text

string

Required
Message text to post to Slack.

Request Example

{
  "channel": "C0123456789",
  "text": "Deployment finished successfully."
}

Success Response

{
  "success": true,
  "channel": "C0123456789",
  "messageTs": "1779456000.000100"
}

Relevant Error Codes

TEXT_REQUIREDSLACK_CHANNEL_REQUIREDSLACK_BOT_TOKEN_NOT_CONFIGUREDSLACK_POST_FAILEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • The endpoint posts through the configured Slack bot token.
  • The channel field should be a Slack channel id, such as C0123456789.
  • Successful calls record invocation metadata with the channel id and Slack message timestamp, not the message text.
POST
/api/v1/chat

Run a controlled single-turn chat request.

Auth

Bearer API key plus enabled chat permission

Content Type

application/json

Capability

chat

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json

Request Fields

messages

array

Required
Array with exactly one user message and at most one optional system message.
provider

doubao | openai | xai

Optional

Default: openai from code

Optional provider override. Accepted values: doubao, openai, xai.
temperature

number

Optional

Default: 0.7

Optional number from 0 to 2.
maxTokens

number

Optional

Default: provider-managed limit

Optional integer from 1 to 1000000. When omitted, MaaS uses the provider-managed limit.
reasoningEffort

none | low | medium | high | xhigh | max

Optional
Optional provider-specific reasoning effort. OpenAI accepts none, low, medium, high, xhigh, and max and defaults to medium. xAI accepts low, medium, and high and MaaS defaults xAI requests to low. Doubao rejects this field.

Request Example

{
  "messages": [
    {
      "role": "system",
      "content": "Answer in concise Chinese."
    },
    {
      "role": "user",
      "content": "Explain MaaS usage accounting."
    }
  ],
  "provider": "openai",
  "temperature": 0.7,
  "reasoningEffort": "high"
}

Success Response

{
  "success": true,
  "result": {
    "model": "gpt-5.6-sol",
    "provider": "openai",
    "text": "MaaS usage accounting works by..."
  },
  "usage": {
    "inputTokens": 123,
    "outputTokens": 80,
    "totalTokens": 203
  }
}

Relevant Error Codes

INVALID_JSON_BODYMESSAGES_REQUIREDINVALID_CHAT_MESSAGETOO_MANY_MESSAGESINVALID_CHAT_PARAMETERTEXT_TOO_LARGEINVALID_LLM_PROVIDERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTLLM_PROVIDER_UNSUPPORTEDINVALID_MODEL_OUTPUTUSAGE_QUOTA_EXCEEDEDSPEND_BUDGET_EXCEEDEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • messages must contain exactly one user message and at most one system message.
  • Caller system instructions are scoped below the MaaS platform policy.
  • provider is optional. When omitted, the server uses the code default openai provider.
  • OpenAI accepts reasoningEffort values none, low, medium, high, xhigh, and max; when omitted, OpenAI defaults to medium.
  • xAI accepts reasoningEffort values low, medium, and high; when omitted, MaaS defaults xAI requests to low.
  • Doubao rejects requests that include reasoningEffort.
  • Callers cannot submit assistant history, arbitrary model ids, base URLs, credentials, tool calls, or raw provider payload fields.
  • Successful calls record invocation and usage-ledger rows. Validation and provider failures are not billable usage rows.
POST
/api/v1/responses

Run a Responses request with allowlisted tools.

Auth

Bearer API key plus enabled responses.create permission

Content Type

application/json

Capability

responses.create

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json

Request Fields

input

string

Required
Required user input sent to the selected Responses provider. Trimmed server side. Maximum 48,000 characters.
inputFiles

Array<{ fileId: string } | { fileUrl: string }>

Optional

Default: []

Optional file inputs. Up to 5 items; each item must provide exactly one of fileId or HTTPS fileUrl. Raw provider file_id, file_url, file_data, and base64 file payloads are rejected.
instructions

string

Optional
Optional caller-scoped instructions appended below the MaaS platform policy. Maximum 48,000 characters.
tools

Array<"web_search">

Optional

Default: []

Optional MaaS tool allowlist. Currently accepts only ["web_search"]. Raw provider tool objects are rejected.
provider

doubao | openai

Optional

Default: openai from code

Optional provider override. Accepted values: doubao, openai.
toolChoice

auto | required

Optional
Optional tool-selection mode when tools is non-empty. Accepted values: auto or required.
includeSources

boolean

Optional

Default: true when web_search is enabled

When true with web_search, MaaS requests provider source details where supported and returns normalized sources.
maxOutputTokens

number

Optional

Default: provider default

Optional integer from 1 to 1000000 forwarded as max_output_tokens. When omitted, MaaS omits max_output_tokens.
reasoningEffort

none | low | medium | high | xhigh | max

Optional

Default: provider default

Optional OpenAI-only reasoning effort. Accepted values: none, low, medium, high, xhigh, max.
thinkingType

auto | disabled | enabled

Optional

Default: provider default

Optional Doubao-only thinking mode. Accepted values: auto, disabled, enabled.

Request Example

{
  "input": "Find today's market-moving China tech news and cite sources.",
  "inputFiles": [
    {
      "fileUrl": "https://files.example.com/brief.pdf"
    }
  ],
  "instructions": "Use concise Slack-friendly bullets.",
  "tools": [
    "web_search"
  ],
  "toolChoice": "auto",
  "includeSources": true,
  "maxOutputTokens": 2000,
  "provider": "doubao"
}

Success Response

{
  "success": true,
  "result": {
    "id": "resp_123",
    "model": "gpt-5.6-sol",
    "provider": "openai",
    "text": "Market-moving China tech news...",
    "sources": [
      {
        "title": "Example News",
        "url": "https://example.com/news"
      }
    ]
  },
  "usage": {
    "inputTokens": 123,
    "outputTokens": 80,
    "totalTokens": 203
  }
}

Relevant Error Codes

INVALID_JSON_BODYTEXT_REQUIREDTEXT_TOO_LARGEINVALID_LLM_PROVIDERINVALID_RESPONSES_PARAMETERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTLLM_PROVIDER_UNSUPPORTEDINVALID_MODEL_OUTPUTUSAGE_QUOTA_EXCEEDEDSPEND_BUDGET_EXCEEDEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • This endpoint uses the provider Responses API, not Chat Completions. Supported providers are openai and doubao.
  • tools is a MaaS allowlist of string tool names. Currently only web_search is accepted.
  • inputFiles accepts MaaS-normalized provider file IDs or HTTPS file URLs. Raw provider file fields and base64 file data are rejected.
  • The endpoint does not accept raw provider tool definitions, provider payload passthrough, model ids, base URLs, or credentials.
  • MaaS sets store=false on provider requests and does not store input text, model output text, raw provider payloads, or raw provider responses in durable invocation metadata.
  • includeSources defaults to true when web_search is enabled. MaaS sends OpenAI source include parameters only to OpenAI, and normalizes URL citations/search sources returned by the selected provider.
  • reasoningEffort is optional and OpenAI-only. thinkingType is optional and Doubao-only. When omitted, MaaS leaves reasoning behavior to the selected provider.
POST
/api/v1/text/polish

Polish submitted text with the MaaS text-polish provider path.

Auth

Bearer API key plus enabled text.polish permission

Content Type

application/json

Capability

text.polish

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json

Request Fields

text

string

Required
Plain text to polish. Trimmed server side. Maximum 48,000 characters.
provider

doubao | openai | xai

Optional

Default: xai from code

Optional provider override. Accepted values: doubao, openai, xai.

Request Example

{
  "text": "please make this email better",
  "provider": "xai"
}

Success Response

{
  "success": true,
  "result": {
    "model": "grok-4.5",
    "provider": "xai",
    "text": "Please improve this email."
  },
  "usage": {
    "inputTokens": 123,
    "outputTokens": 80,
    "totalTokens": 203
  }
}

Relevant Error Codes

INVALID_JSON_BODYTEXT_REQUIREDTEXT_TOO_LARGEINVALID_LLM_PROVIDERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTLLM_PROVIDER_UNSUPPORTEDINVALID_MODEL_OUTPUTUSAGE_QUOTA_EXCEEDEDSPEND_BUDGET_EXCEEDEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • text is trimmed before processing and must be at most 48,000 characters.
  • provider is optional. When omitted, the server uses the code default xai provider.
  • Callers cannot submit arbitrary model ids, base URLs, credentials, or system prompts.
  • Successful calls record invocation and usage-ledger rows. Validation and provider failures are not billable usage rows.
POST
/api/v1/information/extract

Extract information from text and image URLs as Markdown.

Auth

Bearer API key plus enabled information.extract permission

Content Type

application/json

Capability

information.extract

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json

Request Fields

text

string

Optional
Optional source text. Required when imageUrls is omitted. Maximum 48,000 characters.
imageUrls

string[]

Optional
Optional HTTPS image URLs. Required when text is omitted. Maximum 10 URLs.
instructions

string

Optional
Optional caller guidance for extraction focus and Markdown structure.
context

string

Optional
Optional background for interpreting the source. Not treated as source evidence.
provider

doubao | openai

Optional

Default: openai from code

Optional provider override. Accepted values: doubao, openai.

Request Example

{
  "text": "Invoice #A-100 total $42",
  "imageUrls": [
    "https://cdn.example.test/invoice-page-1.png"
  ],
  "instructions": "Extract key invoice fields as a Markdown table.",
  "context": "The image is the authoritative source.",
  "provider": "openai"
}

Success Response

{
  "success": true,
  "result": {
    "model": "gpt-5.6-sol",
    "provider": "openai",
    "markdown": "## Summary\n\n...\n\n## Extracted Information\n\n..."
  },
  "usage": {
    "inputTokens": 123,
    "outputTokens": 80,
    "totalTokens": 203
  }
}

Relevant Error Codes

INVALID_JSON_BODYSOURCE_REQUIREDTEXT_TOO_LARGEINVALID_IMAGE_URLTOO_MANY_IMAGESINVALID_LLM_PROVIDERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTLLM_PROVIDER_UNSUPPORTEDINVALID_MODEL_OUTPUTUSAGE_QUOTA_EXCEEDEDSPEND_BUDGET_EXCEEDEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • At least one of text or imageUrls is required. Text and image URLs can be used together.
  • imageUrls must contain HTTPS URLs and accepts at most 10 URLs.
  • instructions can shape the Markdown output but cannot override platform accuracy rules.
  • provider is optional. When omitted, the server uses the code default openai provider.
  • Durable records do not store source text, image URLs, instructions, context, Markdown output, or raw provider payloads.
POST
/api/v1/images/generate

Start an async image generation job.

Auth

Bearer API key plus enabled image.generate permission

Content Type

application/json

Capability

image.generate

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json
Idempotency-Key: <8-128 printable characters>

Request Fields

prompt

string

Required
Image prompt. Maximum 32,000 characters for OpenAI and 8,000 characters for Doubao.
provider

doubao | openai

Optional

Default: openai from code

Optional provider override. Accepted values: doubao, openai.
model

string

Optional
Optional model id. It must be the configured image model for the selected provider.
size

string

Optional
Doubao accepts 2K, 3K, 4K, or provider-valid WIDTHxHEIGHT values; small/invalid pixel sizes normalize to 2048x2048. OpenAI accepts auto, standard sizes, and gpt-image-2 WIDTHxHEIGHT values with 655,360 to 8,294,400 pixels that satisfy the documented divisibility, edge, and aspect-ratio limits.
count

number

Optional
Rounded to an integer. Maximum 15 for Doubao, reduced by reference image count so references + outputs stay <= 15. Maximum 10 for OpenAI.
responseFormat

url | b64_json

Optional
Doubao only. Accepted values: url, b64_json.
image

string | string[]

Optional
Doubao only. One HTTPS or data:image base64 reference image, or an array of up to 14 references.
quality

low | medium | high

Optional
OpenAI only. Accepted values: auto, low, medium, high.
referenceImageUrls

string[]

Optional
OpenAI only. Up to 16 HTTPS or data:image base64 references. The server still downloads them before calling OpenAI to preserve the existing MaaS API behavior.
background

auto | opaque

Optional
OpenAI only. Accepted values: auto, opaque. gpt-image-2 does not support transparent backgrounds.
moderation

auto | low

Optional
OpenAI only. Accepted values: auto, low.
outputFormat

png | jpeg | webp

Optional
OpenAI accepts png, jpeg, webp. Doubao Seedream 5.0 accepts png or jpeg.
outputCompression

number

Optional
OpenAI only. Integer-like number from 0 to 100 for jpeg/webp output.
maskImageUrl

string

Optional
OpenAI edit requests only. HTTPS or data:image base64 mask image reference.
sequentialImageGeneration

auto | disabled

Optional
Doubao only. Accepted values: auto, disabled. If omitted and count is greater than 1, MaaS sends auto for compatibility with existing count callers.
sequentialImageGenerationOptions

{ maxImages?: number }

Optional
Doubao only. Supports maxImages from 1 to 15.
optimizePromptOptions

{ mode: "standard" }

Optional
Doubao only. The configured Seedream 5.0 Lite model supports { mode: "standard" }.
tools

Array<{ type: "web_search" }>

Optional
Doubao Seedream 5.0 only. Supports [{ type: "web_search" }].
watermark

boolean

Optional
Doubao only. Boolean.

Request Example

{
  "prompt": "a clean studio photo of a desk lamp",
  "provider": "openai",
  "size": "1536x864",
  "count": 1,
  "quality": "auto",
  "background": "auto"
}

Success Response

{
  "success": true,
  "job": {
    "jobId": "job_image123",
    "capabilityKey": "image.generate",
    "status": "queued"
  }
}

Relevant Error Codes

MISSING_IDEMPOTENCY_KEYINVALID_IDEMPOTENCY_KEYIDEMPOTENCY_CONFLICTINVALID_JSON_BODYIMAGE_PROMPT_REQUIREDIMAGE_PROMPT_TOO_LARGEINVALID_LLM_PROVIDERINVALID_IMAGE_PARAMETERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTLLM_PROVIDER_UNSUPPORTEDINVALID_MODEL_OUTPUTUSAGE_QUOTA_EXCEEDEDSPEND_BUDGET_EXCEEDEDWORKFLOW_START_FAILEDMISSING_API_KEYPERMISSION_DENIED

Notes

  • This is an async create route. It returns HTTP 202; poll the returned jobId with GET /api/v1/jobs/{jobId}.
  • Reusing the same Idempotency-Key with the same normalized request returns the existing job. Reusing it with a different request returns IDEMPOTENCY_CONFLICT.
  • prompt is trimmed. OpenAI allows up to 32,000 characters; Doubao keeps the MaaS safety cap of 8,000 characters.
  • provider is optional. When omitted, the server uses the code default openai provider. Accepted values are doubao and openai.
  • model is optional but must match the configured model for the resolved provider.
  • Omitted provider requests infer the provider from Doubao-only or OpenAI-only fields; otherwise they use the OpenAI default path.
  • Doubao accepts responseFormat, image, watermark, outputFormat, sequentialImageGeneration, sequentialImageGenerationOptions, optimizePromptOptions, and tools. The configured Seedream 5.0 Lite model rejects seed, guidanceScale, and fast prompt optimization.
  • OpenAI accepts quality, referenceImageUrls, background, moderation, outputFormat, outputCompression, and maskImageUrl. gpt-image-2 rejects transparent backgrounds and inputFidelity.
  • Provider image output is copied to Cloudflare R2 by a no-retry Workflow step. Polling reads saved job state and never calls the image provider.
POST
/api/v1/videos/generate

Create an async video generation job.

Auth

Bearer API key plus enabled video.generate permission

Content Type

application/json

Capability

video.generate

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json
Idempotency-Key: <8-128 printable characters>

Request Fields

prompt or text

string

Required
Required prompt string. Maximum 8,000 characters.
duration or dur

number

Required
Required duration. Accepted values: -1, or an integer from 4 to 15.
provider

doubao

Optional

Default: doubao

Optional. Only doubao is currently accepted.
model

string

Optional

Default: Seedance 2.0 Fast from code

Optional. Accepted values: doubao-seedance-2-0-260128, doubao-seedance-2-0-fast-260128.
resolution

480p | 720p

Optional

Default: 720p

Optional. Accepted values: 480p, 720p.
ratio

string

Optional
Optional provider ratio string, such as 16:9.
seed

number | string integer

Optional

Default: -1

Optional integer from -1 to 4294967295.
generateAudio

boolean

Optional

Default: true in provider body when omitted

Optional boolean.
imageItems

array

Optional
Optional explicit reference image objects. Max 9. Each item has url, role, and detail. role is first_frame, last_frame, or reference_image. detail is auto, low, or high.
imageUrls, imageUrl, extraImageUrls, referenceImageUrls

string | string[]

Optional
Optional compatibility aliases for HTTPS image URLs. The first image defaults to first_frame unless using referenceImageUrls.
videoItems, videoUrls, videoUrl

array | string[] | string

Optional
Optional HTTPS reference video inputs. Max 3. videoItems also accepts fps, startTime/start_time, and endTime/end_time.
audioItems, audioUrls, audioUrl

array | string[] | string

Optional
Optional HTTPS reference audio inputs. Max 3. Requires at least one reference image or reference video.
callbackUrl

string

Optional
Optional HTTPS callback URL passed to Ark.
imageBeforeText, returnLastFrame, watermark

boolean

Optional
Optional booleans.

Request Example

{
  "prompt": "A clean product video of a matte black desk lamp rotating on a white table.",
  "model": "doubao-seedance-2-0-fast-260128",
  "duration": 5,
  "resolution": "720p",
  "ratio": "16:9",
  "seed": -1,
  "watermark": false,
  "generateAudio": true,
  "imageUrls": [
    "https://cdn.example.test/lamp.png"
  ],
  "imageRole": "first_frame",
  "primaryImageDetail": "high",
  "returnLastFrame": true
}

Success Response

{
  "success": true,
  "job": {
    "capabilityKey": "video.generate",
    "createdAt": "2026-05-20T10:00:00.000Z",
    "jobId": "job_video123",
    "status": "submitted"
  }
}

Relevant Error Codes

MISSING_IDEMPOTENCY_KEYINVALID_IDEMPOTENCY_KEYIDEMPOTENCY_CONFLICTINVALID_JSON_BODYINVALID_VIDEO_REQUESTINVALID_LLM_PROVIDERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTLLM_PROVIDER_UNSUPPORTEDINVALID_MODEL_OUTPUTMISSING_API_KEYPERMISSION_DENIED

Notes

  • This is an async create route. Poll the returned jobId with GET /api/v1/jobs/{jobId}.
  • Reusing the same Idempotency-Key with the same normalized request returns the existing job. Reusing it with a different request returns IDEMPOTENCY_CONFLICT.
  • duration must be -1 or an integer from 4 to 15 seconds.
  • Only Seedance 2.0 and Seedance 2.0 Fast are supported. draft and draftTaskId are intentionally rejected.
  • Reference audio requires at least one reference image or reference video.
POST
/api/v1/audio/transcriptions

Create an async audio transcription job.

Auth

Bearer API key plus enabled audio.transcribe permission

Content Type

application/json

Capability

audio.transcribe

Required Headers

Authorization: Bearer <maas_test_or_live_key>
Content-Type: application/json
Idempotency-Key: <8-128 printable characters>

Request Fields

audioUrl

string

Required
Required HTTPS audio URL.
format

string

Required
Required provider audio format string, for example m4a, mp3, wav, or webm.
duration

number

Required
Required positive number in seconds.
provider

doubao

Optional
Optional. Only doubao is currently accepted.
codec

string

Optional
Optional codec hint.
language

string

Optional
Optional language hint.

Request Example

{
  "audioUrl": "https://cdn.example.test/audio/meeting.m4a",
  "format": "m4a",
  "codec": "aac",
  "duration": 31.4,
  "language": "zh-CN"
}

Success Response

{
  "success": true,
  "job": {
    "capabilityKey": "audio.transcribe",
    "createdAt": "2026-05-20T10:00:00.000Z",
    "jobId": "job_audio123",
    "status": "submitted"
  }
}

Relevant Error Codes

MISSING_IDEMPOTENCY_KEYINVALID_IDEMPOTENCY_KEYIDEMPOTENCY_CONFLICTINVALID_JSON_BODYINVALID_AUDIO_TRANSCRIPTION_REQUESTAUDIO_DURATION_REQUIREDINVALID_LLM_PROVIDERLLM_PROVIDER_NOT_CONFIGUREDLLM_PROVIDER_REQUEST_FAILEDLLM_PROVIDER_TIMEOUTMISSING_API_KEYPERMISSION_DENIED

Notes

  • This is an async create route. Poll the returned jobId with GET /api/v1/jobs/{jobId}.
  • audioUrl must be HTTPS.
  • duration is required in seconds and is rounded to at least one second for request metadata and fallback usage.
  • DOUBAO_ASR_API_KEY is preferred. If unset, the server falls back to DOUBAO_API_KEY.
GET
/api/v1/jobs/{jobId}

Poll an async image, video, or audio job.

Auth

Bearer API key; job must belong to the resolved consumer and caller must still have permission for the job capability

Content Type

application/json

Capability

None

Required Headers

Authorization: Bearer <maas_test_or_live_key>

Request Fields

jobId

string

Required
Path parameter returned by an async create route. Public ids start with job_.

Success Response

{
  "success": true,
  "job": {
    "capabilityKey": "video.generate",
    "finishedAt": "2026-05-20T10:02:00.000Z",
    "jobId": "job_video123",
    "result": {
      "providerVideoUrl": "https://provider.example.test/video.mp4",
      "videoKey": "maas/video-results/job_video123.mp4",
      "videoUrl": "https://cdn.example.test/maas/video-results/job_video123.mp4"
    },
    "status": "succeeded",
    "usage": {
      "quantity": 42,
      "source": "provider",
      "unit": "provider_unit"
    }
  }
}

Relevant Error Codes

JOB_NOT_FOUNDPERMISSION_DENIEDCONSUMER_DISABLEDJOB_PROVIDER_TASK_MISSINGJOB_PROVIDER_QUERY_FAILEDJOB_RESULT_PERSIST_FAILEDMISSING_API_KEYINVALID_API_KEYDISABLED_API_KEY

Notes

  • Unknown jobs and jobs owned by another consumer both return JOB_NOT_FOUND.
  • The route checks the saved job capability key, so image, video, and audio jobs still require their respective capability permission.
  • Image Workflow jobs always return saved database state. Non-terminal video and audio jobs refresh provider state.
  • Successful image and video jobs expose R2 references. Successful audio jobs return transcript text from the provider snapshot.
  • Usage is recorded once when a job reaches succeeded.

Admin-Only API

POST/api/api-credentials/generate

Authenticated Payload super-admin session only. Creates a new raw API key or rotates an existing credential.