---
title: Business APIs and Console Surfaces
description: Design typed Module operations and bind Console UI to exact generated clients.
---

Operator workflows use the same business contracts as every other trusted
client. A Module declares a Business API, publishes a generated client, and
ships an exact Console Surface in its Module Release. Console supplies the
authenticated actor and enforces the connected app's Surface Grant.

## Start with the Business API

Model operations around the business capability, not around a framework-wide
record abstraction. For a Support Ticket Module, useful operations are:

| Operation | Business behavior |
| --- | --- |
| `listTickets` | Return tickets visible to the current actor and tenant. |
| `createTicket` | Create one ticket with a caller-supplied idempotency key. |
| `updateTicket` | Apply a revision-bound update to an existing ticket. |
| `closeTicket` | Close a ticket through its domain transition. |

The OpenAPI contract defines input, output, error, actor, tenant, deadline, and
idempotency behavior. Generate clients from that committed contract and check
the generated output in the owning repository.

## Bind the Surface

`ModuleManifest.console` names the Surface and its ESM entry. The Module Release
binds that entry to an immutable `console_ui_esm` artifact. The application
composition selects the exact Module Release and UI artifact digests.

The Surface Grant narrows access to:

- one Module identity and Module Release digest;
- one UI artifact digest;
- one Business API contract digest;
- an explicit set of operation IDs.

Installing or connecting a Surface never grants every operation in the Module.

## Call through Surface Gateway

The generated client uses the same-origin Surface Gateway exposed as
`ConsoleClient.surfaceApi`. Console Service rechecks the browser session, Console actor,
optional tenant, exact connected System, and full Surface Grant before it calls
the target Module.

The browser does not receive target credentials. It must not call a Service
base URL, query the Service Store, or invent an undeclared operation.

## Design for direct object states

Render each target with one state and a direct reason:

- `connected`: allow operations included in the Surface Grant;
- `unavailable`: keep the current data visible when safe and offer retry;
- `incompatible`: identify the contract, release, or artifact mismatch;
- `unmanaged`: explain that the object is outside the current binding.

Do not turn these states into an app-wide score or silently fall back to a
different target.

## Authorization checklist

- Verify actor and tenant on the target Module, not only in the browser.
- Bind updates to the current business revision.
- Require an idempotency key for retried writes.
- Propagate the caller deadline and reject expired work.
- Keep Surface operation IDs narrower than the Module contract.
- Return typed problem responses without secrets or transport diagnostics.

Continue with [Module Console UI](/docs/console-packages) for artifact packaging
and [Auth and Capabilities](/docs/auth-capabilities) for capability design.
