Agent Guardrails
Automated clients (MCP agents, n8n flows, SDK scripts) retry, loop and run unattended. The PostBoost API protects your accounts from the two mistakes that get social accounts flagged: duplicate posts and runaway volume. These checks apply to API requests only; posts made in the dashboard are not affected.
Recommended loop
- Check the accounts —
GET /{workspaceUuid}/account-health - Dry run —
POST /{workspaceUuid}/posts/validatewith the exact create-post body - Create —
POST /{workspaceUuid}/postswith anIdempotency-Key
Account health
GET /{workspaceUuid}/account-health returns, per account, whether it is authorized, whether it holds an access token (has_token), healthy (both), and its daily cap (limit, used_today). An account that is not healthy must be reconnected in the dashboard before it can publish.
Dry run
POST /{workspaceUuid}/posts/validate takes the create-post body and creates nothing. It always answers 200:
{
"valid": false,
"errors": { "versions.0.content.0.body": ["The text may not be longer than 280 characters for X."] },
"issues": [],
"publish_at": "2026-10-12T10:00:00+00:00",
"accounts": [ { "id": 12, "provider": "twitter", "healthy": true, "daily_cap": { "limit": 50, "used_today": 3 } } ]
}
errors— the validation errors create-post would return as422. Network requirements (text length, media count and type, links) are checked for every account, even for drafts.issues— guardrail problems (below) create-post would refuse.
Viewers can call it too.
Idempotent retries
Send Idempotency-Key: <unique string> (a UUID works) with any POST. Repeating the request with the same key within 24 hours returns the stored response with the header Idempotent-Replayed: true and creates nothing.
| Situation | Response |
|---|---|
| Same key, same body | Stored response, Idempotent-Replayed: true |
| Same key, different body | 422 |
| Same key while the first request is still running | 409, Retry-After: 1 |
| Key longer than 255 characters or not printable ASCII | 400 |
First attempt returned 5xx or 429 | Not stored — retry with the same key |
Keys are scoped to your user, the workspace, the method and the path.
Duplicate guard
Create and update requests are refused with 409 when the content for an account matches a post created for that account in the last 24 hours (case, spacing and media order are ignored):
{
"message": "A post with the same content for this account was created in the last 24 hours. Send \"allow_duplicate\": true to post it anyway.",
"code": "duplicate_post",
"account_id": 12,
"existing_post_uuid": "9f2c1b7e-4a51-4d0e-9a51-6b7d9f0e2c11"
}
To post it anyway, add "allow_duplicate": true to the body or send the header X-Allow-Duplicate: true.
Daily caps
Scheduling (schedule, schedule_now or queue) is refused with 429 when an account already has its daily number of posts on that UTC day (scheduled, awaiting approval or published). Drafts are never capped.
{ "message": "…", "code": "account_daily_cap_reached", "account_id": 12, "limit": 50, "used": 50 }
| Network | Posts per UTC day |
|---|---|
| X | 50 |
| 25 | |
| Facebook Page | 50 |
| Threads | 50 |
| LinkedIn (profile) | 20 |
| LinkedIn Page | 50 |
| TikTok | 15 |
| YouTube | 10 |
| 50 | |
| Bluesky, Mastodon | 100 |
| Google Business Profile | 10 |
| Other networks | 50 |
These are not rate limits: rate limits cap requests per minute, caps cap posts per account per day.
Accounts that cannot publish
Scheduling to an account that must be reconnected returns 422 with code: account_unauthorized (or account_token_missing) right away, instead of failing later at publish time. Drafts for the account are still allowed.
Activity log
GET /{workspaceUuid}/activity lists every write request (POST, PUT, DELETE) made through the API in the workspace, newest first, with its outcome: created, updated, deleted, validated, replayed, blocked_duplicate, blocked_cap, blocked_unauthorized, validation_failed, error or ok. Filter with outcome, client and since. Entries are kept for 90 days.
Label your requests with an X-PostBoost-Client header (for example my-agent/1.2); otherwise the User-Agent is recorded.