PostFast
Schedule social media posts across 11 platforms from one API. SaaS — no self-hosting needed.
Setup
- Sign up at https://app.postfa.st/register (7-day free trial, no credit card)
- Go to Workspace Settings → generate an API key
- Set the environment variable:
export POSTFAST_API_KEY="your-api-key"
Base URL:
https://api.postfa.st
Auth header:
pf-api-key: $POSTFAST_API_KEY
Important: The header name is
pf-api-key
(not
Authorization: Bearer
or
x-api-key
). Regenerating your key in settings permanently invalidates the previous one. See
Troubleshooting if you get 403 errors.
Core Workflow
1. List connected accounts
curl -s -H "pf-api-key: $POSTFAST_API_KEY" https://api.postfa.st/social-media/my-social-accounts
Returns array of
{ id, platform, platformUsername, displayName }
. Save the
id
— it's the
socialMediaId
required for every post.
Platform values:
TIKTOK
,
INSTAGRAM
,
FACEBOOK
,
X
,
YOUTUBE
,
LINKEDIN
,
THREADS
,
BLUESKY
,
PINTEREST
,
TELEGRAM
,
GOOGLE_BUSINESS_PROFILE
2. Schedule a text post (no media)
curl -X POST https://api.postfa.st/social-posts \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posts": [{
"content": "Your post text here",
"mediaItems": [],
"scheduledAt": "2026-06-15T10:00:00.000Z",
"socialMediaId": "ACCOUNT_ID_HERE"
}],
"controls": {}
}'
Returns
{ "postIds": ["uuid-1"] }
.
3. Schedule a post with media (3-step flow)
Step A — Get signed upload URLs:
curl -X POST https://api.postfa.st/file/get-signed-upload-urls \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contentType": "image/png", "count": 1 }'
Returns
[{ "key": "image/uuid.png", "signedUrl": "https://..." }]
.
Step B — Upload file to S3:
curl -X PUT "SIGNED_URL_HERE" \
-H "Content-Type: image/png" \
--data-binary @/path/to/file.png
Step C — Create post with media key:
curl -X POST https://api.postfa.st/social-posts \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posts": [{
"content": "Post with image!",
"mediaItems": [{ "key": "image/uuid.png", "type": "IMAGE", "sortOrder": 0 }],
"scheduledAt": "2026-06-15T10:00:00.000Z",
"socialMediaId": "ACCOUNT_ID_HERE"
}],
"controls": {}
}'
For video: use
contentType: "video/mp4"
,
type: "VIDEO"
, key prefix
video/
.
4. List scheduled posts
curl -s -H "pf-api-key: $POSTFAST_API_KEY" "https://api.postfa.st/social-posts?page=0&limit=20"
Returns
{ "data": [...], "totalCount": 25, "pageInfo": { "page": 1, "hasNextPage": true, "perPage": 20 } }
.
Query parameters:
page
(int, default 0) — 0-based page index. Response shows 1-based display page in pageInfo.page
limit
(int, default 20, max 50) — items per page
platforms
(string) — comma-separated filter: FACEBOOK,INSTAGRAM,X
statuses
(string) — comma-separated: DRAFT
, SCHEDULED
, PUBLISHED
, FAILED
from
/ to
(ISO 8601 UTC) — date range filter on scheduledAt
Example:
GET /social-posts?page=0&limit=50&platforms=X,LINKEDIN&statuses=SCHEDULED&from=2026-06-01T00:00:00Z&to=2026-06-30T23:59:59Z
5. Delete a scheduled post
curl -X DELETE -H "pf-api-key: $POSTFAST_API_KEY" https://api.postfa.st/social-posts/POST_ID
6. Cross-post to multiple platforms
Include multiple entries in the
posts
array, each with a different
socialMediaId
. They share the same
controls
and
mediaItems
keys.
7. Generate a connect link (for clients)
Let clients connect their social accounts to your workspace without creating a PostFast account:
curl -X POST https://api.postfa.st/social-media/connect-link \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "expiryDays": 7, "sendEmail": true, "email": "client@example.com" }'
Returns
{ "connectUrl": "https://app.postfa.st/connect?token=..." }
. Share the URL — they can connect accounts directly. Rate limit: 50/hour.
8. Create a draft post
Omit
scheduledAt
and set
status: "DRAFT"
to save without scheduling:
curl -X POST https://api.postfa.st/social-posts \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posts": [{ "content": "Draft idea...", "mediaItems": [], "socialMediaId": "ACCOUNT_ID" }],
"status": "DRAFT",
"controls": {}
}'
9. Get post analytics
Fetch published posts with their performance metrics:
curl -s -H "pf-api-key: $POSTFAST_API_KEY" \
"https://api.postfa.st/social-posts/analytics?startDate=2026-03-01T00:00:00.000Z&endDate=2026-03-31T23:59:59.999Z&platforms=TIKTOK,INSTAGRAM"
Query parameters:
startDate
(ISO 8601, required) — start of date range
endDate
(ISO 8601, required) — end of date range
platforms
(string, optional) — comma-separated filter
socialMediaIds
(string, optional) — comma-separated account UUIDs
Returns
{ "data": [{ id, content, socialMediaId, platformPostId, publishedAt, latestMetric }] }
.
latestMetric
fields:
impressions
,
reach
,
likes
,
comments
,
shares
,
totalInteractions
,
fetchedAt
,
extras
. All numbers are strings (bigint).
latestMetric
is null if metrics haven't been fetched yet.
Supported platforms for analytics: Facebook, Instagram, Threads, LinkedIn, TikTok, YouTube. LinkedIn personal accounts are excluded. YouTube returns views, likes, comments, and total interactions (no reach or shares).
Rate limit: 350/hour.
Common Patterns
Pattern 1: Cross-platform campaign
Post the same content to LinkedIn, X, and Threads at the same time:
curl -X POST https://api.postfa.st/social-posts \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posts": [
{ "content": "Big announcement!", "mediaItems": [], "scheduledAt": "2026-06-15T09:00:00.000Z", "socialMediaId": "LINKEDIN_ID" },
{ "content": "Big announcement!", "mediaItems": [], "scheduledAt": "2026-06-15T09:00:00.000Z", "socialMediaId": "X_ID" },
{ "content": "Big announcement!", "mediaItems": [], "scheduledAt": "2026-06-15T09:00:00.000Z", "socialMediaId": "THREADS_ID" }
],
"controls": {}
}'
See examples/cross-platform-post.json for a complete example.
Pattern 2: Instagram Reel with upload
- Get signed URL with
contentType: "video/mp4"
- PUT video to signed URL
- Create post with
instagramPublishType: "REEL"
Optional: add a custom cover image by uploading a JPEG (max 8MB) via the same 3-step flow, then set
coverImageKey
in the media item. You can also set
coverTimestamp
(milliseconds) as a fallback frame.
See examples/instagram-reel.json for the basic request, or examples/instagram-reel-cover.json for a Reel with a custom cover image.
Pattern 3: TikTok video with privacy settings
Upload video, then post with privacy controls:
# controls object:
{
"tiktokPrivacy": "PUBLIC",
"tiktokAllowComments": true,
"tiktokAllowDuet": false,
"tiktokAllowStitch": false,
"tiktokBrandContent": true
}
See examples/tiktok-video.json.
Pattern 4: Pinterest pin (board required)
Always fetch boards first, then post:
# Step 1: Get boards
curl -s -H "pf-api-key: $POSTFAST_API_KEY" \
https://api.postfa.st/social-media/PINTEREST_ACCOUNT_ID/pinterest-boards
Step 2: Post with board ID
controls: { "pinterestBoardId": "BOARD_ID", "pinterestLink": "https://yoursite.com" }
See examples/pinterest-pin.json.
Pattern 5: YouTube Short with tags and playlist
Upload video, then post with YouTube controls:
# controls object:
{
"youtubeIsShort": true,
"youtubeTitle": "Quick Tip: Batch Your Content",
"youtubePrivacy": "PUBLIC",
"youtubePlaylistId": "PLxxxxxx",
"youtubeTags": ["tips", "productivity", "social media"],
"youtubeMadeForKids": false
}
See examples/youtube-short.json.
Pattern 5b: YouTube video with custom thumbnail
Upload both video and thumbnail image, then reference the thumbnail key in controls:
# 1. Upload thumbnail image (separate from video upload)
curl -X POST https://api.postfa.st/file/get-signed-upload-urls \
-H "pf-api-key: $POSTFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contentType": "image/jpeg", "count": 1 }'
# PUT thumbnail to signed URL
2. Upload video (same 3-step flow as always)
3. Create post with thumbnail key in controls:
{
"youtubeIsShort": false,
"youtubeTitle": "Full Tutorial: Social Media Strategy",
"youtubePrivacy": "PUBLIC",
"youtubeThumbnailKey": "image/abc123.jpg",
"youtubeTags": ["tutorial", "social media"],
"youtubeMadeForKids": false
}
Thumbnail specs: JPEG/PNG recommended, max 2MB, 1280x720 (16:9), min width 640px. Requires phone-verified YouTube channel. If thumbnail upload fails, the video still publishes without the custom thumbnail.
See examples/youtube-video-thumbnail.json.
Pattern 6: Google Business Profile post
Always fetch locations first, then post with GBP-specific controls:
# Step 1: Get locations
curl -s -H "pf-api-key: $POSTFAST_API_KEY" \
https://api.postfa.st/social-media/GBP_ACCOUNT_ID/gbp-locations
Step 2: Create a standard post with CTA
controls: { "gbpLocationId": "accounts/.../locations/...", "gbpTopicType": "STANDARD", "gbpCallToActionType": "LEARN_MORE", "gbpCallToActionUrl": "https://yoursite.com" }
Three post types:
STANDARD
(updates),
EVENT
(time-bound),
OFFER
(deals with coupons). EVENT and OFFER require
gbpEventTitle
,
gbpEventStartDate
,
gbpEventEndDate
.
See examples/gbp-standard.json, examples/gbp-event.json, and examples/gbp-offer.json.
Pattern 7: LinkedIn document post
Documents (PDF, PPTX, DOCX) display as swipeable carousels on LinkedIn.
- Get signed URL with
contentType: "application/pdf"
- PUT the file to signed URL
- Create post using
linkedinAttachmentKey
instead of mediaItems
# controls: { "linkedinAttachmentKey": "file/uuid.pdf", "linkedinAttachmentTitle": "Q1 Marketing Playbook" }
# Note: mediaItems should be [] when using linkedinAttachmentKey
See examples/linkedin-document.json.
Pattern 8: First comment (auto-posted after publish)
Add a
firstComment
to any post — it's auto-posted ~10 seconds after the main post goes live (up to 3 retries):
{
"posts": [{ "content": "Main post text", "firstComment": "Link: https://postfa.st", "mediaItems": [], "scheduledAt": "...", "socialMediaId": "X_ID" }],
"controls": {}
}
Supported on: X, Instagram, Facebook, YouTube, Threads. NOT supported on: TikTok, Pinterest, Bluesky, LinkedIn.
See examples/x-first-comment.json.
Pattern 9: X (Twitter) retweet
Schedule a retweet — content and media are ignored:
{
"posts": [{ "content": "", "scheduledAt": "...", "socialMediaId": "X_ID" }],
"controls": { "xRetweetUrl": "https://x.com/username/status/1234567890" }
}
See examples/x-retweet.json.
Pattern 10: Batch scheduling (a week of posts)
Schedule multiple posts at different times in a single API call (up to 15 posts per request):
See examples/batch-scheduling.json.
Platform-Specific Controls
Pass these in the
controls
object. See
references/platform-controls.md for full details.
| Platform | Key Controls |
|---|
| TikTok | tiktokPrivacy , tiktokAllowComments , tiktokAllowDuet , tiktokAllowStitch , tiktokIsDraft , tiktokIsAigc , tiktokBrandOrganic , tiktokBrandContent , tiktokAutoAddMusic
|
| Instagram | instagramPublishType (TIMELINE/STORY/REEL), instagramPostToGrid , instagramCollaborators , instagramTrialReelStrategy
|
| Facebook | facebookContentType (POST/REEL/STORY), facebookReelsCollaborators
|
| YouTube | youtubeIsShort , youtubeTitle , youtubePrivacy , youtubePlaylistId , youtubeTags , youtubeMadeForKids , youtubeCategoryId , youtubeThumbnailKey
|
| LinkedIn | linkedinAttachmentKey , linkedinAttachmentTitle (for document posts) |
| X (Twitter) | xRetweetUrl (retweet), xCommunityId (post to community) |
| Pinterest | pinterestBoardId (required), pinterestLink
|
| Google Business Profile | gbpLocationId (required), gbpTopicType , gbpCallToActionType , gbpCallToActionUrl , gbpEventTitle , gbpEventStartDate , gbpEventEndDate , gbpOfferCouponCode , gbpOfferRedeemUrl , gbpOfferTerms
|
| Bluesky | No platform-specific controls — text + images only |
| Threads | No platform-specific controls — text + images/video |
| Telegram | No platform-specific controls — text + images/video/mixed media |
Helper Endpoints
- Pinterest boards:
GET /social-media/{id}/pinterest-boards
→ returns [{ boardId, name }]
- YouTube playlists:
GET /social-media/{id}/youtube-playlists
→ returns [{ playlistId, title }]
- GBP locations:
GET /social-media/{id}/gbp-locations
→ returns [{ id, locationId, title, address, mapsUri }]
. Use locationId
as gbpLocationId
in controls
- Connect link:
POST /social-media/connect-link
→ returns { connectUrl }
. Let clients connect accounts without a PostFast account. Params: expiryDays
(1-30, default 7), sendEmail
(bool), email
(required if sendEmail=true)
Rate Limits
Global (per API key): 60/min, 150/5min, 300/hour, 2000/day
Per-endpoint:
POST /social-posts
: 350/day
GET /social-posts
: 200/hour
GET /social-posts/analytics
: 350/hour
POST /social-media/connect-link
: 50/hour
Platform limits:
- X (Twitter) via API: 5 posts per account per day — do not exceed this
Check
X-RateLimit-Remaining-*
headers. 429 = rate limited, check
Retry-After-*
header. For batch operations, add a 1-second delay between API calls.
Media Specs Quick Reference
| Platform | Images | Video | Carousel |
|---|
| TikTok | Carousels only | ≤250MB, MP4/MOV, 3s-10min | 2-35 images |
| Instagram | JPEG/PNG | ≤1GB, 3-90s (Reels) | Up to 10 |
| Facebook | ≤30MB, JPG/PNG | 1 per post | Up to 10 images |
| YouTube | — | Shorts ≤3min, H.264 | — |
| LinkedIn | Up to 9 | ≤10min | Up to 9, or documents (PDF/PPTX/DOCX) |
| X (Twitter) | Up to 4 | — | — |
| Pinterest | 2:3 ratio ideal | Supported | 2-5 images |
| Google Business Profile | 1 image (JPEG/PNG, 5MB max) | Not supported | — |
| Bluesky | Up to 4 | Not supported | — |
| Threads | Supported | Supported | Up to 10 |
| Telegram | Up to 10 | Supported | Up to 10 mixed media |
Common Gotchas
- Always fetch accounts first —
socialMediaId
is a UUID, not a platform name. Call GET /social-media/my-social-accounts
to get valid IDs.
- Media MUST go through 3-step upload — No external URLs. Always: get signed URL → PUT to S3 → use the
key
in mediaItems
.
scheduledAt
must be in the future — ISO 8601 UTC format. Past dates return 400.
- Pinterest ALWAYS requires
pinterestBoardId
— Fetch boards first with GET /social-media/{id}/pinterest-boards
.
- TikTok requires video for standard posts — Images only work in carousels (2-35 images).
- LinkedIn documents use
linkedinAttachmentKey
— NOT mediaItems
. Set mediaItems: []
when posting documents.
- Content-Type on S3 PUT must match — The
Content-Type
header in your S3 PUT must match what you requested in get-signed-upload-urls
.
- Instagram Reels need video 3-90 seconds — Outside this range returns an error.
- YouTube Shorts need video under 3 minutes — H.264 codec with AAC audio recommended.
- X (Twitter) has a 280 character limit — Longer content is silently truncated.
- Cross-posting shares controls — The
controls
object applies to ALL posts in the batch. Platform-irrelevant controls are ignored.
- X (Twitter) API limit is 5 posts/account/day — Exceeding this risks account restrictions.
firstComment
only works on 5 platforms — X, Instagram, Facebook, YouTube, Threads. TikTok, Pinterest, Bluesky, LinkedIn return a validation error.
- Retweets ignore content/media — When
xRetweetUrl
is set, the content
and mediaItems
fields are ignored.
- LinkedIn documents support PDF, DOC, DOCX, PPT, PPTX — Max 60MB. Cannot mix with regular media.
- Pagination is 0-based —
page=0
returns the first page. Response pageInfo.page
shows 1-based display number.
- Instagram trial reels require
instagramPublishType: "REEL"
— Setting instagramTrialReelStrategy
without it returns 400. Also cannot be combined with instagramCollaborators
.
- YouTube custom thumbnails require phone verification —
youtubeThumbnailKey
only works if the YouTube channel is phone-verified. If it fails, the video still publishes without the custom thumbnail.
- GBP ALWAYS requires
gbpLocationId
— Fetch locations first with GET /social-media/{id}/gbp-locations
. Use the locationId
field (not id
).
- GBP supports only 1 image — No video, no carousels. JPEG/PNG, max 5MB.
- GBP EVENT/OFFER posts require dates —
gbpEventStartDate
and gbpEventEndDate
are required when gbpTopicType
is EVENT
or OFFER
.
- GBP content limit is 1,500 characters — Shorter than most platforms.
- GBP posts expire — Standard posts auto-expire after 6 months. Event/Offer posts expire at their end date.
coverTimestamp
is milliseconds — e.g., "5000"
= 5 seconds into the video. Not seconds.
coverImageKey
platform limits — Instagram Reels: JPEG only, max 8MB. Facebook Reels: any format, max 10MB. Pinterest video: JPEG/PNG. NOT supported on TikTok (use coverTimestamp
) or YouTube (use youtubeThumbnailKey
).
- Facebook Reels don't support
coverTimestamp
— Only coverImageKey
works for FB Reel covers. coverTimestamp
is ignored.
Troubleshooting
403 "Missing organizationId or activeWorkspaceId"
This is the most common error. It means the API didn't recognize your key. Check these in order:
-
Wrong header name. The header must be exactly
pf-api-key
. Not Authorization: Bearer
, not x-api-key
, not api-key
. Example:
# Correct
curl -H "pf-api-key: YOUR_KEY_HERE" https://api.postfa.st/social-media/my-social-accounts
Wrong — these all return 403
curl -H "Authorization: Bearer YOUR_KEY_HERE" ...
curl -H "x-api-key: YOUR_KEY_HERE" ...
-
Env var not set. If
$POSTFAST_API_KEY
isn't set in your shell, the literal string $POSTFAST_API_KEY
gets sent as the key value. Verify it's set:
echo $POSTFAST_API_KEY # Should print a 44-character base64 string ending with "="
If empty, re-export it. If you're using a
.env
file, make sure your tool actually loads it (dotenv, direnv, etc.). Shell quoting matters: use double quotes around the value if it contains special characters.
-
Regenerated key. Each time you click "Generate API Key" in PostFast settings, the previous key is permanently invalidated. Only regenerate if the old key is compromised. If you regenerated and are still using the old key, that's why it fails.
-
Wrong key entirely. Your PostFast API key is a 44-character base64 string ending with
=
. Don't confuse it with keys from other services (OpenAI sk-proj-...
, Stripe sk_live_...
, etc.).
401 Invalid or missing API key
The
pf-api-key
header is either missing from the request or the value is empty. Double-check that your HTTP client is actually sending the header (some tools strip custom headers on redirects).
429 Rate limit exceeded
You've hit the per-workspace rate limit. Check the
Retry-After-Minute
,
Retry-After-5Minutes
,
Retry-After-Hour
, or
Retry-After-Day
response header for when you can retry. Limits: 60/min, 150/5min, 300/hour, 2,000/day.
Supporting Resources
Reference docs:
- references/api-reference.md — Complete API endpoint reference with response examples
- references/platform-controls.md — All platform-specific controls with types and defaults
- references/media-specs.md — Media size, format, and dimension limits per platform
- references/upload-flow.md — Detailed media upload walkthrough
Ready-to-use examples:
- examples/EXAMPLES.md — Index of all examples
- examples/cross-platform-post.json — Multi-platform posting
- examples/tiktok-video.json — TikTok with privacy settings
- examples/tiktok-carousel.json — TikTok image carousel
- examples/tiktok-aigc-video.json — TikTok AI-generated video with AIGC label
- examples/tiktok-draft.json — TikTok saved as draft
- examples/instagram-reel.json — Instagram Reel
- examples/instagram-reel-cover.json — Instagram Reel with custom cover image
- examples/instagram-story.json — Instagram Story
- examples/instagram-carousel.json — Instagram carousel
- examples/instagram-trial-reel.json — Instagram trial reel (non-followers first)
- examples/facebook-reel.json — Facebook Reel
- examples/facebook-story.json — Facebook Story
- examples/youtube-short.json — YouTube Short with tags
- examples/youtube-video-thumbnail.json — YouTube video with custom thumbnail
- examples/pinterest-pin.json — Pinterest with board
- examples/linkedin-document.json — LinkedIn document post
- examples/x-retweet.json — X scheduled retweet
- examples/x-first-comment.json — X post with auto first comment
- examples/threads-carousel.json — Threads image carousel
- examples/batch-scheduling.json — Week of scheduled posts
- examples/gbp-standard.json — Google Business Profile standard update with CTA
- examples/gbp-event.json — Google Business Profile event post
- examples/gbp-offer.json — Google Business Profile offer with coupon code
- examples/telegram-mixed-media.json — Telegram mixed media
Quick Reference
# Auth
Header: pf-api-key: $POSTFAST_API_KEY
List accounts
GET /social-media/my-social-accounts
Schedule post
POST /social-posts { posts: [{ content, mediaItems, scheduledAt, socialMediaId, firstComment? }], status?, approvalStatus?, controls: {} }
Draft post (no scheduledAt needed)
POST /social-posts { posts: [...], status: "DRAFT", controls: {} }
List posts (page is 0-based, limit max 50)
GET /social-posts?page=0&limit=20
GET /social-posts?page=0&limit=50&platforms=X,LINKEDIN&statuses=SCHEDULED&from=2026-06-01T00:00:00Z&to=2026-06-30T23:59:59Z
Delete post
DELETE /social-posts/:id
Upload media (3 steps)
POST /file/get-signed-upload-urls { contentType, count }
PUT <signedUrl> (raw file, matching Content-Type)
then use key in mediaItems
Pinterest boards
GET /social-media/:id/pinterest-boards
YouTube playlists
GET /social-media/:id/youtube-playlists
GBP locations
GET /social-media/:id/gbp-locations
Post analytics (published posts with metrics)
GET /social-posts/analytics?startDate=...&endDate=...&platforms=...
Connect link (for clients)
POST /social-media/connect-link { expiryDays?, sendEmail?, email? }
Tips for the Agent
- Always call
my-social-accounts
first to get valid socialMediaId
values.
- For media posts, complete the full 3-step upload flow (signed URL → S3 PUT → create post).
scheduledAt
must be ISO 8601 UTC and in the future.
- Pinterest always requires
pinterestBoardId
— fetch boards first.
- LinkedIn documents use
linkedinAttachmentKey
instead of mediaItems
.
- For carousels, include multiple items in
mediaItems
with sequential sortOrder
.
- Video cover images: use
coverImageKey
in mediaItems
for IG Reels, FB Reels, Pinterest video. Use coverTimestamp
(milliseconds) for TikTok. YouTube uses youtubeThumbnailKey
in controls.
- When cross-posting, adjust content length for each platform's limits (X: 280, Bluesky: 300, TikTok: 2200, GBP: 1500).
- If the user doesn't specify a time, suggest tomorrow at 9:00 AM in their timezone.
- Batch up to 15 posts per API call for efficiency.
- Use
firstComment
for CTAs and links — keeps the main post clean and gets better engagement.
- X (Twitter) allows only 5 posts per account per day via API — warn the user if they're batching many X posts.
- For draft posts, set
status: "DRAFT"
and omit scheduledAt
— the user can finalize in the PostFast dashboard.
- GBP always requires
gbpLocationId
— fetch locations first with GET /social-media/{id}/gbp-locations
.
- GBP supports 3 post types: STANDARD (default), EVENT, and OFFER. EVENT/OFFER need start and end dates.
- GBP only supports 1 image (no video, no carousels) and has a 5-post/day limit.
- Use
GET /social-posts
with from
/to
filters to check what's already scheduled before adding more.