Create a file upload
POST/asset.create
Create a file asset and get back a self-describing instruction for
uploading its bytes — the JSON-friendly way to attach a file (image, PDF,
document, …) to a message, or to supply media for a story. Unlike
/item.upload, which takes raw bytes in the
request body, every caller-visible step here is JSON in / JSON out (so it
can be driven from MCP and other tool-calling clients), and the file bytes
never pass through this API.
Flow:
POST /asset.createwith the filename(include the extension, e.g.photo.png) and, if known, itssizein bytes. For stories, also passpurpose: "story". The response is an upload instruction:assetId,uploadUrl,uploadMethod, anduploadHeaders.- Upload the raw bytes in a single request: use
uploadMethod(aPOST) againstuploadUrl, send every header fromuploadHeadersverbatim, and put the file in the request body. Send the headers exactly as given — they authorize the upload and select the single-request upload protocol; omitting any will cause the upload to fail. - Processing (thumbnails, previews, …) happens automatically once the bytes land. There is no separate "complete" call.
- Once the asset is ready, use it:
purpose: "file"(default) — attach viaassetIdson/chat.postor/chat.updatepurpose: "story"— post via/story.post
A freshly-uploaded asset may take a few seconds to process (videos take longer). Endpoints that consume the asset return a 400 with a "still processing" message until processing completes.
The uploadUrl is short-lived; if it expires, call asset.create again for
a fresh instruction. Maximum file size is 5 GiB.
Purposes
| Purpose | Use | Access |
|---|---|---|
file (default) | Chat message attachments | Organization and Personal |
story | Story media (photo or video) | Personal only |
Story assets are owned by the authenticated user (stories are posted as you,
not as a bot) and expire about 48 hours after creation. Because the media
must outlive the story's 24-hour lifetime, call
/story.post within about 23 hours of creating the
asset; after that the asset is rejected and a new one must be created.
Access: Organization and Personal. purpose: "story" is Personal only.
Required scope: item:write for purpose: "file"; chat:send_message
or chat:write for purpose: "story".
OpenAPI Spec: chat-v1.json
Request
Responses
- 200
- 400
- 401
- 403
- 405
- 500
Upload instruction created.
Bad request. Common causes:
namemissing or too longsizenegative or larger than 5 GiBpurpose: "story"used with an organization token- Malformed JSON body
Presented invalid authentication credentials.
The token lacks the required scope (item:write for file assets;
chat:send_message / chat:write for story assets).
An unsupported method was requested.
An internal error occurred.