Retrieve a job

October 12, 2026

Table of contents

  1. Request Headers
  2. Query Parameters
  3. Responses
  4. Model
  5. Examples
  6. Try It

Fetch a job record by its jobid. POST /jobs/image and POST /jobs/video both return one. After an async request, poll this endpoint until status is completed or failed.

An image takes 20 to 60 seconds and a video 60 to 140, so polling every 10 seconds is enough. Our side follows each job for up to 10 minutes. If a job is still running well past its usual time, reading it also checks the job’s Muse chat again, so a finished result is not lost. A job that has no result 15 minutes after it was created is failed with 504.

Instead of polling, pass replyUrl (and optionally replyRef) with the POST: when the job completes or fails, the API sends one POST of this same job record, as JSON, to that URL. See Model.

Job records are kept for 7 days. After that the job answers 410.

https://api.useapi.net/v1/muse/jobs/jobid?history=history

  • jobid is URL-encoded in the path (it contains : and @), for example j1012014112831908109v-u12345-email%3Aexample%40gmail.com-task%3A3e8bc834-f243-4172-8f6e-9fc28e1a107c-bot%3Amuse.
Request Headers
Authorization: Bearer {API token}
Query Parameters
  • history is optional, true to add history: the job’s turn read live from its Muse chat (your message, the agent’s replies and the files it showed), for troubleshooting. It opens a connection to Muse, so it is slower than a plain poll. Use it to see what the agent said, or, after a 504, whether it made the file after all. Links into the Muse workspace and token-like fields are left out. The shape of history is Muse’s own and can change. When the chat cannot be read, historyError says why.
    Default: false.
