Surfaces overview

Publish capabilities and workflows as a fluent product API — selective SDK exposure, product naming, one client for consumers.

PrerequisitesWorkflows overview

Product ability: A Surface turns platform building blocks into a product API consumers call through Surface in cliodot — not a custom npm client per product, and not OpenAPI alone labeled as an SDK.

You choose which ops belong on the product, name them as fluent operations (users.account, customers.cards.list), and publish a catalog (plus optional types) so integrators never have to learn every underlying route.

SDK exposure is independent of ordinary public access: you decide what the Surface client can call, separately from what other callers may hit.

Continue with Use Surfaces from the SDK for install, configuration, fluent calls, and errors.

Publish secure APIs, manage domains, and release intentionally.

Surfaces#

Internally, workflows may change frequently. A Surface is a stable front door for published capabilities.

  • Decoupling: Map /api/v1/charge-user to an internal workflow so you can change the underlying implementation without breaking the public URL.
  • Productization: Group related capabilities into a cohesive API with its own documentation.

Authentication strategies

1. Public (no auth)
  • Use case: Webhooks from third parties, public status pages, or open data endpoints.
2. Native API keys
  • Lifecycle: Generate → revoke → regenerate.
  • Custom headers: Define the header name (e.g., X-Acme-Api-Key).
  • Verification before execution: Unauthorized requests are rejected before the workflow runs.
3. JWT

Bring your own identity (Auth0, Okta, Firebase, Cognito, and similar).

  • Stateless: Validates the JWT signature.
  • Claims validation: Enforce iss and aud as required.

Payload mapping and transformation

Your internal workflow expects specific inputs. Public clients send varied shapes. The mapper bridges the gap.

Example
  • Client sends: {"user_first_name": "Alice", "age": "25"} (string age)
  • Downstream needs: {"firstName": "Alice", "age": 25} (number age)
Visual mapper
  1. Renaming: Map body.user_first_namefirstName.
  2. Type casting: Convert strings to numbers or booleans.
  3. Source mixing: Combine path, headers, query, and body into one internal object.
  4. Validation: Mark fields required; return 400 Bad Request before execution when missing.