# 5-minute quickstart

This path proves your API key, tenant base URL, and first read in a few minutes.
Start read-only. Move to writes only after you have a disposable tenant and a
clear rollback plan.

## 1. Set credentials

Set your token and base URL:

```bash
export HOLLYHR_API_TOKEN="hhr_live_..."
export HOLLYHR_API_BASE_URL="https://{workspace}.hollyhr.com/api/v1"
```

Replace `{workspace}.hollyhr.com` with the HollyHR app origin your organisation
uses to sign in. If your organisation uses a custom HollyHR domain, use that
origin instead.

## 2. Check the key

Check the authenticated key:

```bash
curl "$HOLLYHR_API_BASE_URL/me" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json"
```

The response identifies the current organisation, key scopes, environment, and
actor. During beta, public API keys are live organisation keys:
`environment.type` is `live`, `environment.sandbox` is `false`, and
`actor.type` is `api_key`. See [Environments and Testing](/environments-testing)
before running write tests.

## 3. Make the first useful read

List people:

```bash
curl "$HOLLYHR_API_BASE_URL/people?limit=50" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json"
```

Sync people changed since a timestamp:

```bash
curl "$HOLLYHR_API_BASE_URL/people?updated_since=2026-06-16T09:00:00.000Z" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json"
```

Read reference data:

```bash
curl "$HOLLYHR_API_BASE_URL/reference/time-off-categories" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json"
```

## 4. Use the TypeScript SDK

For Node, Next.js, and worker-style server integrations, use the generated
preview SDK from npm:

```bash
pnpm add @hollyhr/api-client
```

```ts
import { createHollyHrApiClient } from "@hollyhr/api-client";

const hollyhr = createHollyHrApiClient({
  baseUrl: process.env.HOLLYHR_API_BASE_URL!,
  token: process.env.HOLLYHR_API_TOKEN!,
});

const people = await hollyhr.get("/people", { query: { limit: 10 } });
console.log(people.requestId, people.rateLimit, people.data);
```

Inside the HollyHR repository, the source package lives at
`packages/hollyhr-api-client` and is generated with `pnpm sdk:generate`. The SDK
includes helpers for cursor pagination, typed API errors, ETags/`If-Match`,
idempotency keys, request IDs, rate-limit headers, and webhook signature
verification. The package is merge-gated with `pnpm guard:sdk`, which builds
the SDK, runs its tests, syntax-checks the packaged examples, and checks
generated operation drift before release branches can merge.

The npm package includes runnable examples for the first call, pagination,
conditional updates, and webhook signatures:

```bash
node node_modules/@hollyhr/api-client/examples/first-call.mjs
node node_modules/@hollyhr/api-client/examples/paginate-people.mjs
```

## 5. Optional TTFC smoke

For a fuller API + MCP connectivity check, run the smoke harness:

```bash
export HOLLYHR_MCP_URL="https://{workspace}.hollyhr.com/api/mcp"
export HOLLYHR_MCP_TOKEN="$HOLLYHR_API_TOKEN"

pnpm developer:ttfc:smoke
```

The smoke expects a seeded disposable tenant by default. If you are debugging an
empty tenant, set `HOLLYHR_TTFC_ALLOW_EMPTY=1`. To produce a shareable evidence
file for directory or aggregator review, set:

```bash
HOLLYHR_TTFC_OUTPUT_PATH="./ttfc-evidence.json" pnpm developer:ttfc:smoke
```

See [Sandbox and TTFC](/sandbox) for disposable tenant guidance and the full
smoke checklist.

## Safe writes

Create a person with safe setup fields:

```bash
curl -X POST "$HOLLYHR_API_BASE_URL/people" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_create_ada_lovelace_001" \
  --data '{
    "work_email": "ada@example.com",
    "first_name": "Ada",
    "last_name": "Lovelace",
    "job_title": "Engineer"
  }'
```

Update safe setup fields by first reading the person and using the returned
`ETag` header as `If-Match`:

```bash
curl -X PATCH "$HOLLYHR_API_BASE_URL/people/{person_id}" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_update_ada_title_001" \
  -H 'If-Match: "etag-from-get-response"' \
  --data '{"job_title":"Principal Engineer"}'
```

End/offboard a person with an effective date:

```bash
curl -X POST "$HOLLYHR_API_BASE_URL/people/{person_id}/end" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_end_ada_001" \
  -H 'If-Match: "etag-from-get-response"' \
  --data '{"end_date":"2026-07-31"}'
```

Reactivate a previously ended or inactive person:

```bash
curl -X POST "$HOLLYHR_API_BASE_URL/people/{person_id}/reactivate" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: idem_reactivate_ada_001" \
  -H 'If-Match: "etag-from-get-response"'
```

Update safe employment fields:

```bash
curl -i "$HOLLYHR_API_BASE_URL/people/{person_id}/employment" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json"
```

```bash
curl -X PATCH "$HOLLYHR_API_BASE_URL/people/{person_id}/employment" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_update_ada_employment_001" \
  -H 'If-Match: "employment-etag-from-get-response"' \
  --data '{
    "job_title": "People Lead",
    "start_date": "2026-02-01"
  }'
```

Create a dated employment-history entry:

```bash
curl -X POST "$HOLLYHR_API_BASE_URL/people/{person_id}/employment-history" \
  -H "Authorization: Bearer $HOLLYHR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_add_ada_history_001" \
  --data '{
    "job_title": "People Lead",
    "start_date": "2026-03-01"
  }'
```

Use the API reference for the full list of implemented endpoints and response
fields.

## Next steps

- Connect an AI client with [Claude and ChatGPT](/ai-connectors).
- Validate MCP transport with the [MCP smoke test](/mcp-smoke).
- Import the OpenAPI schema into Postman, Insomnia, or your API client with
  [OpenAPI imports](/openapi-imports).
