> ## Documentation Index
> Fetch the complete documentation index at: https://developers.apob.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Uploads and Live tools

> Prepare local or remote media and use the MCP Live room, scene, and voting tools.

## Local file upload

`prepare_file_upload` prepares a direct file transfer. File bytes stay in the
client's HTTP PUT; the MCP tool does not read local paths or accept file bytes.
No AWS credentials are needed.

<Steps>
  <Step title="Compute size, MIME type, and checksum">
    Measure the exact byte count and hexadecimal SHA-256 of the complete local
    file. Files must be from 1 through 209715200 bytes (200 MiB).
  </Step>

  <Step title="Prepare the transfer">
    Call `prepare_file_upload` with `fileSize`, `mimeType`, and `sha256`.
    Save the returned `uploadId`, `uploadUrl`, `headers`, and `expiresAt`.
  </Step>

  <Step title="PUT the file">
    Within five minutes, use a local HTTP client to PUT the original bytes to
    `uploadUrl`, sending every returned header exactly. The URL signs the
    declared size, type, checksum, and overwrite protection.
  </Step>

  <Step title="Verify completion">
    Call `complete_file_upload` with the saved `uploadId` using the same account
    and MCP endpoint. Use its canonical `url` in subsequent tool inputs.
  </Step>
</Steps>

### prepare\_file\_upload

All three inputs are required:

| Input | Contract |
| - | - |
| `fileSize` | Exact integer byte count, `1–209715200`. |
| `mimeType` | MIME type without parameters, `3–127` characters; for example `image/png`. |
| `sha256` | Exactly 64 hexadecimal characters. |

Returns `uploadId` (UUID), `uploadUrl`, `headers` (string-to-string map),
`expiresAt` (ISO 8601). Each successful preparation creates a new ticket; save
it instead of preparing another upload for the same successful operation.

This illustrative request uses synthetic size/checksum values. Replace them
with values calculated from the exact file before calling:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 20,
  "method": "tools/call",
  "params": {
    "name": "prepare_file_upload",
    "arguments": {
      "fileSize": 12345,
      "mimeType": "image/png",
      "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    }
  }
}
```

### complete\_file\_upload

Required: `uploadId`, a canonical UUID issued during preparation. Completion
checks ownership, the ticket deadline, and the stored object's actual byte count,
MIME type, and SHA-256 checksum.

Returns `url`, `previewUrl`, `mimeType`, `fileSize`. The canonical `url` is the
generation source; `previewUrl` is a temporary viewing URL.

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 21,
  "method": "tools/call",
  "params": {
    "name": "complete_file_upload",
    "arguments": { "uploadId": "11111111-2222-4333-8444-555555555555" }
  }
}
```

Replace the synthetic ID with the returned `uploadId`. Completion is safe to
retry with that same ID for one hour after preparation, including after a PUT
timeout, a repeated PUT returning HTTP `412`, or expiry of the five-minute PUT
URL. Completion still requires an existing matching object; expiry of the PUT
URL does not imply that an unfinished upload can be transferred again.

## Remote import

### import\_file

Required: `url`, a direct publicly accessible HTTP(S) download URL, nonblank and
at most 8192 characters. Use a DNS hostname and the standard HTTP(S) port.
Query parameters are supported. The source must return HTTP `200` directly
without compressed HTTP content encoding; redirects, authentication, private
network destinations, and IP-literal hosts are not supported.

The file must be from 1 byte through 200 MiB. Returns `url`, `previewUrl`, `mimeType`, `fileSize`,
in the same public shape as upload completion. Each successful import creates
a new file. Save and reuse the returned canonical `url`.

Preparation and import share a quota of 60 upload attempts per account per hour.
The upload/import result does not establish that the file is valid for a
particular generation route; that route still validates type and metadata.

Pass uploaded sources as objects containing only the canonical URL:

```json theme={null}
{
  "uploadedImage": { "url": "<CANONICAL_URL_FROM_IMPORT_OR_COMPLETION>" }
}
```

Treat upload and preview URLs as private credentials; do not publish them.

## Live tools

Live tools share the account, visibility, lifecycle, moderation, and credit rules
of the Live service. Their writes are non-idempotent. Uploaded Live inputs use
the same owned canonical URLs as generation.

### create\_live\_room

| Input | Required | Contract |
| - | - | - |
| `initialPrompt` | Yes | Nonblank initial scene prompt. |
| `initialLength` | Yes | Integer milliseconds, `15000–15000000`; rounds upward to a whole second. |
| `resolution` | Yes | `P480` or `P768`. |
| `isPublic` | Yes | Boolean; choose visibility explicitly. |
| `audienceSceneCreationEnabled` | No | Boolean; defaults to `true`. |
| Source | No | At most one `sourceMediaId`, `sourceLiveRoomId`, `uploadedImage`, or `uploadedVideo`. Omit for text-only generation. |

Source media/rooms must be accessible to the account. Uploaded image/video
objects contain only `url` from your own import or completed upload.

Returns `id`, `title`, `status` (`LIVE` or `ENDED`), `initialPrompt`,
`initialLength`, `resolution`, `isPublic`, `audienceSceneCreationEnabled`, and
nullable `cloudflareHlsPlaybackUrl`.

<Warning>
  Room creation prepays initial generation with APOB credits. Startup is
  asynchronous: a `LIVE` response or room receipt does not prove that playback
  has begun. A repeated creation can create and charge for another room.
</Warning>

### create\_live\_scene

Required: nonblank `roomId`, nonblank `prompt`, integer `creditAmount`
(`0–2147483647`). The room must be accessible and live; audience requests
must also be permitted by its audience-creation policy.

`creditAmount: 0` creates a candidate with **no initial vote**. Positive amounts
charge credits. An owner request funding more than 15 seconds can create a batch
of 5–15 second scenes, at most 1000, and returns its first scene.

Returns `id`, `roomId`, `prompt`, `votedCreditAmount`, and `useFreeVote`.
`votedCreditAmount` is vote weight, not a total of charged credits.

### vote\_live\_scene

Required: nonblank `roomId`, nonblank `sceneId`, integer `creditAmount`
(`0–2147483647`). The scene must belong to the specified accessible room and
remain eligible for voting.

`creditAmount: 0` uses the account's one free vote per scene and adds 100 vote
weight. A positive amount charges that many eligible credits and adds the same
vote weight. Each paid call can charge again.

Returns `voteId`, `scene` (the scene fields above), `creditAmount` (credits
charged for that vote), and boolean `refunded`. `scene.useFreeVote` indicates
whether the caller has already used the free vote.

On an uncertain Live response, check room/scene state before deciding on another
write. Access denial, ended rooms, disabled audience creation, moderation,
insufficient eligible credits, already-used free votes, and conflicts remain
errors; a tool receipt is not a playback/completion proof.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.