Sandbox and TTFC
Use a disposable HollyHR tenant when testing integrations. HollyHR does not use one shared global sandbox credential: API keys are tenant-scoped, and the safer model is a seeded synthetic tenant per reviewer, partner, or trial.
This is the intended product pattern for in-app exploration too: learn inside a made-up company with realistic departments, people, managers, time off, documents, and notifications, then switch to a clean real org before using real company records.
Five-minute smoke
Set an API key with at least organisation:read, people:read,
reference:read, and time_off:read:
Code
Then run:
Code
The smoke checks:
GET /meGET /people?limit=1, including a non-empty seeded-data assertion by defaultGET /metadata- MCP protected-resource metadata
- unauthenticated MCP
WWW-Authenticatediscovery - authenticated
GET /api/mcpreturning405 Method Not Allowed - MCP SDK initialization,
tools/list, andwhoami - request IDs and rate-limit headers where the live endpoint returns them
The command fails if the full path takes longer than 300 seconds. Override that only when debugging a known network or client issue:
Code
If a hosted smoke fails unexpectedly, check https://status.hollyhr.com before
rotating credentials or reseeding the sandbox.
If you are deliberately testing an empty tenant, allow empty people results explicitly:
Code
For directory, aggregator, or internal launch evidence, write the smoke result to JSON:
Code
For a complete directory-review bundle, pair this smoke output with
Reviewer demo guide. The handoff manifest is the
non-secret evidence file; the generated .env file is the secret credential
bundle.
If the tenant is expected to advertise OAuth, make that expectation explicit so
the smoke fails while authorization_servers is still empty:
Code
Scenario seed
For local and internal demo environments, HollyHR includes a beta-confidence scenario seed with synthetic UK SME data:
Code
For developer-platform demos, use the higher-level provisioning command. It reuses the scenario seed, returns endpoint evidence, and can mint a reveal-once API key for TTFC:
Code
When creating credentials for a production-hosted reviewer tenant, pull Vercel
Production env first and derive HOLLYHR_DATABASE_TARGET_PROOF from that env
file. Do not assume local .env points at the same Neon endpoint as the
deployed app.
When --output-env is present, the JSON output redacts the API token and stores
the token only in the mode-0600 env file. Use --reveal-token-in-json only
for an interactive reveal-once flow where the JSON file itself is treated as a
secret.
For a directory reviewer or sales/demo handoff, mint browser login links into the same secret env file:
Code
The JSON evidence redacts login URLs by default. The env file contains
single-use HOLLYHR_REVIEWER_LOGIN_* links plus the API/MCP token. Treat the
env file as a secret, and refresh it before an external review window.
The JSON output now includes a reviewer_handoff block with the concrete MCP
endpoint, endpoint template, safe starter prompts, login expectations, and TTFC
command to copy into the submission pack.
Then run the smoke against the generated env file:
Code
To reset the scenario, prove the target database first and explicitly acknowledge the destructive operation:
Code
Never run the reset against a real customer tenant. The seed is intended for local, preview, disposable demo, and reviewer-demo environments.
The reviewer/demo tenant should include at least one person, one manager relationship, departments or teams, one public holiday set, and at least one time-off record so API, SDK, and MCP smoke runs prove real HR workflows rather than only authentication.
Use --include-write-scopes only for a tenant where writes are explicitly part
of the demo. The key may include mcp:write, but MCP commit still fails unless
the server-side write-mode gate is enabled and the host supports form
elicitation.
Demo orgs versus real orgs
Do not seed fake people into a customer's real tenant. The safe onboarding model
is a separate demo org with its own orgId, seeded from the same synthetic
fixtures as the sandbox. A customer can explore that made-up company, then
switch to their real empty org and import real employees. "Start fresh" deletes
or abandons the demo org; it never promotes sample rows into production data.
For per-customer demo clones, pass a unique subdomain:
Code
Non-default scenario subdomains get clone-specific synthetic email addresses, so multiple demo orgs can coexist without sharing users or reset scope.
Writes
REST writes require idempotency keys and, for conditional updates, ETags. MCP
writes also require mcp:write, HOLLYHR_MCP_WRITE_MODE=enabled, and host form
elicitation. Keep write tests in disposable tenants until your DPIA/DPO approval
and tenant rollout plan are complete.