For AI agents: markdown of this page — /docs-content-en/feedback/attachments.md documentation index — /llms.txt
Upload an attachment
POST /v1/feedback/attachments
Uploads an image and returns its ID for later linking to a ticket or comment. The upload is two-step: first the file is sent here, then the returned id is passed in the attachmentIds field when creating a ticket or adding a comment.
The file is passed as multipart/form-data in the file field. PNG, JPEG, WebP, and GIF are accepted. PNG, JPEG, and WebP are converted to WebP on the server side, GIF is re-encoded as GIF preserving animation. Limits: up to 10 MB and up to 24 million pixels per file, up to 5 attachments per message and up to 25 per ticket.
Request fields (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
file |
file | yes | A PNG, JPEG, WebP, or GIF image, up to 10 MB |
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/feedback/attachments \
-H "X-Api-Key: YOUR_API_KEY" \
-F "file=@screenshot.png"
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/v1/feedback/attachments \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-F "file=@screenshot.png"
JavaScript — personal key
const form = new FormData()
form.append('file', fileInput.files[0])
const res = await fetch('https://vibecode.bitrix24.com/v1/feedback/attachments', {
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
body: form,
})
const { data } = await res.json()
// pass data.id in attachmentIds when creating a ticket or comment
JavaScript — OAuth application
const form = new FormData()
form.append('file', fileInput.files[0])
const res = await fetch('https://vibecode.bitrix24.com/v1/feedback/attachments', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
body: form,
})
const { data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.id |
string | Attachment UUID. Passed in attachmentIds when creating a ticket or comment |
data.mime |
string | Type after processing: image/webp for PNG, JPEG, and WebP, image/gif for GIF |
data.sizeBytes |
number | Size of the processed file in bytes |
data.width |
number | Width in pixels |
data.height |
number | Height in pixels |
data.thumbnailUrl |
string | Path to the attachment thumbnail |
data.originalName |
string | Original file name |
data.expiresAt |
string | The moment after which an unlinked attachment is deleted (ISO 8601) |
Response example
{
"success": true,
"data": {
"id": "1209c405-1f99-4240-95e5-d5cc0cd43560",
"mime": "image/webp",
"sizeBytes": 20480,
"width": 1280,
"height": 720,
"thumbnailUrl": "/v1/feedback/_orphan/1209c405-1f99-4240-95e5-d5cc0cd43560/thumb",
"originalName": "screenshot.png",
"expiresAt": "2026-04-19T11:30:00.000Z"
}
}
Error response example
413 — file larger than 10 MB:
{
"success": false,
"error": {
"code": "IMAGE_TOO_LARGE",
"message": "File too large"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | NO_FILE |
No file was passed in the file field |
| 400 | INVALID_MIME |
The format is not one of PNG, JPEG, WebP, GIF |
| 400 | IMAGE_TOO_MANY_PIXELS |
More than 24 million pixels |
| 413 | IMAGE_TOO_LARGE |
File larger than 10 MB |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not passed |
| 429 | RATE_LIMITED |
More than 5 uploads per minute from one key |
For the full list of common API errors, see Errors.
Known specifics
An attachment lives for an hour before linking. An uploaded attachment is initially not linked to any ticket and is deleted after expiresAt (in one hour) if its id is not passed in attachmentIds when creating a ticket or comment. Once linked, the attachment is stored together with the ticket.
Format after processing. PNG, JPEG, and WebP are converted to WebP, so their mime in the response is image/webp. GIF is re-encoded as GIF (image/gif) preserving animation, up to 30 frames. The sizeBytes, width, and height fields refer to the processed file.