Sandbox Mode

Sandbox mode is a fully functional, deterministic mock of the entire OmniPost API. It exists so you can build, test, and demo your integration before your own Meta, TikTok, or X developer app has passed platform review.

Why it exists

App review for Instagram, Threads, TikTok, and X ranges from same-day to several weeks, and typically requires a working product to screen-record as part of the submission — a chicken-and-egg problem. Sandbox mode breaks that dependency: every endpoint behaves exactly like production (same request/response shapes, same status transitions, same webhook events), except nothing ever reaches a real platform. You can finish your entire integration, demo it, and only flip to live keys once real accounts are connected and your app reviews clear.

How sandbox mode is selected

Sandbox mode is inferred from the API key prefix. Any request authenticated with an op_sandbox_ key runs in sandbox mode; op_live_ runs live. POST /v1/upload also accepts an explicit "sandbox": true | falsebody field, but it must agree with the key's own mode — passing false with a sandbox key returns 403 sandbox_key_not_allowed rather than silently upgrading the request.

Deterministic mock publish responses

In sandbox mode, every target follows the same fixed timeline:

T+Target statusNotes
0spendingReturned synchronously in the POST /v1/upload response.
~1sprocessingSimulates the container-upload / polling window real platforms use.
~2–3spublished (or failed, see below)Sets a stable, fake external_url like https://sandbox.omnipost.dev/mock/{platform}/{post_id}, and fires the matching webhook event if one is registered.

Results are deterministic given the same input — the same caption, media, and platform list always produce the same target outcome, which makes sandbox mode safe to use in automated integration tests and CI.

Simulating failures

Real posting can fail for platform-specific reasons — expired containers, rejected media, rate limiting. Your integration needs to handle those paths too, so sandbox mode gives you an explicit way to force any target to fail with a specific error code.

The simulate_error field

Pass simulate_error in the POST /v1/upload body with any of the target-level error codes documented on the Errors page. Every target in the request resolves to failed with that code instead of publishing.

curl -X POST https://api.omnipost.dev/v1/upload \
  -H "Authorization: Bearer $OMNIPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Testing failure handling",
    "media": [{ "url": "https://picsum.photos/1080/1080", "type": "image" }],
    "platforms": ["tiktok"],
    "simulate_error": "platform_rejected_media"
  }'

The resulting target, once fetched via GET /v1/posts/:id:

{
  "platform": "tiktok",
  "status": "failed",
  "error_code": "platform_rejected_media",
  "error_message": "TikTok rejected the provided media (simulated)."
}

simulate_error is silently ignored on live keys — it only has an effect in sandbox mode, so it's safe to leave in a shared test fixture.

Shortcut: the magic caption prefix

For quick manual testing (a cURL one-liner, a dashboard form) where adding a JSON field is inconvenient, prefix the caption with SANDBOX_FAIL: followed by an error code. This is exactly equivalent to setting simulate_error and only works in sandbox mode; the prefix is stripped before the caption is stored.

curl -X POST https://api.omnipost.dev/v1/upload \
  -H "Authorization: Bearer $OMNIPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "SANDBOX_FAIL:platform_rate_limited Testing rate limit handling",
    "media": [{ "url": "https://picsum.photos/1080/1080", "type": "image" }],
    "platforms": ["x"]
  }'

If both an explicit simulate_error field and a SANDBOX_FAIL: caption prefix are present, the explicit field wins.

What's mocked vs. real

AreaSandbox behavior
Platform publish callsFully mocked. No network call to Instagram, Threads, TikTok, or X is made.
Account connect flowMocked hosted screen, see Connecting Accounts.
Media validationOmniPost still validates request shape (valid URL, supported type, non-empty platforms) — only the platform-side publish is mocked.
WebhooksReal HTTP deliveries to your registered endpoint, with real HMAC signatures — only the underlying event is simulated.
Rate limitsYour workspace-level plan limits still apply in sandbox, so you can test 429 handling; downstream platform rate limits are not simulated.

Use both keys side by side

Most teams keep a sandbox key wired into CI and local development permanently, even after going live, since it lets you test new code paths (including failure handling) without touching real connected accounts.