Endpoint capability matrix
Quick reference for every write endpoint. Use this to design retry logic, webhook handlers, and error recovery without reading each endpoint’s full docs.
Column definitions
| Column | Meaning |
|---|---|
| Idempotent | Accepts Idempotency-Key header. Repeat requests with the same key and body return the cached response without re-executing. |
| Async | The operation completes after the HTTP response returns. The response reflects queued state, not final state. Poll or use webhooks to observe completion. |
| Emits webhook | The event name(s) fired as a side-effect of a successful call. |
| Retry-safe | Whether retrying a failed request is safe without risk of duplicate side-effects. All idempotent endpoints are retry-safe with the same key. |
| Partial success | Whether the response can indicate that some sub-operations succeeded while others failed. |
All write endpoints (POST, PATCH, DELETE) accept the Idempotency-Key header globally. The Idempotent column marks endpoints where idempotency is particularly important to use in production. See Idempotency for key format and behavior.
Posts
| Endpoint | Idempotent | Async | Emits webhook | Retry-safe | Partial success |
|---|---|---|---|---|---|
POST /v1/posts | ✅ Recommended | No — post is created synchronously | post.created, post.scheduled (if scheduled) | ✅ with key | No |
PATCH /v1/posts/:id | ✅ use version token | No | — | ✅ | No |
DELETE /v1/posts/:id | ✅ | No | — | ✅ | No |
POST /v1/posts/:id/publish | ✅ | Yes — publish is queued to SQS | post.published or post.failed (on completion) | ✅ with key | No |
POST /v1/posts/:id/retry | ✅ Recommended | Yes — re-queued to SQS | post.published or post.failed (on completion) | ✅ with key | Yes — some platforms may succeed while others fail |
POST /v1/posts/:id/cancel | ✅ | No | — | ✅ | No |
POST /v1/posts/:id/clone | ✅ | No | post.created | ✅ with key | No |
POST /v1/posts/:id/duplicate | ✅ | No | post.created | ✅ with key | No |
POST /v1/posts/:id/unpublish | ✅ | No | — | ✅ | No |
POST /v1/posts/:id/platforms/:id/fix | ✅ | Yes — re-queued to SQS | post.published or post.failed (on completion) | ✅ with key | Yes |
POST /v1/posts/bulk | ✅ Recommended | No — each post created synchronously | post.created per item | ✅ with key | Yes — HTTP 207; per-item status |
POST /v1/posts/bulk-video | ✅ | No | post.created per item | ✅ with key | Yes — HTTP 207 |
POST /v1/posts/validate | — (read-only semantics) | No | — | ✅ always | No |
POST /v1/posts/:id/recurrence | ✅ | No | — | ✅ | No |
PATCH /v1/posts/:id/recurrence | ✅ | No | — | ✅ | No |
DELETE /v1/posts/:id/recurrence | ✅ | No | — | ✅ | No |
Accounts
| Endpoint | Idempotent | Async | Emits webhook | Retry-safe | Partial success |
|---|---|---|---|---|---|
POST /v1/accounts/connect/:platform | — | No — returns OAuth URL | — | ✅ | No |
POST /v1/accounts/callback/:platform | — | No | account.connected | No — replaying OAuth codes fails | No |
DELETE /v1/accounts/:id | ✅ | No | account.disconnected | ✅ | No |
POST /v1/accounts/:id/refresh | ✅ | No | — | ✅ | No |
POST /v1/accounts/:id/test | — | No | — | ✅ | No |
POST /v1/accounts/:id/select-page | ✅ | No | — | ✅ | No |
POST /v1/accounts/:id/backfill | ✅ | Yes — analytics pulled async | — | ✅ | No |
Media
| Endpoint | Idempotent | Async | Emits webhook | Retry-safe | Partial success |
|---|---|---|---|---|---|
POST /v1/media/upload | ✅ | No — returns presigned URL; S3 upload is separate | — | ✅ | No |
DELETE /v1/media/:id | ✅ | No | — | ✅ | No |
POST /v1/media/:id/validate | ✅ | Yes — validation is queued | — | ✅ | No |
POST /v1/media/register | ✅ | No | — | ✅ | No |
POST /v1/media/bulk-presign | ✅ | No | — | ✅ | Yes — per-file upload URLs |
POST /v1/media/bulk-video-upload-urls | ✅ | No | — | ✅ | Yes — per-file upload URLs |
POST /v1/media/bulk-validate | ✅ | Yes — queued | — | ✅ | No |
POST /v1/media/import-from-url | ✅ | Yes — async import | — | ✅ | No |
POST /v1/media/import-from-drive | ✅ | Yes — async import | — | ✅ | No |
S3 PUT (direct upload) | — | No | media.uploaded (triggered by S3 event after upload) | ✅ | No |
Webhooks
| Endpoint | Idempotent | Async | Emits webhook | Retry-safe | Partial success |
|---|---|---|---|---|---|
POST /v1/webhooks | ✅ | No | — | ✅ | No |
PATCH /v1/webhooks/:id | ✅ | No | — | ✅ | No |
DELETE /v1/webhooks/:id | ✅ | No | — | ✅ | No |
POST /v1/webhooks/:id/rotate-secret | ✅ | No | — | No — secret changes each call | No |
POST /v1/webhooks/test | — | No | — | ✅ | No |
POST /v1/webhooks/:id/deliveries/:id/retry | ✅ | Yes — re-queued | — | ✅ | No |
Design implications
For async endpoints: the HTTP response tells you the operation is queued, not complete. Subscribe to the corresponding webhook event, or poll GET until the terminal status. Never assume an async endpoint’s 2xx means the underlying action succeeded.
For partial-success endpoints: always inspect the per-item result array, not just the top-level status code. A 207 or even 200 response can contain per-item failures.
For idempotent retries: use the same Idempotency-Key on every retry of the same logical request. The key must remain stable across attempts — do not generate a new UUID per attempt.