Publish a web app

October 12, 2026

Table of contents

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

Publish a web app the agent built on a public link. Anyone with the link can open the app, signed in to Muse or not. The app opens inside Muse’s own page. Find web apps with GET /assets ?type=web, or in a chat’s web-app widget (kind space_build_completed).

Muse reviews the app before it goes out, which takes about 15 seconds, and can refuse it: the 422 response says why, with the issues it found in errorDetails. Publishing again republishes the current version of the app, under the same link. The link shows as shareUrl in GET /assets. Stop sharing with DELETE /assets/assetId/share.

https://api.useapi.net/v1/muse/assets/assetId/share

  • assetId is the URL-encoded assetId of a web app, an asset of type web.
Request Headers
Authorization: Bearer {API token}
Responses
  • 200 OK

    {
      "assetId": "user:12345-email:6578616d706c6540676d61696c2e636f6d-web:space~hello-demo",
      "shareUrl": "https://muse.ai/s/hello-demo-k3v9q2m7xw4pzrt"
    }
    
  • 400 Bad Request — the path value is not a Muse assetId, or the asset is not a web app.

    {
      "error": "Only web apps (assets of type web) can be shared",
      "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 web app is not there (deleted), or the account that holds it is not added.

    {
      "error": "Asset not found",
      "code": 404
    }
    
  • 422 Unprocessable Content — Muse reviewed the app and refused to publish it. errorDetails lists the issues it found. Ask the agent to fix them, then publish again. When Muse asks for an extra confirmation instead, publish the app once from the muse.ai app.

    {
      "error": "Muse refused to publish this app: …",
      "errorDetails": "Issues found:\n- …",
      "code": 422
    }
    
  • 502 Bad Gateway — Muse did not publish the app. Retry shortly.

    {
      "error": "Muse did not publish the app (HTTP 500: …), 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
    }
    
  • 504 Gateway Timeout — Muse did not answer in time. The app may still be publishing: check shareUrl in GET /assets ?type=web shortly.

    {
      "error": "Muse did not answer (…); the app may still be publishing: check shareUrl in GET /assets?type=web shortly",
      "code": 504
    }
    
  • 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
{ // TypeScript, all fields are optional
  assetId: string
  shareUrl: string | null   // the public link, null after stopping sharing
  error?: string    // errors only
  code?: number     // errors only
}
Examples
  • ASSETID="user:12345-email:6578616d706c6540676d61696c2e636f6d-web:space~hello-demo"
    curl -X POST -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")/share"
    
  • const token = "API token";
    const assetId = "assetId of a web app from GET /assets?type=web";
    const apiUrl = `https://api.useapi.net/v1/muse/assets/${encodeURIComponent(assetId)}/share`;
    const response = await fetch(apiUrl, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${token}`,
      },
    });
    console.log("response", response.status, await response.json());
    
  • import requests
    from urllib.parse import quote
    token = "API token"
    assetId = "assetId of a web app from GET /assets?type=web"
    apiUrl = "https://api.useapi.net/v1/muse/assets/" + quote(assetId, safe="") + "/share"
    headers = {
        "Authorization" : f"Bearer {token}"
    }
    response = requests.post(apiUrl, headers=headers)
    print(response, response.json())
    
Try It