Media
Endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
| POST | /media/presign | media:write | Get a presigned upload URL |
| POST | /media/confirm | media:write | Confirm a completed upload |
Upload Flow
Adding an image to a document is a 4-step process:
- Get a presigned URL - Call
/media/presignwith the file details. You receive a time-limited upload URL and amedia_id. - Upload the file -
PUTthe file binary directly to the presigned URL. This uploads to clarife's storage without proxying through the API. - Confirm the upload - Call
/media/confirmwith themedia_idto mark the file as active. - Link to document - Call
PATCH /documents/:idto add ascreenshotblock with themedia_idto the document's content. Without this step, the image is uploaded but not visible in the document.
Step 1: Get a Presigned URL
curl -X POST https://my.clarife.app/api/v1/media/presign \
-H "Authorization: Bearer clrf_your_key" \
-H "Content-Type: application/json" \
-d '{
"document_id": "d1234567-...",
"media_id": "m1234567-...",
"filename": "step-3-screenshot.png",
"mime_type": "image/png",
"file_size_bytes": 245760
}'| Field | Type | Required | Description |
|---|---|---|---|
| document_id | uuid | Yes | Document to attach the media to |
| media_id | uuid | Yes | Client-generated UUID v4 for the media |
| filename | string | Yes | Original filename (max 255 chars) |
| mime_type | string | Yes | MIME type (see supported types below) |
| file_size_bytes | integer | Yes | Exact file size in bytes |
Supported MIME types (images only):
| Type | Extension |
|---|---|
| image/png | .png |
| image/jpeg | .jpg |
| image/jpg (non-standard variant) | .jpg |
| image/gif | .gif |
| image/webp | .webp |
| image/svg+xml | .svg |
| image/bmp | .bmp |
| image/tiff | .tiff |
Response (201 Created):
{
"data": {
"upload_url": "https://s3.eu-central-003.backblazeb2.com/...",
"media_id": "m1234567-..."
}
}⚠️ Warning: Maximum file size is 30 MB. The presigned URL expires after 15 minutes.
Step 2: Upload the File
Upload the file directly to the presigned URL using a PUT request with the Content-Length header:
curl -X PUT "https://s3.eu-central-003.backblazeb2.com/..." \
-H "Content-Length: 245760" \
--data-binary @step-3-screenshot.png⚠️ Warning: The Content-Length header must match the file_size_bytes value from step 1 exactly.
Step 3: Confirm the Upload
curl -X POST https://my.clarife.app/api/v1/media/confirm \
-H "Authorization: Bearer clrf_your_key" \
-H "Content-Type: application/json" \
-d '{ "media_id": "m1234567-..." }'Response:
{
"data": {
"id": "m1234567-...",
"status": "active"
}
}Step 4: Link to Document
After confirming the upload, add a screenshot block to the document's content. You must send the full blocks array (read existing blocks first with GET /documents/:id):
curl -X PATCH https://my.clarife.app/api/v1/documents/d1234567-... \
-H "Authorization: Bearer clrf_your_key" \
-H "Content-Type: application/json" \
-d '{
"content": {
"meta": { "version": 1, "locale": "en" },
"blocks": [
{ "type": "heading", "id": "h1", "sort_order": 0, "level": 1, "content": "My Tutorial" },
{ "type": "text", "id": "t1", "sort_order": 1, "content": "Here is a screenshot:" },
{
"type": "screenshot",
"id": "ss1-dashboard",
"sort_order": 2,
"media_id": "m1234567-...",
"caption": "Dashboard view",
"alignment": "center"
}
]
}
}'The screenshot block requires:
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Must be "screenshot" or "image" |
| id | string | Yes | Unique block ID within the document |
| sort_order | integer | Yes | Display position (0-based) |
| media_id | uuid | Yes | The media_id from step 1 |
| caption | string | No | Caption text displayed below the image |
| alignment | string | No | "left", "center", or "right" (default: "center") |
See the Documents API for the full block schema.
Complete Example
# 1. Get presigned URL
MEDIA_ID=$(uuidgen | tr A-Z a-z)
FILESIZE=$(stat -f%z screenshot.png)
RESPONSE=$(curl -s -X POST https://my.clarife.app/api/v1/media/presign \
-H "Authorization: Bearer clrf_your_key" \
-H "Content-Type: application/json" \
-d "{
\"document_id\": \"d1234567-...\",
\"media_id\": \"$MEDIA_ID\",
\"filename\": \"screenshot.png\",
\"mime_type\": \"image/png\",
\"file_size_bytes\": $FILESIZE
}")
UPLOAD_URL=$(echo $RESPONSE | jq -r '.data.upload_url')
# 2. Upload file to presigned URL
curl -X PUT "$UPLOAD_URL" \
-H "Content-Length: $FILESIZE" \
--data-binary @screenshot.png
# 3. Confirm the upload
curl -X POST https://my.clarife.app/api/v1/media/confirm \
-H "Authorization: Bearer clrf_your_key" \
-H "Content-Type: application/json" \
-d "{\"media_id\":\"$MEDIA_ID\"}"
# 4. Add screenshot block to document (fetch existing blocks first!)
curl -X PATCH https://my.clarife.app/api/v1/documents/d1234567-... \
-H "Authorization: Bearer clrf_your_key" \
-H "Content-Type: application/json" \
-d "{
\"content\": {
\"blocks\": [
{\"type\":\"screenshot\",\"id\":\"ss1\",\"sort_order\":0,\"media_id\":\"$MEDIA_ID\",\"caption\":\"My screenshot\",\"alignment\":\"center\"}
]
}
}"Storage Limits
| Plan | Storage limit |
|---|---|
| Free | 100 MB |
| Pro | 10 GB |
| Business | 100 GB |
Exceeding the storage limit returns a 403 error with code PLAN_LIMIT_REACHED.
⚠️ Warning: Uploads that are not confirmed are automatically cleaned up after about 2 hours.