A key that starts with st_test_ is a test key. It works like a live key, with three differences:
- Recorded answers. Every endpoint answers from its recorded responses (the same recordings the docs examples
come from), never from the platform. Responses have the live schema;
meta.modeistest. - Free and deterministic. Nothing is charged:
meta.credits_chargedis 0, and the balance a test key sees is always 10,000 credits. The same request always gets the same answer. - No platform traffic. Test requests are not metered in usage reports.
Get one with the signup page (every new account has one) or, as an AI agent, from the agent signup in account and API keys.
Which answer a request gets
- A recorded input: each endpoint's page lists the inputs it has recordings for. Sending one returns that recording, success or error.
- A magic input (below): returns that error code.
- Anything else live mode would accept: returns the endpoint's docs example, with a
test_default_exampleentry inmeta.warningsnaming your input, so a test never passes on another item's data unnoticed.
Requests are validated as in live mode: a missing or out-of-range parameter, a malformed date or a link of another
kind or platform fails with invalid_input, with the same param and message. (A link on the endpoint's own
platform in a form no recording classifies gets the docs example and the warning; live mode fetches it.)
Unknown parameters, fields and deprecation work as in live mode. Lists are paged over the recorded items: cursors
start with t1., expire like the endpoint's live cursors and continue only the request that issued them;
any other cursor is invalid_cursor.
Magic inputs
Send one of these values as the endpoint's identifying parameter to get the error code, with the status, body,
details and (where the code has one) the retry-after header that live mode sends. Each endpoint accepts the
magic inputs of the codes it can return; its page lists them.
| Error code | Status | handle | query | url |
|---|---|---|---|---|
invalid_input | 400 | socialtap_test_invalid_input | socialtap_test_invalid_input | https://socialtap.dev/test/invalid_input |
invalid_cursor | 400 | socialtap_test_invalid_cursor | socialtap_test_invalid_cursor | https://socialtap.dev/test/invalid_cursor |
insufficient_credits | 402 | socialtap_test_insufficient_credits | socialtap_test_insufficient_credits | https://socialtap.dev/test/insufficient_credits |
spend_limit_reached | 402 | socialtap_test_spend_limit_reached | socialtap_test_spend_limit_reached | https://socialtap.dev/test/spend_limit_reached |
rate_limited | 429 | socialtap_test_rate_limited | socialtap_test_rate_limited | https://socialtap.dev/test/rate_limited |
not_found | 404 | socialtap_test_not_found | socialtap_test_not_found | https://socialtap.dev/test/not_found |
| 403 | socialtap_test_private_or_unavailable | socialtap_test_private_or_unavailable | https://socialtap.dev/test/private_or_unavailable | |
no_transcript | 404 | socialtap_test_no_transcript | socialtap_test_no_transcript | https://socialtap.dev/test/no_transcript |
upstream_blocked | 503 | socialtap_test_upstream_blocked | socialtap_test_upstream_blocked | https://socialtap.dev/test/upstream_blocked |
upstream_error | 502 | socialtap_test_upstream_error | socialtap_test_upstream_error | https://socialtap.dev/test/upstream_error |
overloaded | 503 | socialtap_test_overloaded | socialtap_test_overloaded | https://socialtap.dev/test/overloaded |
internal | 500 | socialtap_test_internal | socialtap_test_internal | https://socialtap.dev/test/internal |
Errors about the key itself (unauthorized, forbidden) are reached the same way as with a live key:
send no key, or a key without the scope.
Account routes in test mode
| Routes | In test mode |
|---|---|
GET /v1/account | A test key sees the fixed test balance. |
PATCH /v1/account | A test key's change is validated and answered but not stored: test mode never changes the live account. |
POST /v1/api_keysGET /v1/api_keys/{id}GET /v1/api_keysDELETE /v1/api_keys/{id}PATCH /v1/api_keys/{id} | A test key sees and manages test keys only. |
POST /v1/billing/checkout | A test key gets a placeholder session (no Stripe call, nothing to pay). |
GET /v1/credit_transactionsGET /v1/usage | A test key gets an empty report: test requests are not metered. |
GET /v1/events/{id}GET /v1/eventsPOST /v1/events/{id}/redeliver | A test key sees test events only (a test job's job.* events and webhook.test); credits.* and api_key.* events are live only. |
POST /v1/jobs/{id}/cancelPOST /v1/jobsGET /v1/jobs/{id}GET /v1/jobsGET /v1/jobs/{id}/results | A test key's job runs every item in test mode: each gets its endpoint's test-mode answer (recorded responses, magic inputs), free; nothing is held or charged. A test key sees test jobs only. |
POST /v1/webhook_endpointsDELETE /v1/webhook_endpoints/{id}GET /v1/webhook_endpoints/{id}/deliveriesGET /v1/webhook_endpoints/{id}GET /v1/webhook_endpointsPOST /v1/webhook_endpoints/{id}/rotate_secretPOST /v1/webhook_endpoints/{id}/testPATCH /v1/webhook_endpoints/{id} | A test key manages the account's test webhook endpoints, separate from live ones; they receive test events only (a test job's job.* events and webhook.test), signed and retried like live ones. |