How headless Cavuno works
Understand which responsibilities belong to Cavuno, the SDK, and your frontend.
A
JCavuno supplies the managed job board backend. @cavuno/board is the typed interface to that backend. Your application owns the frontend experience and its runtime.
That boundary lets you replace Cavuno’s hosted frontend without rebuilding job storage, search, candidate accounts, applications, employer workflows, or the other enabled backend capabilities.
The request path
123456Visitor→ your route, component, or server function→ @cavuno/board→ Cavuno Board API→ typed data or BoardApiError→ your rendered response
Every client method uses a board-scoped base path:
1{baseUrl}/v1/boards/{board}/...
The client builds that path, serializes requests, attaches configured headers, parses JSON, and throws typed API errors. It does not render HTML or choose routes.
Ownership by layer
| Layer | Owns | Does not own |
|---|---|---|
| Cavuno | Persisted data, public Board API responses, search, business rules, feature entitlements, authentication endpoints | Your components, route tree, hosting, or browser session storage |
| SDK | Request construction, response types, namespace methods, auth storage adapters, pagination, errors, and helper packages | Page templates, automatic route generation, hidden token refresh, or deployment |
| Your frontend | Routes, layout, accessibility, forms, analytics presentation, cache policy, session boundary, hosting, and deployment | Cavuno’s internal data model or operator administration |
Start with board context
Call board.context() when assembling the application shell. It returns the board identity, theme, analytics configuration, custom fields, labels, footer data, and capability flags.
12345678910import { createBoardClient } from '@cavuno/board';const board = createBoardClient({board: 'pk_0123456789abcdef0123456789abcdef',});const context = await board.context();console.log(context.name);console.log(context.features.jobAlerts);
Treat context.features as the runtime capability contract. For example, only link to your alerts route when features.jobAlerts is true, and distinguish talentDirectoryVisibility when deciding whether /talent is public, employer-only, or disabled.
Feature flags are not only presentational. The API remains authoritative and can still reject a request, so the frontend must also handle typed errors.
What the API intentionally does not return
The Board API returns data and configuration—not hosted page-builder JSON or Cavuno’s rendered layouts. Recreate the pages you need using the returned data and helper packages.
When moving an indexed hosted board to headless, preserve canonical public paths where possible. In particular, job details use /companies/:companySlug/jobs/:jobSlug; /jobs/:keyword remains a listing route.
Verify the boundary
You have the model right when:
- Changing a component does not require changing Cavuno data APIs.
- Adding an optional route begins with the corresponding context feature.
- A public data request works without a candidate session.
- A user-specific request carries that user’s authorization only for that call.
- Your frontend—not the SDK—decides how a loading, empty, denied, or failed state looks.
Next, choose a stable board identifier and publishable key.