Responses
  • 200 OK

    Completed (an old portrait, restored by an earlier job, brought to life):

    {
      "jobid": "j1012014112831908109v-u12345-email:[email protected]:3e8bc834-f243-4172-8f6e-9fc28e1a107c-bot:muse",
      "type": "video",
      "email": "[email protected]",
      "status": "completed",
      "created": "2026-10-12T01:41:12.831Z",
      "request": {
        "prompt": "Animate image_1 into a video with the same portrait frame: the young woman slowly lifts her eyes to the camera, her smile widens, she gently touches the rose on her shoulder and says softly: \"It has been a hundred years... and you still remember me.\" A light breeze moves a few strands of her hair, soft window light, the camera stays still with a very slow push-in. Keep her face exactly as in image_1.",
        "image_1": "user:12345-email:6578616d706c6540676d61696c2e636f6d-image:media-generation-restored-portrait-0-69c7e16d-eb86-4932-b940-8d688f2b95dc.webp",
        "async": true
      },
      "chatId": "3e8bc834-f243-4172-8f6e-9fc28e1a107c",
      "messageId": "1df531ad-e133-4725-b706-986ab4d19714",
      "updated": "2026-10-12T01:42:21.321Z",
      "completed": "2026-10-12T01:42:21.321Z",
      "result": {
        "assets": [
          {
            "assetId": "user:12345-email:6578616d706c6540676d61696c2e636f6d-video:media-generation-restored-portrait-animation-0-4322afa2-10d0-47b0-acc6-675a129aa78e.mp4",
            "type": "video",
            "mime": "video/mp4",
            "bytes": 3753558
          }
        ],
        "text": "Here it is."
      }
    }
    

    Running:

    {
      "jobid": "j1012014112831908109v-u12345-email:[email protected]:3e8bc834-f243-4172-8f6e-9fc28e1a107c-bot:muse",
      "type": "video",
      "email": "[email protected]",
      "status": "started",
      "created": "2026-10-12T01:41:12.831Z",
      "request": {
        "prompt": "Animate image_1 into a video with the same portrait frame: …",
        "image_1": "user:12345-email:6578616d706c6540676d61696c2e636f6d-image:media-generation-restored-portrait-0-69c7e16d-eb86-4932-b940-8d688f2b95dc.webp",
        "async": true
      },
      "chatId": "3e8bc834-f243-4172-8f6e-9fc28e1a107c"
    }
    

    Failed (Muse could not make the video this time and said why, so it can simply run again):

    {
      "jobid": "j1012014437650921837v-u12345-email:[email protected]:3c0c6fd6-a99f-4d7f-bfd5-91e6af964242-bot:muse",
      "type": "video",
      "email": "[email protected]",
      "status": "failed",
      "created": "2026-10-12T01:44:37.650Z",
      "request": {
        "prompt": "Animate image_1 into a cinematic video in exactly 16:9 aspect ratio (landscape): she rides the vintage motorcycle along the shoreline, the front wheel slices through the shallow waves and sends spray flying, …",
        "image_1": "user:12345-email:6578616d706c6540676d61696c2e636f6d-image:media-generation-beach-shoreline-motorcycle-rid-0-99c2e513-813a-4707-9f5b-f7e68780b072.webp",
        "async": true
      },
      "chatId": "3c0c6fd6-a99f-4d7f-bfd5-91e6af964242",
      "messageId": "f8ac44d6-9b29-455a-8fb7-df4a20c2b82a",
      "updated": "2026-10-12T01:45:14.352Z",
      "completed": "2026-10-12T01:45:14.352Z",
      "error": {
        "code": 503,
        "message": "Muse failed to make it this time, nothing was made: I tried to kick off your shoreline ride video and the video worker glitched out before it rendered anything, so no clip was made. I can't retry it in this same go.\n\nSay the word and I'll run it again from image_1 in 16:9.. Please retry"
      }
    }
    

    With ?history=true, the same record plus history, abridged here (an image job):

    {
      "jobid": "j1012011314385546947i-u12345-email:[email protected]:43d100f9-1dff-4b00-a223-453b45b8d3e3-bot:muse",
      "status": "completed",
      "…": "…",
      "history": [
        {
          "event_name": "message.user",
          "role": "user",
          "display_text": "Create one image: a young woman in a red summer dress on a beach at golden hour, full body, vertical 9:16 photo\n\nMake it directly. Do not ask me questions, do not upscale, crop or edit the result afterwards.",
          "…": "…"
        },
        { "event_name": "message.assistant", "role": "assistant", "display_text": "Done.", "…": "…" },
        { "event_name": "delta.presentation", "role": "assistant", "display_text": "Red summer dress at golden hour", "…": "…" }
      ]
    }
    

    The first event shows the message the API sent: your prompt after Create one image: (or Create one video:), with the line that asks Muse to make the file directly. With inputs, a list naming each input’s file in the workspace comes first.

  • 400 Bad Request

    The path value is not a Muse jobid, or a query parameter is not supported.

    {
      "error": "Path parameter jobid (…) is not a valid Muse job id",
      "code": 400
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "useapi.net ⁝ Unauthorized",
      "code": 401
    }
    
  • 403 Forbidden

    {
      "error": "This job does not belong to this API token",
      "code": 403
    }
    
  • 404 Not Found

    No such job.

    {
      "error": "Job not found",
      "code": 404
    }
    
  • 410 Gone

    The job is older than 7 days: job records are kept for 7 days.

    {
      "error": "Job has expired",
      "code": 410
    }
    
Model

The job record. POST /jobs/image and POST /jobs/video return it too, and it is the body of the replyUrl webhook.

{ // TypeScript, all fields are optional
  jobid: string                  // j<nonce><i|v>-u<id>-email:<email>-task:<chat id>-bot:muse
  type: 'image' | 'video'
  email: string                  // the Muse account the job runs on
  status: 'started' | 'completed' | 'failed'
  created: string                // ISO 8601, when the job was accepted
  updated?: string               // ISO 8601, the last change
  completed?: string             // ISO 8601, when the job completed or failed
  request: Record<string, unknown>   // your request body as sent
  chatId: string                 // the Muse chat this job created (also inside the jobid)
  messageId?: string             // Muse's id of the job's message in that chat, once it was sent
  replyUrl?: string
  replyRef?: string
  error?: {                      // status 'failed'
    code: number                 // see the error codes on GET /jobs/{jobid}
    message: string              // when Muse refused, its own words
  }
  result?: {                     // status 'completed'
    assets: {                    // the generated files, usually one
      assetId: string            // download it with GET /assets/{assetId}, or pass it as image_N / video_N of the next job
      type: 'image' | 'video' | 'audio'
      mime: string               // e.g. image/webp, video/mp4
      bytes: number
    }[]
    text: string | null          // the agent's last message, e.g. "Here's your image."
  }
  history?: unknown[]            // GET /jobs/{jobid}?history=true only: the job's chat turn as Muse sent it
  historyError?: string          // GET /jobs/{jobid}?history=true only: why the chat could not be read
}
status Meaning
started Muse is working on it. Every job starts here.
completed Done. Each file in result.assets[] downloads with GET /assets/assetId and can be the input of the next job.
failed Done without a file. error says why.

