Upload Image to Post
upload_assetUploads an image sent as base64, for an image with no public URL (for example one pasted, generated or edited in a conversation). The format is detected from the bytes (JPEG/PNG/GIF/WebP). Accepts up to 10MB; anything over 3MB is downscaled on the server (longest edge 2048px, EXIF orientation applied, EXIF/GPS metadata stripped). Stored as JPEG or PNG: a GIF or WebP is converted (first frame only). post_id is optional: with it, the image is stored and attached in one call; without it, the call returns a standalone asset { asset_id, url, bytes, width, height, format, resized } that can be attached to any number of posts later (unattached assets expire after 30 days). One call carries about 2.5MB of image. A larger image goes in sequential chunks of about 2MB: chunk 0 as { image_base64, chunk_index: 0, total_chunks: N } returns upload_session_id, chunks 1…N-1 carry it, and the final chunk returns the result (sessions expire after 24 hours; at most 3 open at once). dry_run=true validates without storing. A post holds one media format at a time (single image, carousel or video): replace=true swaps an existing carousel or video for this image. Published posts cannot be changed. Errors carry error.data = { code, recovery, ... } with codes IMAGE_TOO_LARGE (limit_bytes, received_bytes), UNSUPPORTED_FORMAT (detected_magic_bytes, supported_formats), INVALID_BASE64, POST_NOT_FOUND, POST_ALREADY_PUBLISHED, UPLOAD_SESSION_INVALID; recovery says how to fix the call. Attaching media to an approved (ready or scheduled) post returns it to draft, and it needs approval again before it can publish. When a post is attached (post_id), the response carries status_before, status_after and approval_required; a standalone upload has none.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"image_base64": "<image_base64>"
},
"name": "upload_asset"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | When true, the call validates base64, format and size without storing (single call or final chunk). | |
| post_id | No | Optional. The post to attach the image to in the same call. Without it, the image is stored as a standalone asset that can be attached later. | |
| replace | No | When true, the call discards any existing carousel or video on the post and attaches this image instead. | |
| alt_text | No | Optional accessibility text. | |
| chunk_index | No | Chunked uploads only: 0-based index of this chunk; chunks are accepted in order from 0. | |
| image_base64 | Yes | The image bytes (or this chunk's bytes), base64-encoded. A data-URI prefix (data:image/png;base64,) is accepted and stripped. Format is detected from the bytes (JPEG/PNG/GIF/WebP). | |
| total_chunks | No | Chunked uploads only: total chunks (2–8), the same on every chunk. | |
| upload_session_id | No | Chunked uploads only: the session id chunk 0 returned; required on later chunks. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | ||
| asset | No | ||
| dry_run | No | ||
| post_id | No | ||
| resized | No | ||
| asset_id | No | ||
| image_url | No | ||
| mime_type | No | ||
| size_bytes | No | ||
| chunk_index | No | ||
| status_after | No | ||
| total_chunks | No | ||
| dashboard_url | No | ||
| status_before | No | ||
| approval_reset | No | ||
| approval_required | No | ||
| upload_session_id | No |