apimk API

API reference

Use a key to list models, quote, upload references, and create jobs from your own app. Each key only sees the models you allowed. Generating, checking the wallet, and uploading files need a signed-in session or a key.

1. Base URL

https://apimk.com

Prefix: /api/v1. JSON over HTTPS unless noted. Uploads use multipart/form-data.

ItemValue
AuthAuthorization: Bearer hxsk_...
Quote TTL5 minutes, single use
Upload TTL24 hours
Prompt1–5000 characters

2. Authentication

Create keys on the keys page. The full key is shown once, starts with hxsk_, and is about 37 characters — it is not truncated.

Authorization: Bearer hxsk_...

The keys page shows product labels, not API ids. Send the id from GET /api/v1/models. Age confirmation is required before uploads or jobs.

3. Resources

ObjectMeaning
ModelCallable model. Use id in params.model.
SKUPrice tier. Video by resolution, image by quality, chat by context.
QuotePriced offer bound to SKU, prompt, and params.
JobOne generation. Balance is held, then settled or refunded.
UploadReference file. Returns upload_id for params.
WalletAvailable and frozen USD.

4. Request and response

{ "error": { "code": "invalid_sku", "message": "Invalid SKU: video.std" } }

Job creation returns 202. Treat only 2xx bodies as success.

5. Operations

MethodPathPurpose
GET/api/v1/modelsList models and tiers for this key
POST/api/v1/quotesQuote SKU + prompt + params
POST/api/v1/jobsCreate a job with that quote
GET/api/v1/jobs/:idPoll one job
GET/api/v1/jobs?job_id=Search history, max 20
GET/api/v1/jobs/:id/mediaFetch output; ?thumb=1 for poster
POST/api/v1/uploadsUpload a reference
GET/api/v1/walletBalance and holds
POST/v1/videosCompat: one-shot video job, server quotes
GET/v1/videos/:idCompat: poll; succeeded url is official TOS

6. Models and SKUs

Send the id from GET /api/v1/models, not the keys-page label. SKU must match resolution: 480p → video.fast, 720p → video.std, 1080p → video.pro.

FamilyidKeys-page label
Seedance 2 Minidoubao-seedanceSeedance 2 Mini
Seedance 2.0 Fastdoubao-seedance20fastSeedance 2.0 Fast
Seedance 2.0doubao-seedance20Seedance 2.0
Seedance 2.5doubao-seedance25Seedance 2.5
Dreamina 2.0 / 2.5dreamina-seedance-2-0 / dreamina-seedance-2-5dreamina-seedance-2-0 / 2-5
Seedance 1.5 Proseedance15proSeedance 1.5 Pro
Grok videogrok-imagine-video / grok-imagine-video-1.5Grok Imagine Video / 1.5
Grok imagegrok-imagine-image / grok-imagine-image-2.0 / grok-imagine-image-qualityGrok Imagine Image
GPT Imagegpt-image-2 / gpt-image-2.5-flare / gpt-image-2.5-sunburstGPT Image 2 / 2.5 Flare / 2.5 Sunburst
Grok chatgrok-4.5 / grok-4.6Grok 4.5 / 4.6

Do not send seedance20, Seedance 2.0, GPT Image 2.5 Sunburst, or any keys-page label. Those are not catalog ids. Always copy id from GET /api/v1/models.

7. params

Quote and submit the same params object. Unknown fields return unsupported_field.

FieldUse
model, mode, ratio, resolution, durationCore generation settings
first_frame_upload_idFirst frame / Grok i2v still
reference_image_upload_ids / reference_image_urlsExtra stills
reference_video_upload_idRequired for v2v
generate_audio, watermark, clean_outputSeedance output flags
layer_countSeedream layer mode, 1–17

Seedance reference stills stay text-to-video. Grok video with a still is image-to-video. i2v needs a first frame or reference image; v2v needs a reference clip.

8. Endpoints

Quote then submit

curl https://apimk.com/api/v1/quotes \
  -H "Authorization: Bearer hxsk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "sku": "video.std",
    "prompt": "slow push down a rainy alley, neon reflections",
    "params": {
      "model": "doubao-seedance25",
      "mode": "t2v",
      "resolution": "720p",
      "ratio": "16:9",
      "duration": 5
    }
  }'
