Sandbox Mode
API keys prefixed with sk_test_ operate in sandbox mode. The full API flow runs end-to-end, but no posts are actually published to social platforms.
Live vs. Sandbox Behavior
Sandbox mode mirrors production as closely as possible. The main difference is that posts never reach the external platform APIs.
| Behavior | Live (sk_live_) | Sandbox (sk_test_) |
|---|---|---|
| Posts hit real platforms | Yes | No |
| OAuth connects real accounts | Yes | Yes (same OAuth flow) |
| Tokens stored | Yes | Yes |
| Post status transitions | Real | Simulated |
| Webhooks fire | Yes | Yes (with test payloads) |
| Rate limits apply | Yes | Yes (same limits) |
| Usage counted toward plan | Yes | No |
Note: Sandbox uses your real OAuth connections — the tokens are real, but no posts are ever published. This means you can test the full flow without worrying about accidental posts.
What test keys never touch
The policy is simple: test (sk_test_) keys read your real account data, but never mutate a real platform or consume a shared real quota. Live (sk_live_) keys perform real actions. Here is how that plays out per endpoint:
| Action | Test key (sk_test_) behavior |
|---|---|
| Post create / retry, thread create | Simulated. The full lifecycle runs with fake platform results (see below); nothing is published. |
| Engagement reply | Returns a simulated reply with sandbox: true; the platform is never called. |
| Engagement hide / unhide | Returns a simulated result with sandbox: true; the platform is never called. |
| Feeds keyword search (threads) | Disabled. Returns the error code sandbox_unsupported because Threads search consumes the real Meta search budget shared with your dashboard. |
| Feeds keyword search (bluesky) | Available. Bluesky search is a free public read with no shared quota. |
| Analytics refresh | Returns a simulated completion with sandbox: true; no platform APIs are hit. |
| Webhook management | Allowed. Create, update, test, and delete webhooks freely with a test key. |
Simulated Post Lifecycle
When you create a post with a sandbox key, the API simulates the same status transitions that happen in production:
Immediately — scheduled
The post is created and enters the scheduled (or immediate) status
After ~5 seconds — processing
The post transitions to processing, simulating the queue pickup
After ~10 seconds — posted
The post reaches its final state with a fake postId and postUrl
Webhook events fire at each transition, so you can test your webhook handlers with realistic timing.
Example: Create a Sandbox Post
Create a post using your test key and then poll for status changes:
curl -X POST https://schedulala.com/api/v1/posts \-H "Authorization: Bearer sk_test_your_key_here" \-H "Content-Type: application/json" \-d '{"content": "Testing the Schedulala API!","platforms": [{"platform": "twitter","accountId": "acc_your_id"}],"publishNow": true}'
Check the post status after a few seconds:
curl https://schedulala.com/api/v1/posts/post_abc123 \-H "Authorization: Bearer sk_test_your_key_here"
The response will include simulated platform results:
{"success": true,"data": {"id": "post_abc123","status": "posted","content": "Testing the Schedulala API!","platforms": [{"platform": "twitter","accountId": "acc_your_id","status": "posted","postId": "sandbox_1234567890","postUrl": "https://twitter.com/i/status/sandbox_1234567890"}],"sandbox": true,"createdAt": "2026-01-15T10:30:00.000Z"}}
Simulating Failures
To test your error handling, include "simulateFailure": true in your request body. The post will go through the normal lifecycle and then transition to a failed status instead of posted.
curl -X POST https://schedulala.com/api/v1/posts \-H "Authorization: Bearer sk_test_your_key_here" \-H "Content-Type: application/json" \-d '{"content": "This post will fail on purpose","platforms": [{"platform": "twitter","accountId": "acc_your_id"}],"publishNow": true,"simulateFailure": true}'
This is useful for testing webhook failure events, retry logic, and error display in your UI.
Important: The simulateFailure flag only works with sandbox (sk_test_) keys. It is ignored on live keys to prevent accidental failures.