## Using HelpRange in this project

HelpRange (secure document sharing, tracked links, virtual data rooms) is called through its REST API.

- Base URL: `https://www.helprange.com/api/v2` (JSON in, JSON out; uploads also as multipart/form-data).
- Auth: `Authorization: Bearer $HELPRANGE_API_KEY` – a team API key from HelpRange Settings → API keys. Never commit
  the key or send it from browser code; read it from the environment.
- Test mode: keys starting with `hr_test_` work on a sandbox with sample data – no e-mail is sent, only addresses at
  example.com / example.org / *.test are accepted, nothing touches live data. Use a test key in development and CI;
  responses carry `"livemode": false`.
- Scopes: each key has scopes (`documents:read`, `documents:write`, `links:read`, `links:write`, `rooms:read`,
  `rooms:write`, `analytics:read`, `team:read`). 403 `insufficient_scope` names the missing one in `required_scope`.
- Full reference (Markdown, for LLMs): https://www.helprange.com/developers/llms-full.txt · OpenAPI 3.1: https://www.helprange.com/developers/openapi.json
  · Human docs: https://www.helprange.com/developers/api

Key endpoints:
- `GET /api/v2/me` – Who is connected
- `GET /api/v2/folders` – List folders
- `GET /api/v2/documents` – List documents
- `POST /api/v2/files` – Upload a file
- `POST /api/v2/files/{file_id}/links` – Create a share link
- `GET /api/v2/documents/{file_id}/links` – List share links of a document
- `GET /api/v2/documents/{file_id}` – Document statistics
- `GET /api/v2/views` – Recent document views
- `GET /api/v2/data-rooms` – List data rooms
- `GET /api/v2/data-rooms/{data_room_id}` – Data room details
- `POST /api/v2/data-rooms/{data_room_id}/documents` – Add documents to a data room
- `POST /api/v2/data-rooms/{data_room_id}/guests` – Invite a guest
- `POST /api/v2/signature-requests` – Send a document for e-signature
- `POST /api/v2/offers` – Create an offer
- `GET /api/v2/activity` – Team activity

Errors: JSON `{"error": "…"}`, some with `code`. 400 invalid input (the message names the field), 401 bad / revoked /
expired key, 402 plan without API access, 403 missing scope, 404 not found or not yours, 409 / 423 frozen data room,
413 file too large, 429 rate limit – wait `Retry-After` seconds (also `retry_after` in the body).

Retries / idempotency: there is no Idempotency-Key header. GETs are safe to retry. Give every share link a unique
`label` (per document): retrying a create with the same label answers 400 instead of making a duplicate – then list
the document's links (`GET /api/v2/documents/{file_id}/links`). Inviting someone who is already a guest answers 200
with `already_a_guest: true`. Back off on 429 and 5xx.

Rules worth knowing: `expires_on` must be today or later (`YYYY-MM-DD`); `views_limit` 0 or null = no limit;
booleans accept true/false, 1/0 or "true"/"false"; a passcode of only spaces = no passcode. The API never e-mails
share links – send the returned `url` yourself. Usage limits per team: 3,600 requests an hour (120 a minute), 300
writes an hour, 2,000 new links and 1,000 guests a day.

Webhooks (set up in Settings → Integrations, not through the API): verify `HelpRange-Signature: t=…,v1=…` =
HMAC-SHA256(secret, "<t>.<raw body>"), reject timestamps older than 5 minutes, deduplicate on the event `id`, answer
2xx fast. Docs: https://www.helprange.com/developers/webhooks
