Contract Types Overview
Learn about the different contract types in ContractSpec and when to use each one for spec-first development.
Core Contract Types
Operations
API endpoints with input/output schemas, validation, and policy.
defineCommand / defineQueryEvents
Domain events with typed payloads and PII handling.
defineEventCapabilities
Feature groupings that link operations, events, and UIs.
defineCapabilityPresentations
UI specifications for rendering data and handling interactions.
definePresentation1) Operations (Commands & Queries)
Operations are the backbone of your API. Commands mutate state, queries read state. Both have typed input/output schemas.
import { defineCommand, defineQuery } from "@contractspec/lib.contracts";
import { SchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
// Command: Mutates state (creates a user)
export const CreateUserCommand = defineCommand({
meta: {
key: "user.create",
version: "1.0.0",
description: "Create a new user account",
stability: "stable",
owners: ["platform.core"],
tags: ["users", "auth"],
},
io: {
input: new SchemaModel({
name: "CreateUserInput",
fields: {
email: { type: ScalarTypeEnum.Email(), isOptional: false },
name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
},
}),
output: new SchemaModel({
name: "CreateUserOutput",
fields: {
id: { type: ScalarTypeEnum.UUID(), isOptional: false },
email: { type: ScalarTypeEnum.Email(), isOptional: false },
},
}),
errors: {
EMAIL_EXISTS: {
description: "Email already registered",
http: 409,
when: "User with this email already exists",
},
},
},
policy: { auth: "admin" },
});
// Query: Reads state (gets user by ID)
export const GetUserQuery = defineQuery({
meta: {
key: "user.get",
version: "1.0.0",
description: "Get user by ID",
stability: "stable",
owners: ["platform.core"],
tags: ["users"],
},
io: {
input: new SchemaModel({
name: "GetUserInput",
fields: {
id: { type: ScalarTypeEnum.UUID(), isOptional: false },
},
}),
output: new SchemaModel({
name: "GetUserOutput",
fields: {
id: { type: ScalarTypeEnum.UUID(), isOptional: false },
email: { type: ScalarTypeEnum.Email(), isOptional: false },
name: { type: ScalarTypeEnum.String(), isOptional: false },
},
}),
},
policy: { auth: "user" },
});2) Events
Events represent domain occurrences. They have typed payloads with PII field marking for compliance.
import { defineEvent } from "@contractspec/lib.contracts";
import { SchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
export const UserCreatedEvent = defineEvent({
meta: {
key: "user.created",
version: "1.0.0",
description: "Emitted when a new user is created",
stability: "stable",
owners: ["platform.core"],
tags: ["users", "auth"],
},
// Mark PII fields for redaction in logs/exports
pii: ["email"],
payload: new SchemaModel({
name: "UserCreatedPayload",
fields: {
userId: { type: ScalarTypeEnum.UUID(), isOptional: false },
email: { type: ScalarTypeEnum.Email(), isOptional: false },
createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
},
}),
});
export const UserDeletedEvent = defineEvent({
meta: {
key: "user.deleted",
version: "1.0.0",
description: "Emitted when a user is deleted",
stability: "stable",
owners: ["platform.core"],
tags: ["users"],
},
payload: new SchemaModel({
name: "UserDeletedPayload",
fields: {
userId: { type: ScalarTypeEnum.UUID(), isOptional: false },
deletedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
reason: { type: ScalarTypeEnum.String(), isOptional: true },
},
}),
});3) Capabilities
Capabilities group related operations, events, and presentations. They define feature boundaries and dependencies.
import { defineCapability } from "@contractspec/lib.contracts";
export const UserManagementCapability = defineCapability({
meta: {
key: "user.management",
version: "1.0.0",
description: "User account management features",
stability: "stable",
owners: ["platform.core"],
tags: ["users", "core"],
kind: "api",
},
// Operations/events this capability provides
provides: [
{ surface: "operation", key: "user.create", version: "1.0.0" },
{ surface: "operation", key: "user.get", version: "1.0.0" },
{ surface: "operation", key: "user.delete", version: "1.0.0" },
{ surface: "event", key: "user.created", version: "1.0.0" },
{ surface: "event", key: "user.deleted", version: "1.0.0" },
],
// Dependencies on other capabilities
requires: [
{ key: "auth.core", reason: "Needs authentication for user operations" },
],
});
// Capabilities can extend other capabilities
export const AdminUserCapability = defineCapability({
meta: {
key: "user.admin",
version: "1.0.0",
description: "Admin-only user management features",
stability: "stable",
owners: ["platform.core"],
tags: ["users", "admin"],
kind: "api",
},
// Inherit from base capability
extends: { key: "user.management", version: "1.0.0" },
provides: [
{ surface: "operation", key: "user.ban", version: "1.0.0" },
{ surface: "operation", key: "user.impersonate", version: "1.0.0" },
],
});4) Presentations
Presentations define UI specifications. They link to capabilities and specify how data should be displayed.
import { definePresentation } from "@contractspec/lib.contracts";
export const UserListPresentation = definePresentation({
meta: {
key: "users.list",
version: "1.0.0",
description: "Display a list of users with search and pagination",
stability: "stable",
owners: ["platform.core"],
tags: ["users", "ui"],
},
// Link to capability that provides data
capability: { key: "user.management", version: "1.0.0" },
// UI specifications
config: {
title: "Users",
layout: "table",
columns: ["name", "email", "createdAt", "status"],
actions: ["view", "edit", "delete"],
pagination: { defaultPageSize: 25 },
search: { fields: ["name", "email"] },
},
});5) Additional Contract Types
ContractSpec provides specialized contracts for different concerns:
Policy
definePolicyRBAC/ABAC rules, rate limits, and access control.
Workflow
defineWorkflowMulti-step processes with states, transitions, and SLAs.
Translation
defineTranslationi18n messages with ICU format and locale fallbacks.
Integration
defineIntegrationExternal service connections and API adapters.
Form
defineFormSpecForm definitions with fields, validation, and layouts.
Data View
defineDataViewRead-only data projections and aggregations.
Feature
defineFeatureFeature flags and progressive rollout configurations.
Test
defineTestSpecContract-driven test scenarios and fixtures.
6) Registering Contracts
Each contract type has a registry for lookup and validation.
import {
OperationSpecRegistry,
installOp,
} from "@contractspec/lib.contracts/operations";
import { EventRegistry } from "@contractspec/lib.contracts";
import { CapabilityRegistry } from "@contractspec/lib.contracts/capabilities";
// Import your contracts
import { CreateUserCommand, GetUserQuery } from "./user.operation";
import { UserCreatedEvent } from "./user.event";
import { UserManagementCapability } from "./user-management.capability";
// Create registries
export const operationRegistry = new OperationSpecRegistry();
export const eventRegistry = new EventRegistry();
export const capabilityRegistry = new CapabilityRegistry();
// Register operations with handlers
installOp(operationRegistry, CreateUserCommand, async (input) => {
// Your implementation here
return { id: "uuid", email: input.email };
});
installOp(operationRegistry, GetUserQuery, async (input) => {
// Your implementation here
return { id: input.id, email: "user@example.com", name: "User" };
});
// Register events and capabilities
eventRegistry.register(UserCreatedEvent);
capabilityRegistry.register(UserManagementCapability);Contract Type Decision Guide
| When you need... | Use this contract |
|---|---|
| An API endpoint that changes data | defineCommand |
| An API endpoint that reads data | defineQuery |
| Async notification of something that happened | defineEvent |
| Group related specs under a feature | defineCapability |
| Define UI rendering specifications | definePresentation |
| Access control and rate limiting | definePolicy |
| Multi-step business processes | defineWorkflow |
Want visual contract design?
Studio provides a visual editor for creating and managing contracts with team collaboration and version control.
Join Studio waitlist