curl https://apimk.com/api/v1/jobs \
  -H "Authorization: Bearer hxsk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "PASTE_QUOTE_ID",
    "sku": "video.std",
    "prompt": "slow push down a rainy alley, neon reflections",
    "params": {
      "model": "doubao-seedance25",
      "mode": "t2v",
      "resolution": "720p",
      "ratio": "16:9",
      "duration": 5
    }
  }'

Upload and image-to-video

curl https://apimk.com/api/v1/uploads \
  -H "Authorization: Bearer hxsk_..." \
  -F slot=first \
  -F [email protected]
{
  "sku": "video.std",
  "prompt": "the subject walks toward camera, outfit unchanged",
  "params": {
    "model": "grok-imagine-video-1.5",
    "mode": "i2v",
    "resolution": "720p",
    "ratio": "9:16",
    "duration": 5,
    "first_frame_upload_id": "UPLOAD_ID"
  }
}

Poll and download

curl https://apimk.com/api/v1/jobs/JOB_ID \
  -H "Authorization: Bearer hxsk_..."
curl "https://apimk.com/api/v1/jobs/JOB_ID/media?thumb=1" \
  -H "Authorization: Bearer hxsk_..." \
          -o thumb.webp

9. Compat video API

For integrators that cannot quote then submit. Path is /v1/videos, not /api/v1. Same Authorization: Bearer hxsk_.... The server fills SKU from resolution, quotes, and holds the balance. Use section 8 for the full API.

MethodPathPurpose
POST/v1/videosCreate a video job
GET/v1/videos/:idPoll status and result
curl https://apimk.com/v1/videos \
  -H "Authorization: Bearer hxsk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance25",
    "prompt": "slow push down a rainy alley, neon reflections",
    "duration": 10,
    "resolution": "720p",
    "ratio": "16:9",
    "referenceImages": ["https://example.com/img.jpg"],
    "referenceVideos": ["https://example.com/ref.mp4"],
    "referenceAudios": ["https://example.com/ref.mp3"]
  }'
{
  "id": "2f50c75e-...",
  "status": "queued",
  "created_at": 1730000000,
  "quoted_price_usd": 0.45
}
FieldRequiredNotes
modelyesid from GET /api/v1/models, e.g. doubao-seedance25. Do not send Seedance 2.5 or seedance25
promptyes1–5000 characters
durationyesInteger seconds
resolutionyes480p / 720p / 1080p → video.fast / std / pro
ratioyes21:9 / 16:9 / 4:3 / 1:1 / 3:4 / 9:16
referenceImagesnoPublic HTTPS image URLs
referenceVideosnoPublic HTTPS video URL, max 1
referenceAudiosnoPublic HTTPS audio URL, max 1

status is queued / processing / succeeded / failed. Create returns both id and job_id. On success both url and result.url are the upstream HTTPS result URL, passed through as-is. It expires and may hit an upstream warning page. The same request retried within about 2 minutes returns the same id.

Insufficient balance returns 400 and creates no job. Seedance 1.x and some models reject reference URLs. Unknown fields are ignored. Local files still need /api/v1/uploads.

10. Integration flow

  1. Create a key and allow the models you need.
  2. List models, then upload references if required.
  3. Quote, then submit the same prompt, SKU, and params.
  4. Poll until succeeded, failed, or rejected.
  5. Download result.url. Use ?thumb=1 for posters.

11. Integration notes

IssueDo this
Key looks truncatedA hxsk_ key of about 37 characters is complete
Keys page shows Seedance 2.0That is the label. Send the id from GET /api/v1/models: doubao-seedance20 / doubao-seedance25
Sending seedance20 or Seedance 2.0Those are not catalog ids. No spaces or dots
Calling Ark or OpenAI pathsThe full API is quote then jobs. Use POST /v1/videos if you cannot change client code
Compat success urlUpstream HTTPS result URL, passed through as-is. It expires and may hit a warning page
Studio preview fails / download warning pageHistory thumbs are local; canvas TOS links can be blocked. Download promptly

12. Error codes

HTTPcodeMeaning
400quote_mismatch / missing_reference / invalid_skuFix params or requote
401 / 403unauthorized / model_not_allowed / age_confirmation_requiredAuth or model access
429queue_full / rate_limitedBackoff; no extra hold
503generation_unavailableTry later; nothing reserved

Moderation rejects are not billed. If submit times out, the hold stays — poll the job instead of resubmitting the same quote.