Register a finalised attachment row after S3 upload
Step 2 of the two-step upload flow. After PUTting bytes to the
presigned URL from POST /attachments/upload-url, call this endpoint
with parent_type + parent_id + S3 key + filename to finalise the
public.attachments row. entity_id is derived from the API key
and may NOT be supplied in the body. uploaded_via is forced to
api by the canonical handler. Requires the attachments:write
scope.
Authorizations
API key issued per entity via Settings > Developers > API Keys.
Each key carries scopes (e.g. orders:read, products:write).
Bearer token format: Authorization: Bearer ark_live_ent_Test keys use ark_test_ent_. Both are issued per entity
via Settings > Developers > API Keys.
Headers
Client-generated unique key for idempotent POST/PATCH/DELETE operations. Alias for the Idempotency parameter. Max 255 chars. On retry with the same key, the original response is returned without re-executing the operation. Keys expire after 24 hours.
255Body
S3 bucket; defaults to canonical entity bucket if omitted.
Response
Attachment created
A file attached to a parent resource via parent_type + parent_id. The two-step upload flow (POST /attachments/upload-url then POST /attachments) persists bytes in S3 and the row in public.attachments. s3_bucket and s3_key are operator-internal; clients fetch the file by minting a fresh presigned URL via POST /attachments/{id}/download-url. Soft-delete clears deleted_at but does NOT delete the S3 object; an out-of-band sweeper sets s3_deleted_at once bytes are purged. Scope: attachments:read / attachments:write / attachments:delete.
"attachment"
Parent resource family (order, account, ap_bill, etc.). 1..30 chars.
Operator-supplied file name. 1..255 chars.
Content type at upload time. 1..100 chars.
File size at upload time in bytes.
Operator-internal; clients should never need this.
Operator-internal; clients should never need this.
SHA-256 of the bytes if supplied at upload time.
Origin of the upload. Set automatically; not caller-writable.
web, api, portal, migration If true, exposes via tokenized portal URL.
Optional auto-expiry; the sweeper soft-deletes past this date.
Migration provenance (versa, bubble).
Free-form caller metadata. Default {}.
Set once the sweeper purges S3 bytes.

