Download an asset

October 12, 2026 (October 14, 2026)

Table of contents

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

Download a Library item by its assetId: an image, video or audio file from a finished job’s result.assets[], a chat’s file event, an upload with POST /assets, or any item of the account’s Library in GET /assets. The response body is the file itself, streamed from the Muse workspace of the account that holds it on each request. No copy is kept at useapi.net.

What you get depends on the item’s type:

  • image, video, audio: the file.
  • document: the file as the agent wrote it, for example .md, .csv, .pdf or .pptx. With format=pdf, an md, txt or html document comes as a PDF that Muse makes, which takes about 10 seconds. A PDF downloads as it is.
  • web: the web app as one HTML file, with its scripts and styles inside, named after the app.
  • podcast: the episode as MP3. With part=cover, the episode’s cover image.

Items stay in the account’s Library until you delete them with DELETE /assets/assetId or in the muse.ai app. An item that is no longer there answers 404.

https://api.useapi.net/v1/muse/assets/assetId?part=part&format=format

  • assetId is URL-encoded in the path (it contains :), for example user%3A12345-email%3A6578616d706c6540676d61696c2e636f6d-image%3Ad62d3099…jpg.
Request Headers
Authorization: Bearer {API token}
Query Parameters
  • part is optional, for podcasts only.
    Supported values: cover (the episode’s cover image).
  • format is optional, for md, txt and html documents only.
    Supported values: pdf.
Response headers
  • Content-Type: the file’s type, for example image/webp for a generated image, video/mp4 for a video, text/markdown for a Markdown document or text/html for a web app.
  • Content-Disposition: the file name. Images (except SVG), videos and audio come inline, every other file as an attachment.
  • Content-Length: when Muse sends the size.
Responses
  • 200 OK

    The raw file bytes (not JSON), for example:

    Content-Type: video/mp4
    Content-Length: 3753558
    Content-Disposition: inline; filename="media-generation-restored-portrait-animation-0-4322afa2-10d0-47b0-acc6-675a129aa78e.mp4"
    
  • 400 Bad Request

    The path value is not a Muse assetId, or part or format does not fit the item.

    {
      "error": "Path parameter assetId (…) is not a valid Muse asset id (from GET /assets, POST /assets or a job result)",
      "code": 400
    }
    
    {
      "error": "format=pdf is for documents of type md, txt, html, htm, pdf (a pdf downloads as is)",
      "code": 400
    }
    
    {
      "error": "part=cover is for podcast assets only",
      "code": 400
    }
    
  • 401 Unauthorized

    Invalid API token.

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

    The assetId was issued to a different API token.

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

    The file is no longer in the account’s Muse workspace, or the account that holds it is not added.

    {
      "error": "This file is no longer in the Muse workspace of account [email protected]",
      "code": 404
    }
    
    {
      "error": "This podcast has no cover",
      "code": 404
    }
    
    {
      "error": "Account [email protected] (from the asset id) is not configured",
      "code": 404
    }
    
  • 422 Unprocessable Content

    Muse could not convert the document to PDF.

    {
      "error": "Muse could not convert this file (HTTP 400)",
      "code": 422
    }
    
  • 502 Bad Gateway

    Muse did not send the file. Retry shortly.

    {
      "error": "Muse did not send the file (…), please retry",
      "code": 502
    }
    
  • 503 Service Unavailable

    Muse could not be reached. Retry shortly.

    {
      "error": "Could not connect to the Muse workspace of account [email protected] (…), please retry shortly",
      "code": 503
    }
    
  • 596 Account Error

    The account needs your attention, and it is paused until you add it again. You receive an email when this happens. There are two causes.

    Meta asks for a security check on the account. Sign in once at muse.ai in a browser, complete the check, then add the account again with POST /accounts using the same email and password. The API keeps using its session, so no new sign-in is needed.

    {
      "error": "Account [email protected]: Meta asks for a security check on account [email protected] (\"This account must complete a security checkpoint on the web\"). Sign in once at https://muse.ai in a browser, complete the check, then add the account again with POST /accounts",
      "code": 596
    }
    

    Or Muse refused to sign the account in again when its session needed renewing, most often because the password was changed. Add the account again with the current password.

    {
      "error": "Account [email protected]: Muse refused to sign in account [email protected] (…). Update its password with POST /accounts, or sign in at https://muse.ai to clear the block, then re-add it",
      "code": 596
    }
    
Model

A successful response is the file itself (not JSON), with the headers listed above. Errors return:

{ // TypeScript, all fields are optional
  error: string
  code: number
}
Examples
  • ASSETID="user:12345-email:6578616d706c6540676d61696c2e636f6d-video:media-generation-restored-portrait-animation-0-4322afa2-10d0-47b0-acc6-675a129aa78e.mp4"
    curl -H "Authorization: Bearer …" \
         "https://api.useapi.net/v1/muse/assets/$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$ASSETID")" \
         --output video.mp4
    
  • const token = "API token";
    const assetId = "assetId from a finished job, POST /assets or GET /assets";
    const apiUrl = `https://api.useapi.net/v1/muse/assets/${encodeURIComponent(assetId)}`;
    const response = await fetch(apiUrl, {
      headers: {
        "Authorization": `Bearer ${token}`,
      },
    });
    if (!response.ok)
      console.log("error", response.status, await response.json());
    else {
      const file = await response.arrayBuffer();
      console.log("downloaded", file.byteLength, response.headers.get("content-type"));
    }
    
  • import requests
    from urllib.parse import quote
    token = "API token"
    assetId = "assetId from a finished job or POST /assets"
    apiUrl = "https://api.useapi.net/v1/muse/assets/" + quote(assetId, safe="")
    headers = {
        "Authorization" : f"Bearer {token}"
    }
    with requests.get(apiUrl, headers=headers, stream=True) as response:
        response.raise_for_status()
        with open("video.mp4", "wb") as f:
            for chunk in response.iter_content(chunk_size=1 << 20):
                f.write(chunk)
    
Try It

The form fetches the file with your token and shows the image or video inline.