A 201 confirms creation, not every field
When you create a post, a201 means the post was created. It is not a guarantee that every field you sent was recognized. Fields we do not recognize are not applied, so a small naming mistake (for example sending media instead of media_ids, or a misspelled key) can produce a post that publishes without the media you intended.
Two habits keep you safe:
- Send only the fields documented for the endpoint, with their exact names. Validate your request body against the API Reference before you rely on a field.
- When a dropped field would be costly, read the object back with
GET /v1/posts/{id}and confirm the field is present before you depend on it.
Verify media before you publish
The presigned upload path has four steps: request a signed URL,PUT the bytes, verify, then attach. Media that has not been verified stays in a pending state, and a pending media reference does not publish silently: on a validated publish it returns 400 (media ... is not ready or not found), and on delivery it fails that target. Always confirm your media is ready before you attach it. See Media uploads for the full flow.
Response codes
Creating or publishing a post can return three statuses. Read them, and read the per-target detail:
When a target fails, the reason is on that target under
targets[].error, with the shape { "category", "caused_by", "code", "message" }. Surface targets[].error.message to your users rather than a generic retry prompt. See Error handling for the code catalog.
Delete semantics
Delete does not mean the same thing on every resource. All three return204 No Content, but what they leave behind differs:
So you detect a revoked invite from a field value, but you detect a disconnected account from its absence in the list. Two different code paths.
The brand delete takes the ID in the path with an empty body:
IDs are opaque strings
Treat every ID we return as an opaque string. Do not parse it, and do not assume a format. Today, posts, brands, and invites are UUIDs, while accounts are prefixed withacc_, and interaction IDs carry a type prefix such as sapi_cmt_. These formats can differ per object type and may change, so persist IDs as text, not as a typed uuid column.