PostDrip API
Schedule posts on your businesses' social media from your own tools and AI agents. Your agent posts when it has something to say. Every day it leaves empty, PostDrip fills for you.
Quick start
1. Create a key on your profile page. Every plan includes API access.
2. Find your business id:
curl https://www.postdrip.io/api/v1/businesses \
-H "Authorization: Bearer $POSTDRIP_KEY"
3. Upload an image or video to the business's media library:
curl https://www.postdrip.io/api/v1/businesses/BUSINESS_ID/media \
-H "Authorization: Bearer $POSTDRIP_KEY" \
-F "file=@launch-day.jpg"
4. Schedule it for a day:
curl https://www.postdrip.io/api/v1/businesses/BUSINESS_ID/posts \
-H "Authorization: Bearer $POSTDRIP_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "facebook",
"date": "2026-10-14",
"caption": "Our fall menu is here. Come taste it this weekend.",
"media_url": "MEDIA_URL_FROM_STEP_3",
"alt_text": "A table set with three fall dishes"
}'
How scheduling works
- One post per day, per platform. Each business gets at most one post a day on each connected platform.
- Your post takes the day. If PostDrip already wrote a post for that day and nobody edited it, yours replaces it. If the day holds a post you created or edited, through the API or in the app, you get
409 slot_taken. Send"replace": trueto replace it anyway. - Empty days fill themselves. Any day you leave empty gets a post written, designed and published by PostDrip, as usual.
- Dates are in the business's time zone. A post for
2026-10-14goes out on that day at the business's posting time for that platform. You can schedule from today up to 30 days ahead. - What you send is what's published. Your caption and media go out as they are. The API never writes content or adds images for you.
Authentication
Send your key in the Authorization header on every request. Keys start with pd_live_. A key works for every business on your account; agencies use one key across all their clients. Revoke a key any time from your profile.
Authorization: Bearer pd_live_...
Endpoints
All paths start with https://www.postdrip.io/api/v1. Requests and responses are JSON, except media uploads.
GET/me
Your account, and whether it's an agency.
GET/businesses
Your businesses, with their connected platforms, posting times and caption limits.
{
"businesses": [{
"id": "a1b2c3d4e5f60718",
"name": "Sunrise Bakery",
"timezone": "America/Los_Angeles",
"today": "2026-10-01",
"can_schedule": true,
"platforms": [{
"platform": "facebook", "name": "Facebook", "posting_time": "morning",
"caption_limit": 5000, "media_required": false, "video_supported": true
}]
}]
}
GET/businesses/{id}/schedule
Every day and platform in a range: the post, or null with "autofill": true when PostDrip will fill it.
| Query | Meaning |
|---|---|
from | First day (YYYY-MM-DD). Defaults to today in the business's time zone. |
to | Last day. Defaults to 14 days from from. At most 31 days are returned per call. |
platform | Only this platform. |
cursor | Pass next_cursor from the previous response to get the next page. |
{
"from": "2026-10-01", "to": "2026-10-14", "timezone": "America/Los_Angeles",
"days": [{
"date": "2026-10-01",
"slots": [
{ "platform": "facebook", "post": { "id": 912, "status": "scheduled", "source": "ai", ... }, "autofill": false },
{ "platform": "x", "post": null, "autofill": true }
]
}],
"next_cursor": null
}
A post's source says who wrote it: ai (PostDrip), api (created through this API) or user (added in the app).
POST/businesses/{id}/media
Upload one file as multipart/form-data in a field named file. Images: JPEG, PNG or WebP up to 10 MB. Video: MP4 up to 100 MB. The file goes into the business's media library and stays there until you delete it. Returns its id and media_url; use either when creating a post.
{
"id": 318, "media_url": "https://...", "thumb_url": "https://...",
"media_kind": "image", "content_type": "image/jpeg", "size_bytes": 482113,
"name": null, "source": "api", "created_at": "2026-10-02T17:21:05Z"
}
Each business has a storage allowance: 5 GB on Autopilot and 100 GB on Teams. A full library returns 413 library_full.
GET/businesses/{id}/media
The business's media library, newest first. It holds every file uploaded through the API and in the app.
| Query | Meaning |
|---|---|
kind | image or video. Leave out for both. |
limit | Files per page. Defaults to 50, at most 100. |
cursor | Pass next_cursor from the previous response to get the next page. |
{
"media": [{ "id": 318, "media_url": "https://...", "media_kind": "image", "size_bytes": 482113, ... }],
"next_cursor": null,
"usage": { "used_bytes": 482113, "limit_bytes": 5368709120 }
}
DELETE/businesses/{id}/media/{media_id}
Remove a file from the library. A file that a scheduled post still uses returns 409 media_in_use; change or delete that post first.
POST/businesses/{id}/posts
| Field | Meaning |
|---|---|
platform | Required. A connected platform, e.g. facebook. |
date | Required. The day to publish, in the business's time zone. |
caption | Required. Up to the platform's caption limit. |
media_id | Optional (media is required on some platforms). The id of a file in the business's media library. |
media_url | Optional. The same file by its media_url, instead of media_id. |
alt_text | Optional. Describes the image for screen readers. |
replace | Optional. true replaces a post you created or edited on that day. |
Returns the new post with status 201.
{
"id": 1043, "business_id": "a1b2c3d4e5f60718", "platform": "facebook",
"date": "2026-10-14", "scheduled_at": "2026-10-14T16:12:00Z",
"status": "scheduled", "source": "api",
"caption": "Our fall menu is here. Come taste it this weekend.",
"media_url": "https://...", "media_kind": "image",
"alt_text": "A table set with three fall dishes", "editable": true,
"published_at": null, "error": null
}
GET/posts/{post_id}
One post, including its status once it publishes (published, with published_at) or fails (failed, with error).
PATCH/posts/{post_id}
Change caption, media_id (or media_url), alt_text or date on a post you created. Moving to another day follows the same rules as creating. On posts PostDrip wrote, only caption can be changed. Posts that are publishing or published can't be changed.
POST/posts/{post_id}/skip and /unskip
Skip a day: nothing publishes on that platform that day, and PostDrip won't fill it. Unskip to bring the post back before the day passes.
DELETE/posts/{post_id}
Remove a post. The day becomes empty again, so PostDrip will fill it. To keep a day quiet, skip it instead.
Platforms
| Platform | platform | Caption limit | Media | Video |
|---|---|---|---|---|
facebook |
5000 | Optional | Yes | |
| Bluesky | bluesky |
200 | Optional | Yes |
instagram |
1500 | Required | Yes | |
| Mastodon | mastodon |
300 | Optional | No |
| X (Twitter) | x |
280 | Optional | Yes |
Errors & limits
Errors return a status code and a body like this:
{ "error": { "code": "slot_taken", "message": "That day already has a post you created or edited. ..." } }
| Status | When |
|---|---|
401 | Missing, invalid or revoked API key. |
403 | The business has no active plan. |
404 | The business, post or file isn't on your account. |
409 | The day is taken, skipped or already published, the post can no longer change, or a scheduled post still uses the file. |
413 / 415 | The file is too large, the media library is full, or the file isn't a supported type. |
422 | A field is missing or invalid. The code says which. |
429 | Too many requests. Limits are 120 requests a minute and 60 uploads an hour per key. |
Questions or something missing? Tell us. We're building this with the people using it.