Clerk

@crvouga/mockingbird-service-clerk

Stateful Clerk public vendor API emulator with native namespaces, checkpoints and test controls.

Parity: Vendor API workflows compared with the pinned Emulate package oracleIdentity44 of 44 operationsIn-process fetchNode servermockingbird-clerk
$
npm install -D @crvouga/mockingbird-service-clerk

Playground

Requests go to the real emulator running in this tab. State persists across requests, and the journal shows what it received. A green dot marks operations whose sample succeeds as-is; others need ids from earlier responses.

Loads the real @crvouga/mockingbird-service-clerk into this tab on first send
https://api.clerk.com

Send a request to see the emulator's response.

Operations

44 of 44 operations in the vendored contract are emulated.

MethodPathOperationStatus
GET/v1/email_addresses/{emailId}GET /v1/email_addresses/:emailIdGET /v1/email_addresses/:emailId
PATCH/v1/email_addresses/{emailId}PATCH /v1/email_addresses/:emailIdPATCH /v1/email_addresses/:emailId
DELETE/v1/email_addresses/{emailId}DELETE /v1/email_addresses/:emailIdDELETE /v1/email_addresses/:emailId
GET/v1/organizations/{orgId}GET /v1/organizations/:orgIdGET /v1/organizations/:orgId
PATCH/v1/organizations/{orgId}PATCH /v1/organizations/:orgIdPATCH /v1/organizations/:orgId
DELETE/v1/organizations/{orgId}DELETE /v1/organizations/:orgIdDELETE /v1/organizations/:orgId
PATCH/v1/organizations/{orgId}/memberships/{userId}PATCH /v1/organizations/:orgId/memberships/:userIdPATCH /v1/organizations/:orgId/memberships/:userId
DELETE/v1/organizations/{orgId}/memberships/{userId}DELETE /v1/organizations/:orgId/memberships/:userIdDELETE /v1/organizations/:orgId/memberships/:userId
GET/v1/users/{userId}GET /v1/users/:userIdGET /v1/users/:userId
PATCH/v1/users/{userId}PATCH /v1/users/:userIdPATCH /v1/users/:userId
DELETE/v1/users/{userId}DELETE /v1/users/:userIdDELETE /v1/users/:userId
GET/.well-known/openid-configurationGET /.well-known/openid-configurationGET /.well-known/openid-configuration
GET/oauth/authorizeGET /oauth/authorizeGET /oauth/authorize
GET/oauth/userinfoGET /oauth/userinfoGET /oauth/userinfo
GET/v1/jwksGET /v1/jwksGET /v1/jwks
GET/v1/organizationsGET /v1/organizationsGET /v1/organizations
POST/v1/organizationsPOST /v1/organizationsPOST /v1/organizations
GET/v1/organizations/{orgId}/invitationsGET /v1/organizations/:orgId/invitationsGET /v1/organizations/:orgId/invitations
POST/v1/organizations/{orgId}/invitationsPOST /v1/organizations/:orgId/invitationsPOST /v1/organizations/:orgId/invitations
GET/v1/organizations/{orgId}/invitations/{invitationId}GET /v1/organizations/:orgId/invitations/:invitationIdGET /v1/organizations/:orgId/invitations/:invitationId
GET/v1/organizations/{orgId}/membershipsGET /v1/organizations/:orgId/membershipsGET /v1/organizations/:orgId/memberships
POST/v1/organizations/{orgId}/membershipsPOST /v1/organizations/:orgId/membershipsPOST /v1/organizations/:orgId/memberships
GET/v1/sessionsGET /v1/sessionsGET /v1/sessions
POST/v1/sessionsPOST /v1/sessionsPOST /v1/sessions
GET/v1/sessions/{sessionId}GET /v1/sessions/:sessionIdGET /v1/sessions/:sessionId
GET/v1/usersGET /v1/usersGET /v1/users
POST/v1/usersPOST /v1/usersPOST /v1/users
GET/v1/users/countGET /v1/users/countGET /v1/users/count
PATCH/v1/organizations/{orgId}/memberships/{userId}/metadataPATCH /v1/organizations/:orgId/memberships/:userId/metadataPATCH /v1/organizations/:orgId/memberships/:userId/metadata
PATCH/v1/organizations/{orgId}/metadataPATCH /v1/organizations/:orgId/metadataPATCH /v1/organizations/:orgId/metadata
PATCH/v1/users/{userId}/metadataPATCH /v1/users/:userId/metadataPATCH /v1/users/:userId/metadata
POST/oauth/authorize/callbackPOST /oauth/authorize/callbackPOST /oauth/authorize/callback
POST/oauth/tokenPOST /oauth/tokenPOST /oauth/token
POST/v1/email_addressesPOST /v1/email_addressesPOST /v1/email_addresses
POST/v1/organizations/{orgId}/invitations/{invitationId}/revokePOST /v1/organizations/:orgId/invitations/:invitationId/revokePOST /v1/organizations/:orgId/invitations/:invitationId/revoke
POST/v1/organizations/{orgId}/invitations/bulkPOST /v1/organizations/:orgId/invitations/bulkPOST /v1/organizations/:orgId/invitations/bulk
POST/v1/sessions/{sessionId}/revokePOST /v1/sessions/:sessionId/revokePOST /v1/sessions/:sessionId/revoke
POST/v1/sessions/{sessionId}/tokensPOST /v1/sessions/:sessionId/tokensPOST /v1/sessions/:sessionId/tokens
POST/v1/sessions/{sessionId}/tokens/{template}POST /v1/sessions/:sessionId/tokens/:templatePOST /v1/sessions/:sessionId/tokens/:template
POST/v1/users/{userId}/banPOST /v1/users/:userId/banPOST /v1/users/:userId/ban
POST/v1/users/{userId}/lockPOST /v1/users/:userId/lockPOST /v1/users/:userId/lock
POST/v1/users/{userId}/unbanPOST /v1/users/:userId/unbanPOST /v1/users/:userId/unban
POST/v1/users/{userId}/unlockPOST /v1/users/:userId/unlockPOST /v1/users/:userId/unlock
POST/v1/users/{userId}/verify_passwordPOST /v1/users/:userId/verify_passwordPOST /v1/users/:userId/verify_password