Error codes

error.code Meaning
403 Muse refused to make it, for example on content grounds, and message has the agent’s own words. Running the same prompt again will not help: change the prompt or the inputs. 403 is also the answer when Muse asked for a confirmation instead of making the file.
404 The account was removed with DELETE /accounts/email before the job’s result could be read.
412 The account’s weekly Muse allowance is used up. message says when it resets. See GET /accounts/email.
429 Muse is limiting requests on the account right now and nothing was made. Retry in about a minute.
500 An unexpected error on our side.
502 Muse made a file the API cannot return (an unusual file name), or did not accept the message. A made file is in the job’s chat (GET /jobs/jobid?history=true), and running the job again uses the allowance again. Report the jobid to support.
503 Nothing was made. Either the job never reached Muse (Muse could not be reached, the job could not be started, or it was interrupted before it was sent), or Muse failed to make it this time and said so, for example the video worker glitched out before it rendered anything. Run it again: in our tests the same prompt then worked. When Muse ends its answer with a promise such as Back in a minute, the job keeps waiting up to 5 more minutes for the file before it fails.
504 Muse did not finish in time (a job is followed for up to 10 minutes and failed 15 minutes after it started), or the connection to Muse dropped after the job was sent. The job may still have completed in the account’s Muse chat: check GET /jobs/jobid?history=true before running it again.
596 The account needs attention: Meta asks for a security check, or Muse refused to sign it in again. See Setup Muse.

A sync POST whose job fails answers with the HTTP status in error.code and the failed job record as the body.

The replyUrl webhook is one POST with Content-Type: application/json and this record as the body, sent once when the job completes or fails (a 10-second timeout, no retries, redirects are not followed). Use replyRef to match the callback to your own records.

Examples
  • JOBID="j1012014112831908109v-u12345-email:[email protected]:3e8bc834-f243-4172-8f6e-9fc28e1a107c-bot:muse"
    curl -H "Authorization: Bearer …" \
         "https://api.useapi.net/v1/muse/jobs/$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$JOBID")"
    
  • const token = "API token";
    const jobid = "j1012014112831908109v-u12345-email:[email protected]:3e8bc834-f243-4172-8f6e-9fc28e1a107c-bot:muse";
    const apiUrl = `https://api.useapi.net/v1/muse/jobs/${encodeURIComponent(jobid)}`;
    let job;
    do {
      await new Promise(resolve => setTimeout(resolve, 10000));
      const response = await fetch(apiUrl, {
        headers: {
          "Authorization": `Bearer ${token}`,
        },
      });
      job = await response.json();
      console.log(job.status);
    } while (job.status === "started");
    console.log("job", job);
    
  • import requests, time, urllib.parse
    token = "API token"
    jobid = "j1012014112831908109v-u12345-email:[email protected]:3e8bc834-f243-4172-8f6e-9fc28e1a107c-bot:muse"
    apiUrl = "https://api.useapi.net/v1/muse/jobs/" + urllib.parse.quote(jobid, safe="")
    headers = {
        "Authorization" : f"Bearer {token}"
    }
    while True:
        time.sleep(10)
        job = requests.get(apiUrl, headers=headers).json()
        print(job.get("status"))
        if job.get("status") != "started":
            break
    print(job)
    
Try It