{"object":"sandbox","name":"0xinsider API sandbox","livemode":false,"description":"Every operation in the 0xinsider Developer API OpenAPI document except GET /api/v1/stream, with no credential and no production data. Responses are the documented examples or deterministic samples of each response schema, filled with values that are legal for the field they land in. Nothing is stored.","authentication":"none","sandbox_key":{"prefix":"oxi_sk_test_","register_url":"https://0xinsider.com/api/v1/agents/register","note":"Optional. POST to register_url for a key, with no account. On operations that require a credential, the sandbox answers a well-formed key with X-Oxi-Sandbox-Key: valid and a malformed one with the production 401; requests without it are served the same."},"base_url":"https://0xinsider.com/sandbox","api_base_url":"https://0xinsider.com/sandbox/api/v1","example_url":"https://0xinsider.com/sandbox/api/v1/leaderboard","openapi_url":"https://0xinsider.com/sandbox/api/v1/openapi.json","pagination":{"collection_rows":7,"cursor_prefix":"sbx_","example_url":"https://0xinsider.com/sandbox/api/v1/leaderboard?limit=3","note":"Every cursor-paginated list serves one fixed collection. min_grade drops the rows below it (at its documented default when the request omits it, so the holders roster lists S, A and B only), and a filter whose value a row field holds (strategy, side, timeframe, severity, cohort, status) sets that field on every row, before limit and cursor cut the page. The last page answers has_more false, with next_cursor null where the schema allows null and omitted where it is optional. A feed whose schema requires next_cursor (GET /api/v1/events/feed/since) names the end of the collection on its last page, and that cursor answers an empty page with the same cursor. Its meta describes each page: meta.replay.to_cursor equals next_cursor, and meta.completeness.status is caught_up on the empty page and complete on every other. A cursor the sandbox did not mint, or one beyond the collection, is refused with reason cursor_expired. A list without a cursor parameter answers one page. X-Effective-Query names only the parameters the sandbox applied: any other documented filter is checked and left out."},"validation":{"note":"Documented query parameters and JSON request bodies are checked against the OpenAPI document, every occurrence of a repeated name included. A value outside its schema is 400 invalid_query, a body that does not fit is 400 invalid_body, a body without Content-Type: application/json is 415, and a body over 1 MiB is 413 payload_too_large. An unknown expand value is ignored, as production ignores it.","unknown_query_parameters":"Ignored and reported in X-Query-Ignored, as production does; send X-Query-Validation: strict for 400 unknown_query_parameter."},"batch":{"note":"POST /api/v1/traders/batch and /api/v1/markets/flow/batch (and its deprecated alias /api/v1/markets/intel/batch) answer one item per posted identity, in the order posted, each carrying the condition_id posted or the trader it names: a sandbox wallet (0x51ab...) answers with its own username and figures, any other address with no username, and for traders only the sections expand asks for. An identity the sandbox cannot resolve is a per-item error, and meta counts match the items. Single-market routes (snapshot, intel, candles, holders, context.md) describe the condition_id in their path."},"mcp":{"note":"POST /api/v1/mcp answers the way the live transport does: initialize reports the live server's capabilities, serverInfo and instructions and negotiates protocolVersion against the revisions it serves, a malformed message is 400 with a JSON-RPC error object and X-Mcp-Error-Code (-32700 or -32600), an unknown method with an id is 200 with -32601, an id-less ping or notification is 202 with no body, and a response's id echoes the request's.","protocol_versions":["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],"session":"initialize answers Mcp-Session-Id: the session the request claimed, or a0b1c2d3e4f5a6b7c8d9eafbecfda0b1. The sandbox stores no session, as production stores none; a MCP-Protocol-Version header outside the revisions above is 400 with -32600, before the body is read."},"markdown":{"note":"GET /api/v1/trader/{address}/context.md and GET /api/v1/market/{condition_id}/context.md answer 200 text/markdown. Each document is rendered from the body this sandbox serves for the JSON route beside it, so the two never describe different rows.","example_url":"https://0xinsider.com/sandbox/api/v1/trader/0x51ab00000000000000000000000000000000ab01/context.md"},"downloads":{"note":"GET /api/v1/trader/{address}/export/download answers the documented 302. Location is a sample CSV this sandbox serves itself, gzip-encoded with the format's Content-Type, never an object store and never a real trade.","artifact_url":"https://0xinsider.com/sandbox/exports/trader-dataset.csv"},"simulated_errors":{"parameter":"sandbox_status","statuses":[400,401,402,403,404,423,429,500,503],"example_url":"https://0xinsider.com/sandbox/api/v1/leaderboard?sandbox_status=429","note":"Only statuses the operation documents are simulated; 429 and 503 carry Retry-After."},"not_simulated":["GET /api/v1/stream, the only documented operation without an answer here","stored state between requests"],"production_base_url":"https://api.0xinsider.com","docs_url":"https://0xinsider.com/llms-full.txt"}