Documentation

The package README, the same file that ships in the npm tarball.Edit on GitHub

Local emulators. Real API contracts. Part of Mockingbird.

OIDC discovery, JWKS, OAuth authorize/token/userinfo, users, email addresses, organizations, memberships, invitations, sessions. Runs through Mockingbird's portable Fetch runtime with SQLite persistence, namespaces, checkpoints, faults and admin controls.

Install

Shell
npm install @crvouga/mockingbird-service-clerk

Usage

TypeScript
import { createServer } from "@crvouga/mockingbird-service-clerk/server"

const server = await createServer({ seed: 1 })

// The app's Backend API calls, with the emulator's URL in place of https://api.clerk.com.
const headers = { authorization: "Bearer sk_test_fixture", "content-type": "application/json" }
const created = await fetch(`${server.url}/v1/users`, {
  method: "POST",
  headers,
  body: JSON.stringify({ email_address: ["ada@example.com"], first_name: "Ada" }),
})
const user = (await created.json()) as { id: string; first_name: string }
const listed = await fetch(`${server.url}/v1/users?email_address=ada@example.com`, { headers })
const { data } = (await listed.json()) as { data: { id: string }[] }
console.log(data[0]?.id === user.id) // true
await server.close()

The example uses plain fetch because @clerk/backend only parses a response whose content-type is exactly application/json, and the emulator answers application/json; charset=UTF-8. With createClerkClient({ secretKey, apiUrl: server.url }) the requests succeed but resources come back as unparsed JSON strings.

API

  • ClerkAPI: portable provider instance; accepts SQLite, namespace, clock, fixtures and baseUrl.
  • createRuntime: shared runtime, including native namespace and checkpoint controls.
  • CLERK_NAMESPACE: default storage namespace.
  • document, operationIds, supportedOperationIds: registered provider route inventory.
  • createServer, DEFAULT_PORT, serveTarget from /server: loopback listener and CLI configuration.

fixtures accepts synthetic provider seed records. reset() restores defaults. Emulate 0.12.1 is a test oracle only, never a runtime dependency. Vendor handlers ported under Apache-2.0 retain their license and attribution; see LICENSE_EMULATE and THIRD_PARTY_NOTICES.md.

See SUPPORT.md for coverage and limits and API_EVIDENCE.md for validation status.

↑↓ to navigate↵ to open