Testing & Sandbox
PostEverywhere does not currently have a separate sandbox environment or a bulk dry-run endpoint. The strategies below let you test your integration safely without publishing live posts to your real audience.
Testing Strategies
1. Create Dedicated Test Accounts
Connect social accounts that you use exclusively for testing on each platform. For example, create a private X account, a test Instagram business account, and a test LinkedIn page. Test posts publish to accounts your audience never sees, so mistakes are invisible.
2. Schedule-Then-Delete
Create posts scheduled far in the future (e.g. one year from now), inspect them via the API, then delete them before they publish. This exercises the full create / read / delete flow without any real publishing risk:
# Schedule a post for next year
curl -X POST https://app.posteverywhere.ai/api/v1/posts \
-H "Authorization: Bearer pe_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"content": "Test post - will be deleted",
"account_ids": [123],
"scheduled_for": "2027-04-15T10:00:00Z"
}'
# Inspect the post (use the id returned above)
curl https://app.posteverywhere.ai/api/v1/posts/{post_id} \
-H "Authorization: Bearer pe_live_abc123..."
# Delete before it publishes
curl -X DELETE https://app.posteverywhere.ai/api/v1/posts/{post_id} \
-H "Authorization: Bearer pe_live_abc123..."
3. Verify Media Before Attaching
Upload media and confirm it processes successfully before using it in posts:
# Option A: One-call URL import (image-only, 25 MB cap) — returns media_id ready to attach
curl -X POST https://app.posteverywhere.ai/api/v1/media/upload-from-url \
-H "Authorization: Bearer pe_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/hero.webp"}'
# Option B: 3-step flow (for local files or videos)
# Step 1: Request presigned URL — body is JSON, NOT multipart. Required: filename, content_type, size
curl -X POST https://app.posteverywhere.ai/api/v1/media/upload \
-H "Authorization: Bearer pe_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"filename": "test-image.jpg", "content_type": "image/jpeg", "size": 524288}'
# Step 2: PUT/POST the bytes to the returned upload_url
# Step 3: POST /api/v1/media/{media_id}/complete to mark it ready
# Check status (poll until "ready") — for videos which may still be processing thumbnails
curl https://app.posteverywhere.ai/api/v1/media/{media_id} \
-H "Authorization: Bearer pe_live_abc123..."
# Response when ready:
# { "id": "{media_id}", "status": "ready", "mime_type": "image/jpeg", ... }
Only attach media to posts once the status is ready. See Media Requirements for file size and dimension limits.
4. Validate Your Payload Client-Side First
Before sending to the API, check your payload for the common mistakes that cause 400 errors:
contentis present and non-emptyaccount_idsis a non-empty array of integers (not strings)scheduled_for(if set) is a valid ISO 8601 datetime in UTC and at least 5 minutes in the future. Never usescheduled_at— it is a deprecated alias and new integrations should usescheduled_for.media_ids(if set) are UUIDs from your media uploads. The only accepted media field name ismedia_ids. Sendingmedia,media_id,mediaId, orattachmentsreturns400 invalid_field_name.timezone(if set) is a valid IANA name likeAmerica/New_York. It is display metadata only and does not affect when the post actually fires.
All field names use snake_case. accountIds, mediaIds, and platformContent are also accepted as camelCase aliases for back-compat, but snake_case is canonical.
Rate Limits Apply to All Calls
Test requests count against your rate limits. Scheduled posts (with a future scheduled_for) only count against the hourly and daily limits. Immediate posts (no scheduled_for) also count against the per-minute limit. Plan your test loops accordingly to avoid hitting rate_limit_exceeded errors.
If you are running automated test suites, add a short delay between requests:
// Simple delay between test API calls
async function testWithDelay(calls, delayMs = 1100) {
for (const call of calls) {
await call();
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
}
See Rate Limits for the full details on limits and headers.
Pinterest Sandbox
Pinterest offers a dedicated sandbox environment for API testing. If you are integrating with Pinterest specifically, you can use the sandbox to test pin creation without publishing to live boards. Contact support at [email protected] if you need Pinterest sandbox access enabled for your account.
Production Readiness Checklist
Before going live, verify each of these:
- Authentication works. Your API key returns a
200onGET /accounts. - Error handling is implemented. Your code handles 400, 401, 429, and 500 errors distinctly (see Error Handling).
- Retry logic uses exponential backoff. Retries only fire for 429 and 5xx responses.
- Rate limits are respected. You are not exceeding your per-minute limit.
- Media uploads are validated. You check that media status is
readybefore attaching to posts. - Scheduling times are in the future. All
scheduled_forvalues are at least 5 minutes ahead and expressed in UTC. - Field names are
snake_caseand canonical.content,account_ids,scheduled_for,media_ids,platform_content,timezone. Neverscheduled_at,media,media_id,mediaId, orattachments. - Round-trip works. A post you fetch via
GET /v1/posts/{id}can be POSTed back as-is (top-level fields) to create a clone. - Post results are polled. You track publishing results via Get Post Results and handle failures.
- Scopes are correct. Your API key has the minimum scopes needed (see Scopes).
Related
- Quick Start — first API call walkthrough
- Error Handling — error codes and retry strategies
- Rate Limits — request limits and headers