How headless Cavuno works

Understand which responsibilities belong to Cavuno, the SDK, and your frontend.

Cavuno 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

text
Visitor
→ 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:

text
{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

LayerOwnsDoes not own
CavunoPersisted data, public Board API responses, search, business rules, feature entitlements, authentication endpointsYour components, route tree, hosting, or browser session storage
SDKRequest construction, response types, namespace methods, auth storage adapters, pagination, errors, and helper packagesPage templates, automatic route generation, hidden token refresh, or deployment
Your frontendRoutes, layout, accessibility, forms, analytics presentation, cache policy, session boundary, hosting, and deploymentCavuno’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.

ts
import { 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.