{"openapi":"3.1.0","info":{"title":"Dripost API","version":"1.0.0","description":"Schedule and publish to your connected channels from scripts and agents. Authenticate with a workspace API key: `Authorization: Bearer dp_...` (Settings -> API keys). A `read` key can only read; a `post` key can also create, change, publish and delete. Every response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`; a 429 also carries `Retry-After`. Anything outside the key's workspace answers 404."},"servers":[{"url":"https://dripost.com/api/v1"}],"security":[{"bearer":[]}],"paths":{"/workspace":{"get":{"summary":"The key's workspace, scope and plan limits","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceInfo"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/channels":{"get":{"summary":"Connected channels with live health","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"channels":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts":{"get":{"summary":"List posts, newest first","parameters":[{"name":"status","in":"query","schema":{"type":"string"},"description":"One or more of DRAFT, PENDING_APPROVAL, SCHEDULED, QUEUED, PUBLISHING, PUBLISHED, FAILED, CANCELLED, comma-separated"},{"name":"platform","in":"query","schema":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Scheduled at or after"},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Scheduled at or before"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque: nextCursor from the previous page"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"nextCursor":{"type":["string","null"]}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a post: a draft, scheduled, or published now","description":"Each network's text is the deterministic transform of `text` + `hashtags` (the same adaptation the composer shows), unless `networkText` gives that network its own. With `scheduledAt` or `publishNow` it is checked exactly like a composer post (plan, the network's own rules, approvals); if refused, nothing is kept. `publishNow` schedules it for this minute and returns at once; follow it with GET /jobs/{id} or a `post.live` / `post.failed` webhook. `?dryRun=true` previews the adaptation without saving. Accepts `Idempotency-Key`.","parameters":[{"name":"dryRun","in":"query","required":false,"schema":{"type":"boolean"},"description":"Preview only; nothing is saved"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"A retried call with the same key and body replays the first response instead of doing it twice (24h; a different body under a reused key is 422 idempotency_mismatch)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePost"}}}},"responses":{"200":{"description":"dryRun=true","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DryRunPreview"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it, or a reused Idempotency-Key with a different body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts/{id}":{"get":{"summary":"One post with per-network delivery","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Post id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Change a post that has not gone out, or restore a deleted one","description":"Fields not sent keep their value. Refused within a minute of its time (409 too_late). `{ restore: true }` undoes a DELETE within 24 hours (404 past the window).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Post id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePost"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete a draft (for good), or a post still waiting (undoable for 24h)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Post id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean"},"status":{"type":"string"},"restorableUntil":{"type":["string","null"],"format":"date-time"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code: post_is_live for an already-published post)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts/{id}/publish":{"post":{"summary":"Schedule, queue, or publish now","description":"`{ when: \"at\", at }` schedules; `{ when: \"queue\" }` takes the next free queue slot (422 `no_queue_slots` when the workspace has no posting times); `{ when: \"now\" }` is the publish gate (§4.2): the first call (no `confirm`) returns `202 { status: \"needs_confirmation\", confirm, approval, preview }` and publishes nothing. A person then approves on Dripost: at `approval.url` (signed in as the key's or app's own user) or from the email sent to the workspace owner; whichever is used first counts, and the approval publishes. Calling again with `confirm` (30-minute expiry) reports the outcome: `202 { jobId, status: \"approved\" }`, `409 approval_pending` while nobody has decided, `409 approval_declined`, or `409 confirm_stale` if the post was edited since. Past ten publishes a minute per workspace the approved post goes out the next minute with room: `status: \"queued_by_limit\"` with its `scheduledAt`. Accepts `Idempotency-Key`; the confirm call has a different body, so give it its own key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Post id"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"A retried call with the same key and body replays the first response instead of doing it twice (24h; a different body under a reused key is 422 idempotency_mismatch)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishInput"}}}},"responses":{"202":{"description":"Job accepted, or needs_confirmation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishResult"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or immediate_publish_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"already_publishing, confirm_stale, approval_pending, approval_declined, or approval_failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts/{id}/retry":{"post":{"summary":"Retry exactly one network whose delivery FAILED","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Post id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["network"],"properties":{"network":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostStatus"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/{id}":{"get":{"summary":"Publish or media-import job status","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Job id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/variants/{id}/optimize":{"post":{"summary":"Opt-in AI rewrite of one variant (spends an AI credit)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Variant id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/media":{"get":{"summary":"The media library, newest first","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":60,"default":24}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque: nextCursor from the previous page"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"}},"nextCursor":{"type":["string","null"]}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/media/presign":{"post":{"summary":"Step 1 of an upload: get a URL to PUT the file to","description":"Returns `mode: single` with one `url`, or `mode: multipart` with `parts[]` for large files. PUT the bytes (Content-Type as returned), then call /media/finalize. Files up to the plan's storage; images JPEG/PNG/GIF/WebP, video MP4/MOV/WebM.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sizeBytes","contentType"],"properties":{"fileName":{"type":"string"},"sizeBytes":{"type":"integer"},"contentType":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Storage unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/media/import":{"post":{"summary":"Import an image or video from a public HTTPS URL, byte for byte","description":"Direct file links only: a redirect is refused, so Drive and Dropbox share links are not accepted. URL up to 2,048 characters, query up to 1,024; files up to 2 GB. The request only checks the link; the file is fetched in the background. Follow GET /jobs/{jobId}: `mediaId` is set once it is done.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"202":{"description":"Import started","content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["queued"]}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Import unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/media/finalize":{"post":{"summary":"Step 2 of an upload: the file is checked by its bytes and added to the library","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["assetId","extension"],"properties":{"assetId":{"type":"string"},"extension":{"type":"string"},"fileName":{"type":"string"},"uploadId":{"type":"string","description":"Multipart only"},"parts":{"type":"array","items":{"type":"object","properties":{"partNumber":{"type":"integer"},"etag":{"type":"string"}}}},"abort":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Already added","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Added","content":{"application/json":{"schema":{"type":"object","properties":{"asset":{"type":"object"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"summary":"Webhook endpoints of this workspace","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Register a webhook endpoint; the signing secret is returned once","description":"https only, public host, default port. Deliveries are signed (see Dripost-Signature on /docs/api), retried with backoff for about two days, and the endpoint is disabled after 10 events in a row could not be delivered, or at once on 410 Gone. At most 10 endpoints per workspace.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"},"minItems":1}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"},"secret":{"type":"string","description":"whsec_..., shown once"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"get":{"summary":"One webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Change the URL/events, and/or rotate the signing secret","description":"A rotated secret is returned once, like creation; the old secret keeps signing alongside it for 24 hours (Dripost-Signature carries a v1 for each).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"},"minItems":1},"rotateSecret":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"},"secret":{"type":"string","description":"whsec_..., only present when rotateSecret was true"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Remove a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/test":{"post":{"summary":"Send a webhook.test event right now, outside the retry queue","description":"Signed the same way as a real delivery and recorded in the deliveries list, but never retried and never counted toward the auto-disable threshold.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"delivered":{"type":"boolean"},"statusCode":{"type":["integer","null"]},"error":{"type":["string","null"]},"delivery":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan does not allow it (code: entitlement)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope: this is a read key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in a state that allows this (code says which)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A network's own rules refuse it (code: blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/deliveries":{"get":{"summary":"The last 20 deliveries to one endpoint, newest first","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked key, or its creator is no longer an owner/admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this key's workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit: see Retry-After and RateLimit-* headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"A workspace API key, dp_..."}},"schemas":{"WebhookEvent":{"type":"string","enum":["post.live","post.failed","channel.disconnected"]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"secretLastFour":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"disabledAt":{"type":["string","null"],"format":"date-time"},"disabledReason":{"type":["string","null"]},"rotatingUntil":{"type":["string","null"],"format":"date-time","description":"Set while a rotated-out secret still signs alongside the new one"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"event":{"type":"string"},"status":{"type":"string","enum":["pending","delivered","failed"]},"attempts":{"type":"integer"},"lastStatusCode":{"type":["integer","null"]},"lastError":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"deliveredAt":{"type":["string","null"],"format":"date-time"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"code":{"type":"string"}}},"WorkspaceInfo":{"type":"object","properties":{"workspace":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"requireApproval":{"type":"boolean"}}},"key":{"type":"object","properties":{"id":{"type":"string"},"scope":{"type":"string","enum":["read","post"]}}},"plan":{"type":"object"}}},"Channel":{"type":"object","properties":{"id":{"type":"string"},"platform":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]},"username":{"type":"string"},"displayName":{"type":["string","null"]},"clientId":{"type":"string","description":"The client this channel belongs to."},"status":{"type":"string"},"health":{"type":"string","enum":["ok","expiring","broken"]},"healthReason":{"type":["string","null"]}}},"TransformInput":{"type":"object","required":["platform","baseText"],"properties":{"platform":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]},"baseText":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}},"title":{"type":"string"}}},"TransformResult":{"type":"object","properties":{"text":{"type":"string"},"firstComment":{"type":"string"},"title":{"type":"string"},"placement":{"type":"string"},"warnings":{"type":"array","items":{"type":"string"}}}},"CreatePost":{"type":"object","required":["text","platforms"],"properties":{"text":{"type":"string"},"platforms":{"type":"array","items":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]},"minItems":1},"hashtags":{"type":"array","items":{"type":"string"},"description":"Without #; placed where each network expects them"},"mediaIds":{"type":"array","items":{"type":"string"},"description":"Library ids from /media or /media/finalize"},"channels":{"type":"object","additionalProperties":{"type":"string"},"description":"Network -> channel id, when the workspace has several channels on one network"},"clientId":{"type":"string","description":"The client (brand) the post is for. Needed when the workspace has several clients and no channels are named; each channel's clientId is in GET /channels."},"networkText":{"type":"object","additionalProperties":{"type":"string"},"description":"Network -> its own text; refused (422), never cut, if over that network's limit"},"youtube":{"type":"object","properties":{"title":{"type":"string"},"privacy":{"type":"string","enum":["public","unlisted","private"]},"thumbnailMediaId":{"type":"string"},"shortsTag":{"type":"boolean"}}},"firstComment":{"type":"string","description":"Instagram and YouTube only"},"facebookPlacement":{"type":"string","enum":["feed","reel"]},"scheduledAt":{"type":"string","format":"date-time"},"publishNow":{"type":"boolean"}}},"UpdatePost":{"type":"object","properties":{"text":{"type":"string"},"platforms":{"type":"array","items":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]}},"networkText":{"type":"object","additionalProperties":{"type":"string"},"description":"Keyed by network, e.g. { \"X\": \"...\" }"},"mediaIds":{"type":"array","items":{"type":"string"}},"channels":{"type":"object","additionalProperties":{"type":"string"},"description":"Keyed by network, e.g. { \"X\": \"...\" }"},"youtube":{"type":"object"},"firstComment":{"type":["string","null"]},"facebookPlacement":{"type":"string","enum":["feed","reel"]},"scheduledAt":{"type":"string","format":"date-time"}}},"Delivery":{"type":"object","properties":{"status":{"type":"string","enum":["PENDING","IN_FLIGHT","CONFIRMING","PUBLISHED","FAILED","UNKNOWN"]},"attempts":{"type":"integer"},"permalink":{"type":["string","null"]},"externalId":{"type":["string","null"]},"error":{"type":["string","null"],"description":"The network's own refusal, verbatim"},"publishedAt":{"type":["string","null"],"format":"date-time"},"warnings":{"type":"array","items":{"type":"object"}}}},"Post":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"heldForApproval":{"type":"boolean"},"hold":{"type":["object","null"],"description":"After a connected app writes or changes a post, Dripost holds it for a short review window (default 10 minutes) before it can go out; the owner can cancel it in that time. Null when there is none. Not an error: nothing to retry.","properties":{"until":{"type":"string","format":"date-time"},"minutesLeft":{"type":"integer"},"goesOutFrom":{"type":["string","null"],"format":"date-time","description":"Earliest send: the later of `until` and `scheduledAt`. Null for a draft."},"note":{"type":"string","description":"One calm sentence to show a person"}}},"text":{"type":"string"},"authoredBy":{"type":["string","null"],"description":"User id of the workspace member who wrote it"},"scheduledAt":{"type":["string","null"],"format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"networks":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]},"variantId":{"type":"string"},"channelId":{"type":["string","null"]},"text":{"type":"string"},"title":{"type":"string"},"firstComment":{"type":"string"},"delivery":{"oneOf":[{"$ref":"#/components/schemas/Delivery"},{"type":"null"}]}}}}}},"PostStatus":{"type":"object","properties":{"postId":{"type":"string"},"status":{"type":"string"},"deliveries":{"type":"array","items":{"type":"object"}}}},"DryRunPreview":{"type":"object","properties":{"dryRun":{"type":"boolean"},"when":{"type":"string","enum":["draft","at","now"]},"mediaCount":{"type":"integer"},"networks":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]},"text":{"type":"string"},"channelId":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"string"}}}}}}},"PublishInput":{"type":"object","required":["when"],"properties":{"when":{"type":"string","enum":["now","at","queue"]},"at":{"type":"string","format":"date-time","description":"Required when when is \"at\""},"confirm":{"type":"string","description":"The token from a prior needs_confirmation response; the call reports whether a person approved"}}},"PublishResult":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["needs_confirmation","approved","queued_by_limit"]},"scheduledAt":{"type":"string","format":"date-time","description":"queued_by_limit: when the post now goes out (the next queue slot, or the next minute with room)"},"confirm":{"type":"string"},"approval":{"type":"object","description":"needs_confirmation: where a person approves this publish","properties":{"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"emailedOwner":{"type":"boolean"},"message":{"type":"string"}}},"preview":{"type":"object","properties":{"networks":{"type":"array","items":{"type":"string","enum":["INSTAGRAM","YOUTUBE","X","LINKEDIN","THREADS","FACEBOOK"]}},"firstLine":{"type":"string"},"mediaCount":{"type":"integer"},"when":{"type":"string"}}}}},"JobStatus":{"type":"object","properties":{"jobId":{"type":"string"},"kind":{"type":"string","enum":["publish","media_import"]},"status":{"type":"string","enum":["queued","publishing","importing","done","failed","cancelled"]},"postId":{"type":"string"},"mediaId":{"type":["string","null"],"description":"media_import: the library id once done"},"error":{"type":"string","description":"media_import: why it failed"},"code":{"type":"string","description":"media_import: not_media, too_large, redirect_refused, origin_refused, size_mismatch, storage_full, deadline, …"}}},"Media":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["IMAGE","VIDEO"]},"fileName":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"durationSeconds":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"}}}}}}