How it works
The HelloBooks Public API lives at /public/v1/* and is gated by a marketplace-scoped Bearer token.
When a HelloBooks user installs your marketplace app into one of their entities, the OAuth flow returns an access token whose JWT aud claim is marketplace_app. That token is bound to a single AppInstall record, which carries:
installId— the install's database IDclientId— your marketplace app's client identifierappSlug— your app slugorgRefId+entityRefId— the tenant the user installed your app intoscopes— the OAuth scopes the user granted
Send the token on every request:
Authorization: Bearer <access_token>Host placeholder. Examples below use api.hellobooks.com as a stand-in. Replace it with your environment's host — production, staging, and self-hosted deployments each have their own. Confirm the correct host with your HelloBooks contact before going live.Verify your install
Call GET /public/v1/me with the token to confirm the tenant scope and the granted scopes.
curl -H "Authorization: Bearer $HB_TOKEN" \
https://api.hellobooks.com/public/v1/me{
"install_id": "65f0a1...",
"client_id": "cli_abc123",
"app_slug": "your-app-slug",
"org_ref_id": "65...",
"entity_ref_id": "66...",
"scopes": ["invoices:read", "bills:read"]
}The values in org_ref_id and entity_ref_id MUST match the :orgId/:entityId you put in the URL of any tenant-scoped route (see Tenant Isolation).
Token rotation
Marketplace access tokens carry an explicit AccessTokenExpiresAt. When the token expires, calls return:
{ "error": "invalid_token", "message": "Access token expired." }Use your refresh token (issued at the end of the install flow) to mint a new access token. Disabling your AppApiKey from the marketplace dashboard immediately kills outstanding tokens — every request after that returns invalid_client.
Marketplace tokens are NOT user tokens
HelloBooks runs two separate authentication surfaces:
| Surface | URL prefix | Token type |
|---|---|---|
| Internal app (used by HelloBooks frontend) | /<resource>/... (e.g. /invoices/read/...) | User session JWT |
| Public API (marketplace apps) | /public/v1/* | Marketplace access token |
The user-token middleware explicitly rejects marketplace tokens with Marketplace app tokens cannot be used on user routes. Conversely, a user JWT will not authenticate at /public/v1/*. Pick the right surface for the right caller.