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

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/feedback/attachments \
  -H "X-Api-Key: YOUR_API_KEY" \
  -F "file=@screenshot.png"

curl — OAuth application

Terminal
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

javascript
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

javascript
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 time after which an unlinked attachment is deleted (ISO 8601)

Response example

JSON
{
  "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:

JSON
{
  "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 — whether declared by the client or detected from the file contents
400 MIME_MISMATCH The file signature was not recognised at all: the contents belong to none of the four formats. A mismatch between two allowed formats is not an error — processing follows the actual contents
400 IMAGE_DECODE_FAILED The file could not be parsed as an image: the data is corrupted, the image has no dimensions, or processing did not finish within 5 seconds
400 IMAGE_TOO_MANY_PIXELS More than 24 million pixels
400 TOO_MANY_FRAMES The animation has more than 30 frames
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. This is the platform-wide cap and it is divided across the backend replicas, so the effective value arrives in the X-RateLimit-Limit header

For the full list of common API errors, see Errors.

Known specifics

An attachment lives for an hour before it is linked. 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; beyond that the upload is rejected with 400 TOO_MANY_FRAMES. The sizeBytes, width, and height fields refer to the processed file.

The file extension may not match its contents. The platform derives the client-declared type from the file extension, so a JPEG saved as image.png arrives as image/png. Such a file is accepted: processing follows the actual contents, and the mime in the response is the result of re-encoding. MIME_MISMATCH is reserved for the case where the signature is not recognised at all.