Skip to main content

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:

  1. POST /asset.create with the file name (include the extension, e.g. photo.png) and, if known, its size in bytes. For stories, also pass purpose: "story". The response is an upload instruction: assetId, uploadUrl, uploadMethod, and uploadHeaders.
  2. Upload the raw bytes in a single request: use uploadMethod (a POST) against uploadUrl, send every header from uploadHeaders verbatim, 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.
  3. Processing (thumbnails, previews, …) happens automatically once the bytes land. There is no separate "complete" call.
  4. Once the asset is ready, use it:

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

PurposeUseAccess
file (default)Chat message attachmentsOrganization and Personal
storyStory 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

Upload instruction created.