support_attachment_create
Reserve a file on a support thread and get a short-lived signed URL to upload it to.
Reserve a file on a support thread and get a short-lived signed URL to upload it to. The bytes never pass through this API: PUT them to the returned uploadUrl with the same Content-Type AND the header "x-goog-content-length-range: 0,26214400", both of which the signature covers — omit either and storage refuses the PUT. Then call support_attachment_finalize, which checks that the first bytes really are the type you declared. Only the content types listed on the contentType field are accepted. A thread may hold at most 20 attachments waiting for their bytes at once; past that the call is refused with 429 and a message beginning "too_many_pending_attachments". Until finalized the attachment is pending — it cannot be attached to a message and is invisible in message output. A thread belonging to another product is reported as not found
Behavior
- HTTP
POST /support/attachments
Arguments
| Name | Type | Required | Description |
|---|---|---|---|
| fileName | string | • | Display name of the file, e.g. "invoice.pdf". Only the base name is used for the storage key; any directory part is discarded |
| threadId | string | • | Thread the file belongs to. An attachment is created against a thread first and claimed by one of its messages later, when that message is posted |
| sizeBytes | integer | • | Size of the file in bytes, at most 26214400. Declared up front so an oversized upload is refused before a URL is issued; finalize checks the real size again |
| contentType | string | • | MIME type of the file, which must be one of: image/jpeg, image/png, image/gif, image/webp, image/heic, video/mp4, video/webm, video/quicktime, application/pdf, text/plain, application/zip. Exact strings only — a parameter such as "; charset=utf-8" is refused. The upload URL is signed for exactly this type, so the PUT must send the same Content-Type header, and finalize refuses the file unless its first bytes really are this type |
Response
| Field | Type | Always | Description |
|---|---|---|---|
| id | string | • | Attachment id |
| status | string | • | pending: the row exists and an upload URL was issued, but no bytes have been confirmed. uploaded: finalize saw the object in storage and its first bytes matched the declared type. rejected: they did not, the object was deleted, and this attachment is finished — the state is terminal. Only uploaded attachments can be attached to a message or downloaded |
| fileName | string | • | Display name of the file |
| threadId | string | • | Thread this attachment belongs to |
| createdAt | string | • | ISO-8601 creation timestamp |
| messageId | string | • | The message that carries this attachment, or null while nothing claims it yet |
| sizeBytes | integer | • | Size in bytes: what the caller declared while the attachment is pending, what storage reported once it is uploaded |
| uploadUrl | string | • | Short-lived signed URL. PUT the file bytes here with the same Content-Type, then call support_attachment_finalize. The URL is a bearer credential for this one object |
| uploadedAt | string | • | ISO-8601 timestamp of the confirmed upload, or null while pending |
| contentType | string | • | MIME type declared when the attachment was created |
| rejectedReason | string | • | Why finalize refused the file — signature_mismatch, not_utf8, nul_byte or markup_in_text — or null in any state but rejected |
| uploadExpiresAt | string | • | ISO-8601 moment the upload URL stops working |
Try it
Reserve a file on a support thread and get a short-lived signed URL to upload it to.