Simulators
Clerk changelog
What changed in each Clerk simulator release, newest first.
v0.0.5 — 2026-11-06
-
A key that does not start with
sk_is refused on every route. Every Backend API route returns 401clerk_key_invalidfor a bearer value that does not start withsk_, as Clerk does. A secondAuthorizationheader gets 401authorization_header_format_invalid, where Clerk returns a 400 page. Deleting an organization and updating a membership used to carry out such requests, and the other routes returned a 401 or 403 that varied by route. -
The docs gain an Errors and limits section. It shows the
errorsbody withcode,long_message,meta.param_nameandclerk_trace_id, how each list pages withlimit,offsetandstarting_after, and what a repeated create returns.
v0.0.4 — 2026-11-05
-
The twin documents its own control plane in Swagger.
/_rystic/swaggernow lists a Rystic control plane spec, served at/_rystic/swagger/spec/rystic-control-plane.json, describing the/_rystic/*routes this twin serves (its scenarios, inspect views and seedable registers by name) and its/_twin/*routes. -
A state dump seeds back as it was, and the next record gets a fresh id.
GET /_rystic/inspectposted toPOST /_rystic/seedafter a reset restores every record where it was, per-caller records included, which used to land under a doubled key. The next record created after any seed passes every uuid and event id the simulator minted that the seed holds.GET /_rystic/inspect?view=sequenceslists every id counter, and a world document’s newsequenceskey restores them, so ids the simulator renders from a counter continue where the dump left off. -
A slow client no longer holds up the others. The simulator reads a request’s whole body before it starts serving it and sends the answer after, so a client that uploads slowly, or reads a large answer slowly, no longer delays other clients’ requests. Answers are unchanged; one larger than 4 MiB still makes other requests wait while it is sent.
-
The call log shows what each call asked for and whether it succeeded. Each
GET /_rystic/callsentry now carriesargs, the call’s query and body arguments with credentials redacted (long values cut, file contents left out), andok, false for an answer that is not 2xx. A path the simulator does not serve is markedunknown_route: true.?tail=Nreturns only the last N calls, anddroppedcounts the calls the log no longer keeps. -
Coverage lists the browser assets. The docs’ Coverage section now lists
GETandHEADfor/clerk.js,/clerk-ui.js,/clerk.cssand/preview/{file}, which the simulator already served, and counts them in its route total. -
The docs are one page, with a page for the browser companion. The archive ships
README.mdin place ofHOWTO.mdandSCENARIOS.md, with the same sections in the same order as every Rystic simulator’s page, andCHANGELOG.mdbeside it. The browser companion has its own page underdocs/features/, and every example on these pages runs as written against a fresh simulator. -
The docs page links the admin token section. The page now sends you to the admin token’s section of the shared-simulators page.
-
Scenario descriptions use customer terms. The Scenarios table and
--list-scenariosdescribe each scenario in American spelling, with no internal references. -
The Scenarios table is easier to scan. Each row says in a line what the scenario is for, and a list below the table says what each scenario holds.
-
Pro starts with a 14-day trial. Free has ended, so every simulator is on Pro and Enterprise, and the docs name only those plans.
-
Limitations is shorter to read. It opens with the known issues and one sentence counting the rest. The detailed lists follow, and the website folds them behind “Show all limitations”.
-
The page has no Plans section. The Quickstart names the plans that run the simulator, and the pricing page lists what each plan includes.
-
The docs read more plainly, and each difference from Clerk is marked. Sentences are shorter, and each behavior that differs from Clerk is marked “Differs from Clerk” where it’s described. Rules with several outcomes, such as what a missing key returns, which
Clerk-API-Versionvalues the simulator serves and which writes record a webhook event, are tables. The Auth section also names the two requests that go through with a key not starting withsk_or a repeatedAuthorizationheader: deleting an organization and updating a membership. Quickstart, Auth, Seeding state and the reset section keep to this simulator’s own facts, leaving the rules every simulator shares to the shared pages.
v0.0.3 — 2026-10-27
-
The HOWTO documents the world document
POST /_rystic/seedtakes. A direct seed takes a whole scenario file, with itsclock,rng_seed,credentialsandevents, not only the bare register map; the HOWTO now says so, with an example that binds a token and schedules a call. -
Indexed list query parameters. A list filter sent as
user_id[0]=…&user_id[1]=…, as some SDKs encode arrays, reads the same as the repeateduser_id=…&user_id=…onGET /users,GET /users/count,GET /organizationsandGET /organizations/{organization_id}/memberships. -
Swagger UI to read and call the twin from the browser.
/_rystic/swagger, linked from the state UI header, is Swagger UI over the published API trimmed to the operations this twin serves; Try it out sends each request to the twin.
v0.0.2 — 2026-10-12
-
clerk_acme_tenantplays a timeline. Its backend, bound tosk_test_acme_backend, updates Sam’s metadata two hours after the pinned clock, creates Priya Raman a day in, promotes Yuki to admin, moves the organization to thescaleplan on day three and removes Iris on day five, all through the Backend API; advance the clock to watch the tenant change. -
A seeded user, organization or membership sends its created webhook. A record a world’s timeline
seedevent or a barePOST /_rystic/seedcreates now sendsuser.created,organization.createdororganizationMembership.created, as the create operation does, to the egress log and any configured webhook endpoint. A world’s starting snapshot sends none. -
Session tokens and webhooks can follow a shifted app clock.
POST /_rystic/clock {"wall_offset_seconds": N}stamps session JWTiat,nbfandexpand the webhooksvix-timestampN seconds past the wall clock, so an app whose own clock you moved forward (assandbox clock -advancedoes) still accepts them;0or/_rystic/resetputs it back. -
Every Backend API call without a secret key is refused as Clerk refuses it. A request with no
Authorizationheader now answers401witherrors[0].code = authorization_header_format_invalidon every operation, ahead of the operation’s own checks.DELETE /v1/organizations/{id}andPATCH /v1/organizations/{id}/memberships/{user_id}used to succeed without a key, and other operations answered with differingauthentication_invalidbodies.
v0.0.1 — 2026-10-11
-
A local Clerk for your app’s users, organizations and sign-in. The first release of the Clerk twin: the 20 Backend API operations on users and their metadata, organizations with their metadata and memberships, at
Clerk-API-Version: 2026-05-12, served from a model validated against a live Clerk development instance, and a browser companion that serves a lookalikeclerk.jsso a@clerk/nextjsapp signs users in against the same state. It runs on Pro and Enterprise. Point@clerk/backendat it with anysk_key (HOWTO.mdshows how); no email is sent and no real instance changes. -
Users and their metadata, as Clerk keeps them.
POST /v1/usersstores each email address in lowercase,GET /v1/users?email_address=finds a user by any letter case of their address, and an address that differs from a taken one only in case answers 422form_identifier_exists; a malformed one answers 422form_param_format_invalid.GET /v1/usersrefuses anorder_bythat names no sortable field with 422form_param_value_invalid.PATCHandPUT /v1/users/{user_id}/metadatamerge and replace metadata, andDELETE /v1/users/{user_id}removes the user’s organization memberships. Everyimage_urlandprofile_image_urlleads to a PNG the twin serves under/preview/. -
Organizations, their metadata and their members. An organization created with
created_bylists its creator as anorg:adminmember right after the create, andinclude_members_count=truecounts them.PATCH /v1/organizations/{organization_id}/metadatadeep-mergespublic_metadataandprivate_metadata, removing a key set tonull, andPUTreplaces each field it names whole. Writes and lists answer with the keys Clerk’s answers carry. -
Clerk-API-Versionis checked on every route and echoed.2021-02-05,2024-10-01,2025-04-10,2025-11-10and2026-05-12(the default) are accepted and echoed inclerk-api-version, and any other value answers 400api_version_invalid. At2026-05-12, metadata sent toPATCH /v1/users/{user_id}orPATCH /v1/organizations/{organization_id}answers 422form_param_deprecated, as Clerk does: write it through the/metadataroutes. -
A browser sign-in for
@clerk/nextjs. PointNEXT_PUBLIC_CLERK_JS_URLandNEXT_PUBLIC_CLERK_UI_URLat the twin’s/clerk.jsand/clerk-ui.jsand your app gets email sign-in and sign-up with consent, Continue with GitHub and Continue with Google buttons that sign in local test identities, organization creation and selection, and member invitation, role changes and removal; signing in as an invited address joins its organization with no email sent. Sessions are RS256 tokens stamped on the wall clock your site verifies them against, and the SDK middleware’s handshake is answered by the twin, so a sandboxed site never leaves it. Boot the twin with your own RSA key, your site’s origin and its own origin;GET /_twin/configgives the publishable key, the public PEM and the proxy URL. -
Webhooks Clerk would send, signed with Svix headers. Every user write, organization create, update and delete, and membership write, from the Backend API or the browser, records
user.*,organization.*ororganizationMembership.*inGET /_rystic/egress; the organization/metadataroutes record none. Boot withCLERK_TWIN_WEBHOOK_URLand awhsec_CLERK_TWIN_WEBHOOK_SECRETand each is also delivered, itssvix-timestampon the wall clock so your receiver’s five-minute window holds however long the twin sat idle. A failed delivery never undoes the write. Event shapes follow Clerk’s documentation and are not measured against live deliveries. -
Five shipped worlds.
--scenario clerk_acme_tenantboots Acme Robotics: five users in one organization, two pending invitations and three live sessions.clerk_holdco_orgsholds one identity across three organizations,clerk_invite_backlogan organization at its ten-seat cap with eight invitations pending,clerk_session_sweepsix sessions from lapsed to live, andclerk_solo_founderone user and her organization;SCENARIOS.mdsays what each is for. Without--scenariothe twin boots an empty instance,POST /_rystic/seedlands users, organizations, memberships, sessions and invitations directly, andPOST /_rystic/resetrewinds the ID sequence, so two identical runs from a pinned clock give byte-identical users and organizations. -
Measured against a live Clerk development instance. The 2026-10-07 full-suite round matched 100 of 100 Backend API probes, with 0 inconclusive.
HOWTO.mdstates what the suite leaves out and the differences this release ships with: typed query parameters are not validated, responses carry nox-clerk-trace-idheader, an unserved route answers a plain 404, not Clerk’sresource_not_found, and deleting an organization or changing a membership’s role checks no secret key.