Point the official openai SDK (or curl) at https://openai.sandboxapis.dev via the client's baseURL option. Auth is a Bearer admin key (sk-admin-… — any value is accepted here). This is the org's OpenAI platform telemetry: users, projects, admin-key metadata, completions usage, and costs — the codex cohort's usage, reconciling with the git activity on the git hosts.
Coverage badge
Deep113/122 · 93%
The share of read rows with a final answer — served and verified, a deviation, retired upstream, or a reviewed empty/refusal. Computed in the coverage manifest, copied here.
openai.sandboxapis.devServed & verified
44 / 36%
Answering with real universe data, each response checked against OpenAI's published spec by the conformance suite on this build.
The full read API
122
Every read surface OpenAI publishes, deferred long tail included, minus the rows excluded by policy. Writes are out of scope: this universe is read-only.
Not served yet
78
Each returns an explicit, provider-shaped coverage error naming the gap — never invented data.
01 / The swap
No SDK of ours, no shim, no recorded fixtures. The same client library you already use, one environment variable different.
curl -H 'Authorization: Bearer any-key' "https://openai.sandboxapis.dev/v1/organization/users"Verified drop-in clients
openai7.5.0The versions the conformance suite drives against this host on every build — pinned in coverage/client-pins.yaml, and watched weekly for upstream releases, because a client library moving without us is how a shipped integration breaks silently.
02 / Coverage by family
All 122 rows the coverage manifest carries for OpenAI, deferred long tail included and nothing capped. Open a family, or filter by path to find the exact endpoint your client calls.
Status — what a conformance test found
Mode — what kind of answer a row gets
A row with no mode shown has not been judged yet. Modes are the manifest's own words, from coverage/MODES.yaml; every empty and refuse carries a written reason and a review date before it counts as final.
Badge — where Deep starts
REST + GraphQL + git rows that are not `excluded`. Write operations are NOT rows (DECISIONS 2026-09-01 decision 9): they are counted in meta.write_operations and never enter this ratio.
122 read surfaces in 14 families
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the vendored document declares security: [{AdminApiKeyAuth: []}] on retrieve-project-hosted-tool-permissions - the SAME scheme as /organization/users, /organization/costs and the sibling /organization/projects/{project_id}/model_permissions this replica serves at 200 - so the sandbox admin key IS the right credential here and a 401 invalid_api_key would contradict the document; this org configures no hosted-tool permission set, so OpenAI's own 404 for an object that does not exist is the answer, the same shape as /organization/certificates/{certificate_id} (founder ruling 2026-09-03 on proposal 1 of coverage/reviews/2026-09-03-openai-refuse-shapes.md, superseding the INFERENCE-plane 401 read that grouped this row by its "Hosted tools" tag rather than by its plane)
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
refuse — the sandbox key is an OpenAI ADMIN key and this row is on the INFERENCE plane (assistants, threads, responses, files, batches, evals, fine-tuning, vector stores, skills, videos, conversations, audio consents); OpenAI answers 401 invalid_api_key when an admin key reads it, and SandboxAPIs mirrors the admin surface, not the inference surface
this org's OpenAI story is coding: it recorded no speech usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no transcription usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no code-interpreter usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no embedding usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no file-search usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no image usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no moderation usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no vector-store usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
this org's OpenAI story is coding: it recorded no web-search usage in the window, so the family's page is real, spec-validating and empty (DECISIONS 2026-08-20 [P31/openai])
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
refuse — the same inference plane as the tagged platform rows — chatkit threads and code-interpreter containers only read as separate here because the spec leaves their tag empty; an OpenAI admin key gets 401 invalid_api_key for them too
generate — new canon entity SpendAlert, hung off the Subscription the A15 wave lands
generate — new canon entity SpendAlert, hung off the Subscription the A15 wave lands
SERVED 2026-09-10 (hello-15): canon's IdentityGroup — reader.listIdentityGroups(org) (reader.ts:2472) — in the vendored GroupListResource envelope. A GROUP IS NOT A TEAM and this reads neither a team nor a roster: the generator builds each group out of an access fact canon already records (everyone who writes code, everyone who has reviewed something, everyone who may cut a release, the machine accounts) and the canon suite asserts no group has exactly a team's membership, which groups.test.ts re-asserts over the served rows. `is_scim_managed` is the FEDERATION's fact, read off IdentityProviderConfig.scim_enabled, so every group this provider asserts reports the same value. `group_type` is `group` and never `tenant_group`: a tenant group belongs to an OpenAI enterprise tenant standing above the organization, and these are asserted by the organization's own provider. The id is openaiId("group_", "idgroup-00N") — the same fnv-1a derivation user-/proj_/key_ ride, so it is a pure function of the canonical id rather than a counter over an iteration order. Older pins answer the noIdentityGroups generation-gap 404 naming openai-2020-10-g10, never an empty list
SERVED 2026-09-10 (hello-15): the same IdentityGroup by id, byte-identical to the row the list publishes — conformance asserts every group both ways. GroupResponse carries NO `object` field and spells the flag `is_scim_managed`; the document's `Group` schema (the summary embedded in a role assignment) carries `object: "group"` and `scim_managed` instead, and these two operations return GroupResponse. A canonical `idgroup-00N` does NOT address a group here, which conformance asserts too
SERVED 2026-09-12 (hello-17): the ORGANIZATION role an identity group holds, from the `scope_kind = 'group'` membership hello-17's features.grants writes — reader.groupRole(group) — in the vendored RoleListResource envelope. ONE ROW OR NONE, and that is canon's shape rather than a slice taken in the renderer: a group's role is the FLOOR of its members' own authority, because a grant to a group reaches everyone in it and granting more than its least-authorised member already holds would elevate that person through the directory, so canon writes exactly one row per group (decisions/2026-09-11-2304-hello-17-grants.md). The objects are the SAME AssignedRoleDetails under the SAME ids the user assignments publish — one catalog, two kinds of principal — which groups.test.ts asserts directly, because a schema cannot. Paged by the Roles API's own bounds: list-group-role-assignments declares no limit default and no order default, exactly as list-user-role-assignments does not, so both take 0..1000 / default 1000 / order asc from list-roles. hello-16 and every older artifact answer the noGrants generation-gap 404 naming generation hello-17 — never an empty list, which would be a claim about the ORGANIZATION rather than about the snapshot the caller pinned (the 2026-09-02 ruling). FOUNDER RULING 2026-09-10, round 13
SERVED 2026-09-12 (hello-17): the same assignment by id, byte-identical to the row the list publishes — conformance asserts every group both ways. A REAL catalog role this group does not hold misses here too, the way it does for a user one route over: which role is held is the question the route answers, and a group holds exactly one. The by-id half was PROPOSED as a `refuse` on the reading that no role id could ever resolve for a group; hello-17's grant makes exactly one resolve per group, so the proposal is withdrawn rather than ruled and this is a `derive` like its list. FOUNDER RULING 2026-09-10, round 13
SERVED 2026-09-10 (hello-15): a group's canonical members (IdentityGroup.members) INTERSECTED with this organization's own roster, in the vendored UserListResource envelope. THE INTERSECTION IS THE JUDGMENT AND IT IS THE ONLY COHERENT ONE: an OpenAI organization user on this replica is a codex seat holder (renderer-openai/src/render.ts members()), canon's group rosters are rosters of PEOPLE, and serving a person with no account here would publish a user id that 404s against /organization/users/{user_id} standing right beside it — invariant #5 broken in one response pair. OpenAI's own question is which USERS are assigned to the group, and a person with no account is not one of its users; the same reading /v3/enterprise/members/service-users takes on Devin. NOTHING IS HIDDEN, because no shape here publishes a member count: GroupResponse is {id, name, created_at, is_scim_managed, group_type} and carries neither a size nor canon's description. Two of the four groups therefore list nobody, which is DATA rather than a mode — the Default project lists no API key for the same kind of reason — and conformance asserts the served set equals the intersection FROM BOTH SIDES, so a widening and a narrowing are both red. `order` defaults to DESC here and asc on every sibling, which is the document's own default. Older pins answer the noIdentityGroups generation gap
SERVED 2026-09-10 (hello-15): the same membership addressed by (group, user), in the vendored GroupMemberUser shape — the list item plus three fields. A real organization user who is NOT in this group misses here too, because group membership is the question this route answers. `picture` is null because nothing in this universe is a profile-picture URL: canon holds identicon bytes for an org and a repo and nothing keyed to a person, and an authored URL would resolve nowhere (invariant #4). `is_service_account` READS person.is_bot rather than being hard-coded, so it follows rather than being asserted; it is false for everyone this route can reach today because canon's only non-human identity is the CI bot and it holds no codex seat. `user_type` is `user` and never `tenant_user`, for the reason group_type is never tenant_group
no identity group has access to a project, and no generation of this universe grants one. The vendored summary on list-project-groups is "Lists the groups that have ACCESS to a project" and its item, ProjectGroup, is a GRANT object (object + project_id + group_id + group_name + group_type + created_at) rather than a group — so this list can only carry rows canon does not have. hello-17's features.grants writes one `scope_kind = 'group'` membership per identity group, which attaches the group to a ROLE; IdentityGroup itself carries an org, a provider, a name slot, a member list and a creation instant and nothing that names a container, and a project on this host is minted per TEAM holding a codex seat (renderer-openai/src/render.ts projects()) with no group on either side of it. UNGATED BY GENERATION, deliberately: a generation gap would say the caller's snapshot is too old to answer where the true statement is that the answer is the same on every snapshot there is. The project still has to resolve — a ruling about a project nobody has is a typo answered confidently — and the bounds validated are this operation's own (limit 0..100 default 20, order default asc), which differ from every sibling's. FOUNDER RULING 2026-09-11, round 17
refuse — the id half of the project-groups pair: its list is empty because no identity group has access to a project, so no (project, group) grant can resolve and OpenAI's own 404 is the only possible answer — the certificates/invites shape ruled 2026-09-01. It addresses a ProjectGroup (the grant) and not a Group, so there is nothing for {group_id} to resolve against and a REAL group id misses here exactly as an invented one does, which is the ruling rather than a gap. Parent-guarded (the project resolves first) and ungated by generation, for the reason the list carries. FOUNDER RULING 2026-09-11, round 17
refuse — NOT the project-scoped twin of /organization/groups/{group_id}/roles, and the difference is what decides the mode: this one is scoped BY a group's access to a project, and /organization/projects/{project_id}/groups is `empty` because no identity group has that access in any generation (founder ruling 2026-09-11, round 17). So the (project, group) pair never resolves and OpenAI's own 404 is the only possible answer — the same reading /projects/{project_id}/users/{user_id}/roles already takes one route over, where a person who is not in the project misses rather than getting an empty list. hello-17's features.grants attaches a group to an ORGANIZATION role, which /organization/groups/{group_id}/roles serves; it attaches nothing to a container. The refusal names the GROUP and not the role, because the group's access is the first thing that fails and the request never reaches a role. Parent-guarded (the project resolves first) and ungated by generation, for the reason the project-groups pair carries. FOLLOWS FROM FOUNDER RULING 2026-09-11, round 17
refuse — the id half of the project group-roles pair: its list refuses because no identity group has access to a project, so the (project, group) pair never resolves and no role id under it can either — OpenAI's own 404, naming the group rather than the role for the reason the list gives. Same guard, same ungating, same ruling. FOLLOWS FROM FOUNDER RULING 2026-09-11, round 17
an empty DENY list — no model is denied, which is exactly a universe with no restriction evidence; an empty ALLOW list would claim no model may be called, which the usage report disproves (DECISIONS 2026-08-20 [P31/openai])
these are policy NUMBERS and this org configures no override; any figure printed here would be a placeholder copied off the spec's example, which invariant #4 forbids. The empty list says 'no override configured' (DECISIONS 2026-08-20 [P31/openai])
the canon's only non-human identity is the CI bot: it holds no codex seat, belongs to no team and produced no OpenAI usage, so nothing here is a project-scoped machine identity (DECISIONS 2026-08-20 [P31/openai])
refuse — the id half of the service-account pair: /organization/projects/{project_id}/service_accounts is `empty` because the CI bot is not a project-scoped machine identity, so no service-account id can resolve and OpenAI's own 404 is the only possible answer (DECISIONS 2026-09-01 [coverage/A0]). The refusal suite owns this row: its OPENAI_ENDPOINTS expectMiss entry was removed 2026-09-03 (founder ruling on proposal 2 of coverage/reviews/2026-09-03-openai-refuse-shapes.md) because it made a refuse row read `green`, and a refusal is terminal by mode, never green by status
SERVED 2026-09-10 (hello-16): reader.listMembershipRoles() (packages/artifact/src/reader.ts:3042) in the vendored PublicRoleListResource envelope. Five catalog ROWS rather than an enum rendered at request time: `Role.permissions` is REQUIRED, and a permission list composed inside a renderer is a fact invented at serving time. `permissions` stays canon's closed `scope:level` vocabulary, which the schema types `array<string>` with no enum; `resource_type` is `api.organization`, the document's own example for this scope; and `predefined_role` is DERIVED — a role minted at the organization's own creation instant was created by nobody in it, which conformance asserts as a biconditional rather than as the current answer
SERVED 2026-09-10 (hello-16): the same catalog row by id — reader.listMembershipRoles() (reader.ts:3042) addressed by openaiId("role_", …), byte-identical to the row the catalog serves, which conformance asserts for all five. An id the catalog does not carry is OpenAI's own `Role <id> not found`, never the empty-body coverage miss
SERVED 2026-09-10 (hello-16): the role on this person's ACTIVE organization membership — reader.listMemberships("org", org) (reader.ts:3020) — rendered as the catalog row it names, in the vendored RoleListResource envelope. A pending membership is an invitation and is not an assignment, which is the only place that distinction could have been lost. The four nulls are facts: canon records no edit to a catalog row (`updated_at`), no author for one (`created_by`), and every assignment is held directly rather than inherited (`assignment_sources`)
SERVED 2026-09-10 (hello-16): the same assignment addressed by (user, role) — reader.listMemberships("org", org) (reader.ts:3020). A REAL catalog role this person does not hold misses here too, because which role you hold is the question this route answers; conformance drives both halves
SERVED 2026-09-10 (hello-16): the same reader.listMembershipRoles() catalog (reader.ts:3042) at project scope — `resource_type: api.project`, the document's own example for this scope, under ids of its own because OpenAI addresses an organization role and a project role as different objects. Same name, same description, same permissions, same created_at as the organization row, which conformance asserts; an organization role id does NOT address a project role, which it asserts too
SERVED 2026-09-10 (hello-16): the project catalog row by id — reader.listMembershipRoles() (reader.ts:3042). The project must still resolve, so an unknown {project_id} is OpenAI's own `Project <id> not found` rather than a cheerful empty catalog
SERVED 2026-09-10 (hello-16): the role on this person's membership in the container the PROJECT IS — reader.listMemberships("team", team) for a team project and reader.listMemberships("org", org) for the Default project (reader.ts:3020), since a project here is a team holding a codex seat and Default is the organization's own project. One rule, total over every project this renderer mints, which is why an assignment can never name somebody outside the container; a user who is not in the project misses rather than getting an empty list
SERVED 2026-09-10 (hello-16): the same project assignment addressed by (project, user, role) — reader.listMemberships over team and org scope (reader.ts:3020). Byte-identical to the row the list serves, and a role the person does not hold in THIS project is OpenAI's own 404
generate — new canon entity SpendAlert, hung off the Subscription the A15 wave lands
generate — new canon entity SpendAlert, hung off the Subscription the A15 wave lands
generate — new canon entity SpendAlert, hung off the Subscription the A15 wave lands
generate — new canon entity SpendAlert, hung off the Subscription the A15 wave lands
OpenAI answers {"data": []} to an admin key for the org certificate list when no mTLS certificate has been uploaded, and this org uploaded none — refusing would be false to the provider
OpenAI answers {"data": []} to an admin key for a project certificate list when no mTLS certificate has been uploaded, and this org uploaded none — refusing would be false to the provider
refuse — the id half of the certificate pair: this org uploaded no mTLS certificate, so no certificate id can resolve and OpenAI's own 404 is the only possible answer (the by-id shape ruled in DECISIONS 2026-09-01 [coverage/A0] for the invite and service-account rows)
generate — new canon entity RetentionPolicy
generate — new canon entity RetentionPolicy
every member of this org accepted; no invite is pending (DECISIONS 2026-08-20 [P31/openai])
refuse — the id half of the invites pair: /organization/invites is `empty` because every member already accepted, so no invite id can resolve and OpenAI's own 404 is the only possible answer (DECISIONS 2026-09-01 [coverage/A0]); `derive` was the wrong word for that answer. The refusal suite owns this row: its OPENAI_ENDPOINTS expectMiss entry was removed 2026-09-03 (founder ruling on proposal 2 of coverage/reviews/2026-09-03-openai-refuse-shapes.md) because it made a refuse row read `green`, and a refusal is terminal by mode, never green by status
generate — A WIDENING, NOT A BUILD: canon.AdminAuditEvent exists (packages/canon/src/support-desk.ts:690) and its own doc comment calls it "GENERIC by construction". The action vocabulary (AuditAction, :602), the change vocabulary (AuditChangeSlot, :633), the target vocabulary (AuditTargetKind, :611) and the RFC 5737 source-address rule (AuditSourceBlock, :652) all shipped, and Zendesk serves the table today (reader.listAuditEvents(), ruled 2026-09-07). TWO things are missing and neither is the entity: git-host members on AuditTargetKind, and a generation that WRITES personActor — the field is declared for exactly this wave and "this generation writes none" (:695-697)
03 / What's simulated
Every OpenAI call resolves against the same simulated data set every other provider serves. Counted from the openai-2020-10-g11 artifact (universe generation 11):
Each line below is one assertion in the conformance suite named beside it — run on every build, over one artifact, through the real renderers. Nothing is claimed here that no expect checks.
This surface and the Codex Analytics surface serve ONE cohort: the set of `actor.user_id` in Codex usage equals the set of `/v1/organization/users` ids, the emails match per id, and the two hosts' uncached-input and output token totals are equal.
Against Codex Analytics · parity/m3-parity.test.ts
This vendor's user roster is disjoint from the GitHub Copilot cohort and from Anthropic's, Cursor's and Devin's — nobody holds two vendors' seats — and the token totals summed across the paged usage endpoint equal its own slice of the canonical seat table.
Against GitHub, Anthropic, Cursor, Devin · parity/m3-parity.test.ts
Every identity this host bills for resolves as a user on the GitHub host with the same name.
Against GitHub · parity/m3-parity.test.ts
05 / Pinned snapshots
Each pin regenerates byte-identically on every request, so a test written against one never drifts. Generations are DIFFERENT universes, not versions of one — never swap a suffix expecting the same data.
openai-2020-10.snap.sandboxapis.devgeneration 52020-10-01servedopenai-2020-10-g10.snap.sandboxapis.devgeneration 102020-10-01servedopenai-2020-10-g11.snap.sandboxapis.devgeneration 112020-10-01servedopenai-2020-10-g6.snap.sandboxapis.devgeneration 62020-10-01servedopenai-2020-10-g8.snap.sandboxapis.devgeneration 82020-10-01servedopenai-2020-10-g9.snap.sandboxapis.devgeneration 92020-10-01servedNeed an endpoint that is not served yet?
Every row OpenAI's manifest carries is on this page, so “not here” is an answer rather than a gap in the rendering. Tell us which path and which client, and it moves up the queue — the order is set by what people ask for.