Support/Developer Platform/Build a complete headless SaaS

Developer Platform

Build a complete headless SaaS

Use every promoted first-class module from your own React, mobile, desktop, or legacy interface without exposing an API credential to the browser.

Public contract
227 operations
First-class modules
181 typed operations
Browser secrets
None

A headless SaaS keeps your own interface while BuildWithHQ supplies the governed application backend. Developer Kit 1.7.0 exposes all 181 promoted first-class module operations through the same app-bound Developer API as the existing 46 platform operations. You can build Contacts, Work Orders, Universal Inbox, Files, Checklists, Calendar, Reservations, Knowledge Core, GoClaw, AI Insights, Global Search, and the remaining cataloged experiences without calling an internal tenant URL or connecting React to SQL.

The production shape

Browser / mobile / desktop UI
        | your session + CSRF
        v
Your trusted server or narrow BFF
        | app-bound BuildWithHQ credential
        v
https://api.buildwithhq.com/v1/apps/{saasAppId}/...
        | server-derived app + user + DataRole + location scope
        v
Only the authorized, paginated result returns to your UI

The app credential is bound to one SaaS app and, for module data, to one active runtime principal. Every request is re-authorized by its explicit scope and then executes the same typed service and secured stored-procedure contract used by the native application. The URL chooses a target; it never proves authority.

Copy the server-side TypeScript start

import { BuildWithHQModuleClient } from "./sdk/BuildWithHQConnector.js";

const api = new BuildWithHQModuleClient({
  saasAppId: process.env.BWHQ_SAAS_APP_ID!,
  credential: process.env.BWHQ_API_CREDENTIAL!,
});

export async function contactsPage(search = "") {
  return api.contactsList({ search, pageNumber: 1, pageSize: 50 });
}

export async function workOrdersPage() {
  return api.workOrdersList({ pageNumber: 1, pageSize: 50 });
}
Important

Run this code on a trusted server only. Never put BWHQ_API_CREDENTIAL in VITE_*, NEXT_PUBLIC_*, page JSON, browser storage, a mobile bundle, logs, prompts, or source control.

What the 1.7.0 kit gives you

  • All 227 public operations in semantically identical generated JSON and YAML OpenAPI files.
  • All 181 first-class module operations as typed methods in sdk/modules.generated.ts, exported by BuildWithHQConnector.ts.
  • Exact required scopes on every operation in catalog/operations.json, with module rate classes and aliases in the sanitized catalog/module-surface.json.
  • Complete request and response DTOs, including lists, detail reads, writes, files, searches, ticketing, approvals, and module-specific state changes.
  • React presentation sources for professional dashboards and native Builder pages, while leaving authentication and mutations on the trusted side of the boundary.
  • Machine-readable coverage whose two SDK manifests must equal OpenAPI exactly before the ZIP builds.

Builder names and API names are explicitly joined

catalog/capabilities.json records each Builder feature slug beside its Developer API module key, public base path, and scopes. For example, the Builder feature record-relations uses the record-graph API module, knowledge-core uses knowledge-articles, and dynamic-records is served below /modules/dynamic. The React gallery displays both identities so developers do not infer route names from marketing labels.

Native Builder and headless are two views of the same system

Builders save registered React blocks and pages in BuildWithHQ; those blocks use a signed-in tenant session. Headless developers use the generated server SDK and paint the returned data in their own React or other client. Both paths reach the same module services and secured database contracts. A developer can prototype a presentation from the kit, then either publish it as a Builder component or host it in a headless interface—the identity mechanism changes, but the business contracts and server-side data scope do not.

Go-live checks

  1. Issue a least-privilege credential with only the module read/write scopes the server needs.
  2. Keep list/search calls bounded and preserve server pagination; never download a tenant graph to render one row.
  3. Handle 401, 403, 404, 409, 429, and 5xx distinctly and retain the correlation ID.
  4. Test a valid record, a foreign-tenant record, and a random nonexistent ID. Foreign and nonexistent responses must remain indistinguishable.
  5. Exercise optimistic concurrency, file scanning, retry/idempotency, empty states, mobile layout, keyboard access, and service recovery.
  6. Generate clients from the checked-in OpenAPI version and pin the Developer Kit SHA-256 for the release.

A missing credential scope returns HTTP 403 with code credential_scope_required, safe message The authenticated credential does not grant this operation., and a correlation ID. Checklist item updates and normal Contact updates declare HTTP 409 because they carry concurrency state. The Contacts favorite command is an idempotent boolean write without an expected revision, so its contract deliberately does not advertise 409.

Note

The repository implementation and local battle environment expose and test this contract. Availability at api.buildwithhq.com still depends on deploying that gateway build, database grants, TLS, routing, and credentials to the production environment.