Every shipped change that a caller can see: a new service in the catalogue, a data set the live hosts rolled to, a wave of pinned snapshot hosts, or a client library we now prove works. Newest first.
Watch it from your reader: the Atom feed. Nothing below is announced before it ships.
The live hosts cut over to hello-23, which added eight small domains to the data set. Sentry: every project's client key and DSN, built on the host you call. GitHub: sub-issues and parent issues, the Actions cache retention and storage limits, and the event behind each recorded webhook delivery. GitLab: related epics, award emoji on epic notes, and a hook's recent events. Linear: an issue's parent and children. Azure DevOps: a task's parent user story in the work item hierarchy. Antigravity: the organization's webhook registration. Datadog: one DORA deployment per service a production deployment actually changed. The reseed moved every live host's rows; the pinned -g12 hosts did not change.
The live hosts cut over to hello-22, which added distributed traces to the data set: the calls between its six services, the thirteen Linux hosts they run on, and about 6,600 sampled traces with their spans over the 90 days. A trace's duration follows the same service's latency series, error traces follow its error rate, and every sampled error event links to the trace that carried it. No host serves these yet. The reseed moved every live host's rows; the pinned -g12 hosts did not change.
grafana.sandboxapis.dev serves the Grafana HTTP API of Grafana OSS 13.2.4 over this data set: a folder per team, a dashboard per service with a panel per metric series, and one Prometheus data source that is the Prometheus host, so a panel's query, the resource API and the data frames all return its series. One alert rule per monitor, with every state change an annotation at the instant the incident opened and closed, plus the users, teams and server stats. mcp-grafana works with GRAFANA_URL set to the host and any service-account token. The data ends at 00:00 UTC today, and now-relative ranges resolve there.
api.dd.sandboxapis.dev served the Datadog API, v1 and v2, over the same data set: a monitor for every alerting rule, metric queries over the trace metrics with the same spike PagerDuty and Sentry report, monitor events, downtimes, incidents, on-call schedules, users, teams, keys and error logs. Traces and spans came from hello-22: one trace per service every two hours, one every five minutes on the incident's service during the incident, and one for every recorded error, whose failing span carries the same error the Sentry issue shows. The thirteen hosts the services run on were listed with their service, team and tier tags. The whole published API was counted, and every read is classified: served, empty because the data set never configured that product, Datadog's own 404, or not yet covered. The host is api.dd. because Datadog clients build their host from a site.
prom.sandboxapis.dev serves the Prometheus HTTP API v1 over this data set's services: latency, request and error counters, the error ratio and CPU as Prometheus series, a PromQL subset that evaluates them, and one alerting rule per monitor, with ALERTS marking exactly when each canon alert fired and resolved. The spike is the one PagerDuty and Sentry serve the incident for. The data ends at 00:00 UTC today, and a query with no time is evaluated there.
The live hosts cut over to hello-21, which added agent runs to the data set: the Antigravity agent's sessions, its scheduled triggers and their executions, and the environments and credentials those runs use, served on antigravity.sandboxapis.dev in the Gemini Interactions API's shapes. A run tied to a pull request names the same pull request and Jira issue the git hosts and the tracker already serve. The reseed moved every live host's rows; the pinned -g12 hosts did not change.
Every week we compare each replica with the vendor's own published spec, and the result is now a public page at /api-drift. Each report says, per provider, what the vendor retired that our live host still served, which specs we re-pinned, which new read endpoints are not served yet and which sources could not be checked, with every item marked done or open. A new report appears on the page in the build that merges it.
A key with scratch writes turned on can now call chat.postMessage against a channel that already exists in the data set, by id or by name, with an optional thread_ts, and gets Slack's own success envelope back: ok, the channel, the minted ts and the complete message object. For 24 hours that key's conversations.history and conversations.replies include the message, merged before the cursor pager so has_more and next_cursor stay right, and a reply moves its parent's reply_count, reply_users and latest_reply. The message is authored by a member of that channel, blocks are stored as sent and echoed back, text over 40,000 characters is Slack's own msg_too_long, and a full allowance answers Slack's 429 with a Retry-After. search.messages does not include scratch messages yet and says so in a header. Slack scratch creates no channels, the GitHub and Jira writes are unchanged, and anybody calling without a scratch key gets exactly the bytes they got before.
A key with scratch writes turned on can now post a comment on a Jira issue and move it through the workflow, and read both back for 24 hours: POST /rest/api/3/issue/{key}/comment answers 201 with Jira's own comment object, POST /rest/api/3/issue/{key}/transitions answers 204, and the thread, the inline comment field, the issue's status and resolution date, and GET /transitions all reflect the change for that key alone. The GitHub issue writes from September are unchanged, and the two now share one contract. Jira scratch creates no issues, JQL search and the changelog do not include scratch rows yet and say so in a header, and anybody calling without a scratch key gets exactly the bytes they got before. Separately, every read-only refusal now links /coverage directly instead of the /roadmap redirect.
The MCP server now ships as a Cursor plugin in the public examples repository, in Cursor's own plugin format: the server entry, a rule that teaches the agent to call orient first, check_budget before a loop, pin a snapshot host for anything it will assert, and read a write refusal or a coverage 404 as an answer rather than an error to retry, and a skill that runs the answer-key eval pack and reads the score. An Add to Cursor link on /docs/mcp installs the server in one click and carries no key, and a fifth tutorial at /docs/tutorials/cursor walks from that click to Cursor's agent tracing one incident across the pinned Slack, Jira and GitHub hosts. The rule's tool list is checked against the server's source on every build.
A new page at /docs/evals hands you a downloadable file of 53 known facts about the olympus-labs data set across GitHub, Jira, Slack, GitLab and Linear, each one carrying the request that answers it and the value the answer has to be. Every host it calls is a pinned snapshot, so the same question returns the same answer on every run, and every item cites the test in our own repository that would fail if the answer changed. Two harnesses come with it, one Python and one Node, each under sixty lines and each caching by request so a full run costs twelve requests rather than one per item. Both read the answer out of the response by default, which scores the data set; replacing one function with a model call is what turns the same file into an eval of your agent.
A fourth page under /docs/tutorials is written for the reader who builds the tool server rather than the agent that calls it, who until now had no upstream to test against at all. It points github/github-mcp-server 1.12.2 at a pinned GitHub replica by setting GITHUB_HOST and nothing else, drives it with a sixty-line Node client over stdio, and asserts what two of its tools said about one pull request, including that both of them report the same commit for its head branch. It also shows, captured from a real session, what a write tool gets back from a read-only host, and it says plainly which part of the fault-injection header this particular server cannot reach and why.
Five pages under /compare weigh SandboxAPIs against the alternatives a reader actually chooses between: mocking libraries, the vendors' own developer sandboxes, record-and-replay tools, the simulated twins other companies now sell, and a run-it-yourself page that asks a spec-derived mock of GitHub and one of our pinned hosts the same seven questions and prints both answers. Each opens by saying what the other approach is genuinely better at, scores eight to ten dimensions with an honest cell in our own column, and cites every claim about somebody else's product to that product's own documentation with the date it was read. Two pages carry a note saying what we could not verify and left out. /blog opens alongside them with the launch post.
Every service's quickstart page gained a download row. The Postman v2.1 collection carries one request per served read endpoint, foldered by area, with that provider's own auth header set as the collection auth and baseUrl and apiKey as variables; beside it sits a minimal OpenAPI 3.1 file whose servers block is already our host. Both are generated from our own coverage manifest rather than from a vendor's spec, so they can only describe what we actually serve: 2,353 read requests across the 21 collections. A table on the docs index lists all 42 files.
A caller with a key can now ask any host for a failure on demand. Five faults: rate-limit, which answers with that provider's real over-limit response through the same code path a genuine refusal uses; server-error at 500, 502, 503 or 504 in the provider's documented error envelope; timeout; latency; and the read-only refusal, on a GET. An out-of-range value is refused with a 400 naming the grammar rather than quietly clamped, a substituted response costs no request budget, and every one of them carries an X-SandboxAPIs-Simulated header. Pinned hosts accept the header and stay byte-identical without it.
Three walkthroughs point a Python agent at a pinned GitHub, Jira or Slack host, have it answer one question about a real incident, and assert the answer in five lines of pytest. Every script on those pages is compiled and run by CI, so none of them can claim output nobody produced. The hosts are pinned snapshots, which is what makes an assertion in a test suite safe to keep.
Every one of the 21 services gained a pinned snapshot host on the newest data set, registered and pinned in the same change, taking the registry to 148 hosts with none left unpinned. All 21 hosts serve one byte-identical artifact, so a Jira pin and a GitHub pin are two dialects of the same story rather than two data sets that happen to agree. Point CI at a -g12 host and it returns the same bytes in a year. The MCP package shipped as 0.3.13 carrying the new registry.
The live hosts cut over to hello-20, the largest single step the data set has taken. Thirteen domains landed together, among them package registries, repository rules, CI runners and CI policy, board configuration, watch graphs, billing periods, resource events and audit actors, alongside 199 rulings that closed rows the sandbox will deliberately never invent. Coverage across the fleet reached 97% of every published read surface, with ten services answering their whole read surface.
The quickstarts page carries snippets for ten real client libraries, each executed against the live hosts by a check that fails unless what it prints is the olympus-labs data set. Both Azure DevOps SDKs and the Jira board filter joined the same day, after the discovery request the official Python SDK sends was served and board filters were honoured. A snippet that stops working stops being published.
CI secret and variable NAMES became part of the data set, so GitHub Actions, Dependabot and Codespaces secrets, GitLab CI variables, Bitbucket pipeline variables and Devin organization secrets all list what a pipeline is given. No value is ever returned, because no secret exists to return. GitHub's coverage badge crossed into Deep for the first time on the back of it.
Four domains landed in one generation. Repository and organization webhooks on GitHub, GitLab and Bitbucket now carry the events they subscribe to, Jira filters and Azure DevOps saved queries answer along with WIQL by id, attachments hang off more parents than issues alone, and directory identities resolve on GitLab. Every stored query was proven to run on its own host before it was published.
The caller's keys and tokens, epic notes and discussions, approval rules, follows, issue links and relations, CODEOWNERS and the folder README, team grants and default reviewers all became part of the data set in one generation. GitLab, GitHub, Bitbucket, Linear, Jira and OpenAI each gained rows from it. This was the first of four cutovers in three days.
Twenty-one pinned snapshot hosts were registered on the newest data set and pinned in the same wave, leaving no unpinned host in the registry. Pinned means content-addressed: the artifact behind a pin is verified against a recorded sha before it is served, so a pinned host cannot quietly change under a test suite.
Organization and team memberships, invitations and a role catalog became part of the data set, along with 64 credentials whose last use and expiry derive from the event log rather than being invented. Sixteen vendor reference catalogs started serving from the artifact, covering licences, ignore templates, API versions, hosted runners, Jira project types and more. Every repository gained a LICENSE file, and the plan gained one level of depth plus a subgroup that owns no repository.
The canon-gap generation reached the live hosts: CI configuration, avatars and reactions, the founding order and the two subscription facts the generator had never produced. CircleCI and Buildkite answer their configuration surfaces from it, and reactions resolve on the git hosts and the trackers alike. Twenty-one pins were registered on it the same day, so every service had a snapshot host carrying the new data set within hours of it going live.
Statuspage serves the outage as customers were told about it: incidents, their updates, components and the page they were published on, all derived from the same incident canon Sentry and PagerDuty read. Its spec was published inside a documentation page rather than as a spec file, so it is pinned to bytes that hold still. Statuspage is the twenty-first read-only replica.
Two build services began serving over CI canon that had existed since the second generation, including a build's real job log rather than a description of one. CircleCI went on to answer its whole read surface three days later. Buildkite serves agents, builds and annotations, and refuses the vendor's own emoji catalogue rather than republishing somebody else's licensed data.
The outage finally reached the support queue. Zendesk serves the desk itself, with tickets, users, macros, views, triggers and an audit trail; HubSpot answers its whole read surface over the same CRM canon; Salesforce serves its sObject core with bounded SOQL that refuses an unsupported query by name instead of guessing at it. Salesforce is the thinnest service in the catalogue and the coverage page says so rather than hiding it.
The 0.3 line of @sandboxapis/mcp taught the published package every service and every pinned snapshot host, so an agent can pick a pinned universe without being told one. CI fails the build if the package's provider list or pin registry drifts from what the hosts actually serve, which is what stopped the published package advertising fewer services than the product had. Later releases in the line added the rate-limit budget to tool results and the orientation copy an agent reads first.
An incident domain landed, so the outage is derived from the event log rather than invented per service. Sentry serves issues and events whose stack traces point at files that exist in the repositories; PagerDuty serves the page that went off, who answered it, and what they did next. Both are about the same afternoon as the Slack thread, the Jira ticket and the pull request that fixed it.
A paid tier for one developer, at $5 a month or $50 a year. It buys rate limit and nothing else: every endpoint and every field is in the free tier, and anonymous access with no account stays free.
Channels, threads and messages became part of the data set, and two services render them. Slack's inverted dialect and the Microsoft Graph teamwork slice tell byte-identical stories, so the same incident thread reads correctly in either client. This is the hop that makes the four-vendor walk on the front page possible.
The OpenAI Platform organization surface arrived from the vendor's own published spec, followed the same day by Codex Analytics. Both project the same simulated engineering work the git hosts already serve, so a model's usage and the commits it helped produce are about one company rather than two unrelated fixtures.
The ninth service, built against the vendor's published v3 API, serving session and enterprise reads over the same engineering story the git hosts tell. Eight endpoints that would have needed invented data are refused by name instead, each with a reason on the coverage page.
The Anthropic Admin API surface, covering the organization, usage and cost reports and Claude Code analytics, plus Cursor's team admin, analytics, AI code tracking and cloud-agent reads. Both are derived from the same simulated engineering work the git hosts serve, so a usage report and the pull requests behind it agree.
A planning domain of sprints, epics and workflow transitions landed, and two trackers render it. Jira serves bounded JQL search, boards, sprints, changelogs and ADF comments; Linear serves a GraphQL schema subset with matching issue identifiers and branch names. The ticket a GitHub pull request closes is the same ticket in either tracker.
Two more git hosts, each in its own REST dialect. Bitbucket Cloud 2.0 serves workspaces, repositories, pull requests, pipelines, deployments and environments; Azure DevOps 7.1 serves git, pull requests, builds, graph identities and Boards including WIQL. The same commits at the same SHAs as GitHub and GitLab, because all four read one compiled artifact.
A Model Context Protocol server over the public API, published to npm as @sandboxapis/mcp and installed in one line. It gives an agent discovery and query tools instead of documentation to read. Calling orient first returns the hosts, the company, the entry points and how to pin a snapshot, so the next call is a correct one.
SandboxAPIs opened with GitHub's REST and GraphQL surface and GitLab's v4 REST and GraphQL surface, both served from one compiled data set. A pull request on GitHub and its merge request on GitLab are two renderings of the same object, down to the head SHA. Responses are validated against each vendor's own published spec on every CI run, and anything not covered answers a provider-shaped 404 rather than a made-up value.