Upload and retrieve raw binary content (images, audio, PDFs).
Blobs
Blobs are content-addressed binary objects. Reference them from an experience envelope via content.kind = "blob_ref" or as media[].blob_id inside a message.
Content negotiation
Blob endpoints use Content-Type to describe the request body (on upload) and the response body (on download). They do not look at Accept. Concretely:
- Upload (
POST /v1/blobs): send the bytes raw withContent-Type: <mime>. Do not wrap them in JSON / multipart / base64 — the body is the file. The server stores the declared MIME alongside the bytes. - Download (
GET /v1/blobs/{id}): the responseContent-Typeechoes whatever was declared at upload.Acceptheaders are ignored — there is no transcoding. If you uploadedimage/png, you always getimage/pngback.
POST /v1/blobs with a JSON-or-multipart body returns 415 unsupported_media_type.
POST /v1/blobs
Upload a blob.
POST /v1/blobs
Content-Type: image/png
Content-Length: 245892
<binary bytes>
Response
{
"blob_id": "blob_01HX...",
"size_bytes": 245892,
"content_type": "image/png",
"sha256": "..."
}
Blobs are content-deduplicated by SHA-256 — uploading the same bytes twice returns the same blob_id cheaply.
GET /v1/blobs/
Returns the raw bytes with the original Content-Type. Auth checked at the scope of the calling experience (a blob with no referencing experience is accessible only to the original uploader).
HTTP/1.1 200 OK
Content-Type: image/png
Content-Disposition: inline; filename="architecture-diagram.png"
Content-Length: 245892
<binary bytes>