Skip to content
Basenet
🇳🇱 Nederlands
Esc
↑↓navigate↵open⌘Jpreview

Public API and documentation

One OpenAPI contract feeding Blume Pages, Scalar, and OpenWiki.

Outward-facing platform surface for BLI-66: documented REST API, scoped tokens, webhook subscriptions, and a permission-filtered OData v4 BI service. Linear issue BLI-66 owns product scope; the committed OpenAPI artifact owns the currently published HTTP contract.

Entry URLs

Surface Where
Partner guides (this site) /partner · Pages: https://supreme-adventure-r2rn151.pages.github.io/partner
Developer map (this site) /developers
OpenAPI JSON (Pages) /openapi.json — primary published reference
OpenAPI JSON (app) GET /api/v1/openapi.json
Scalar reference (deployed staff app) GET /reference — see Scalar API reference for the auth reality and runtime-vs-committed distinction
Scalar local preview (developers only) http://localhost:3000/reference after pnpm dev

Contract source of truth

Nothing below is a second source — all consumers take the same artifact:

  1. Zod schemas in packages/api-contract/src/
  2. → OpenAPI 3.1 via @asteasolutions/zod-to-openapi
  3. → committed packages/api-contract/openapi.json (pnpm --filter @blinqx/api-contract gen)
  4. → live GET /api/v1/openapi.json on apps/web

Four layers over one spec

Caption: one generated contract; Blume and OpenWiki symlink it; Scalar renders the live app generator.

apps/docs/openapi.json              → packages/api-contract/openapi.json
apps/docs/public/openapi.json       → packages/api-contract/openapi.json
openwiki/integrations/openapi.json  → packages/api-contract/openapi.json

Verify: docs/runbooks/docs-surfaces.md.

Partner narrative

Guides under /partner cover scoped tokens, scopes/can(), pagination, idempotency (not yet in the contract), rate limits, webhook subscriptions, and OData.

Published capability map

Capability Published paths Scope Contract boundary
REST resources /api/v1/matters, /relations, /documents, /hours, /tasks, /invoices Resource-specific read/write scopes; invoices currently publish billing:read only JSON request and response schemas come from OpenAPI
Webhook subscriptions GET and POST /api/v1/webhooks webhooks:admin List/create and the five event types are published; delivery headers, retry timing, update, and revoke are not yet in OpenAPI
OData BI /api/v1/bi, /api/v1/bi/$metadata, /api/v1/bi/matters, /hours, /billing bi:read OData v4 discovery and collection envelopes with $top/$skip; no general query-option or DirectQuery promise

The table deliberately follows packages/api-contract/openapi.json. A route that exists in apps/web but is absent from that artifact is an internal or not-yet-published route.

Authentication and permission flow

Caption: token scope is the coarse gate; the resolved user’s normal permission rule remains authoritative before serialization.

Webhook subscription contract

POST /api/v1/webhooks accepts an event type, callback URL, secret, and optional active flag. The transport adapter authenticates webhooks:admin; the webhook capability layer adds the tenant-admin and callback safety gates; the application handler persists the subscription without returning the secret.

Caption: the public create path applies scope, permission, and callback-safety checks before persistence.

The published event enum is matter.created, relation.created, hour.created, task.created, and invoice.sent. Keep partner docs limited to fields and operations present in OpenAPI; internal delivery implementation is not a substitute for a published signature/retry contract.

OData discovery and paging

The BI service is intentionally small and read-only. An OData-aware client starts at /api/v1/bi, reads /api/v1/bi/$metadata, then requests the matters, hours, or billing entity set. Collection routes reuse the API’s permission filtering before paging and return @odata.context, value, and optional @odata.nextLink.

Caption: OData discovery exposes three permission-filtered entity sets and offset paging without promising unsupported query options.

Change and verification workflow

  1. Change Zod schemas or operation registration under packages/api-contract/src/.
  2. Regenerate the committed artifact with pnpm --filter @blinqx/api-contract gen.
  3. Review the packages/api-contract/openapi.json diff; partner availability wording must follow that artifact.
  4. Run pnpm --filter @blinqx/api-contract test and the route-focused tests for the affected surface.
  5. Build the docs site so /openapi.json, partner guides, and this developer map are checked together.

Hard constraints

  • EU-only production path for tenant data, auth, AI, observability.
  • Every tenant resource is permission-filtered through can() before serialization.
  • Bearer tokens hashed at rest and scoped; /api/v1 versioned; list endpoints server-side paged.
  • Published availability comes from committed OpenAPI, not from an unregistered route or a future Linear acceptance criterion.

Was this page helpful?