Skip to content

Example Contracts

Copy-ready contracts for common services: databases, a message broker, a proxy, a cron job and more. Start from the one closest to your service, or use them as dependencies. New to writing contracts? Read the developer guide first.

Tip

A contract describes what a service exposes and how it behaves. Deployment details stay in your manifests. A contract points at the specs you already have (OpenAPI, AsyncAPI, a gRPC descriptor, JSON Schema for configurations) and adds what they lack: owner, dependencies, compatibility and state. Every referenced spec file must parse as JSON or YAML (see interface types).

To see contracts in action, try a demo:

  • Live dashboard demo: the dashboard in your browser, nothing to install. Its source is in examples/demo. Its runtime conformance finding is recorded.
  • Docker Compose demo: a registry, an Evidence Server and the dashboard on your machine, from one OCI artifact. A host agent checks runtime conformance live.
  • Guided tour: seven user stories from the command line, offline. Its runtime conformance finding is recorded. The same fleet opens in the terminal UI; pacto tui --root oci://ghcr.io/trianalab/pacto/pacto-demo:1.0.0 --local "" opens most of it straight from the registry.

Available examples

Service Type State Description
PostgreSQL service stateful/persistent Relational database
Redis service stateful/persistent In-memory data store
RabbitMQ service stateful/persistent Message broker
NGINX service stateless/ephemeral Reverse proxy / web server
Cron Worker scheduled stateless/ephemeral Scheduled batch job
Event Processor service stateless/ephemeral Event-driven message consumer
gRPC Service service stateless/ephemeral Microservice exposing a gRPC service descriptor
Hybrid Cache API service hybrid/persistent API with local cache and upstream rebuild

PostgreSQL

A stateful, persistent relational database with high data criticality.

pactoVersion: "2.0"

service:
  name: postgresql
  version: 16.4.0
  owner:
    team: databases

interfaces:
  - name: metrics
    type: openapi
    ref: interfaces/metrics.yaml
    visibility: internal

configurations:
  - name: default
    schema: configuration/schema.json
    required: true

workload: service

state:
  type: stateful
  persistence:
    scope: local
    durability: persistent
  dataCriticality: high

capabilities:
  - type: health
    binding:
      type: http
      interface: metrics
      path: /health
  - type: metrics
    binding:
      type: http
      interface: metrics
      path: /metrics

metadata:
  tier: critical
  backup: required
  storage-class: ssd

Note

PostgreSQL's binary wire protocol and Redis's RESP below have no openapi, asyncapi or grpc spec, so neither contract declares them as interfaces. In both contracts the only declared interface is the HTTP endpoint the metrics exporter exposes, which the health and metrics capabilities bind to (see interface types).

  • state.type: stateful with durability: persistent: persistent storage survives pod restarts
  • dataCriticality: high: backups and strict disruption budgets expected
  • Single instance: replication is handled externally; replica counts belong to the deployment
  • Capabilities over ports: health and metrics are declared as capabilities bound to the exporter interface

Redis

A stateful in-memory data store with persistent durability.

pactoVersion: "2.0"

service:
  name: redis
  version: 7.4.0
  owner:
    team: caching

interfaces:
  - name: metrics
    type: openapi
    ref: interfaces/metrics.yaml
    visibility: internal

configurations:
  - name: default
    schema: configuration/schema.json
    required: true

workload: service

state:
  type: stateful
  persistence:
    scope: local
    durability: persistent
  dataCriticality: medium

capabilities:
  - type: health
    binding:
      type: http
      interface: metrics
      path: /health
  - type: metrics
    binding:
      type: http
      interface: metrics
      path: /metrics

metadata:
  tier: high
  eviction-policy: allkeys-lru
  • state.type: stateful with durability: persistent: Redis with AOF/RDB persistence enabled needs durable storage
  • dataCriticality: medium: data is important but can be rebuilt from source if needed
  • Capabilities over ports: health and metrics are declared as capabilities bound to the exporter interface

For a pure cache without persistence:

state:
  type: stateless
  persistence:
    scope: local
    durability: ephemeral
  dataCriticality: low

RabbitMQ

A stateful message broker with persistent durability and multiple protocol interfaces.

pactoVersion: "2.0"

service:
  name: rabbitmq
  version: 3.13.7
  owner:
    team: messaging

interfaces:
  - name: amqp
    type: asyncapi
    ref: interfaces/amqp.yaml
    visibility: internal

  - name: management
    type: openapi
    ref: interfaces/management-api.yaml
    visibility: internal

  - name: metrics
    type: openapi
    ref: interfaces/metrics.yaml
    visibility: internal

configurations:
  - name: default
    schema: configuration/schema.json
    required: true

workload: service

state:
  type: stateful
  persistence:
    scope: local
    durability: persistent
  dataCriticality: high

capabilities:
  - type: health
    binding:
      type: http
      interface: management
      path: /api/health/checks/alarms
  - type: metrics
    binding:
      type: http
      interface: metrics
      path: /metrics

metadata:
  tier: critical
  cluster: required
  quorum-queues: enabled

Note

RabbitMQ's AMQP is a message-oriented protocol, so the amqp interface uses type: asyncapi with an AsyncAPI document (see interface types). The management REST API is openapi, and the Prometheus metrics endpoint is a separate openapi interface the metrics capability binds to.

  • dataCriticality: high: message loss can cause data integrity issues across the system
  • state.type: stateful with durability: persistent: queues and messages must survive restarts
  • Clustering is external: quorum-queue cluster sizing belongs to the deployment and is recorded in metadata
  • Multiple interfaces: AsyncAPI for messaging, OpenAPI for the management API and metrics

NGINX

A stateless reverse proxy and web server.

pactoVersion: "2.0"

service:
  name: nginx
  version: 1.27.3
  owner:
    team: networking

interfaces:
  - name: proxy
    type: openapi
    ref: interfaces/openapi.yaml
    visibility: public

  - name: metrics
    type: openapi
    ref: interfaces/metrics.yaml
    visibility: internal

configurations:
  - name: default
    schema: configuration/schema.json
    required: true

workload: service

state:
  type: stateless
  persistence:
    scope: local
    durability: ephemeral
  dataCriticality: low

capabilities:
  - type: health
    binding:
      type: http
      interface: proxy
      path: /health
  - type: metrics
    binding:
      type: http
      interface: metrics
      path: /metrics

metadata:
  tier: critical
  edge: true
  • state.type: stateless: any instance can serve any request
  • durability: ephemeral: no persistent storage needed
  • visibility: public: the proxy interface is externally reachable; HTTP/HTTPS termination and ports belong to the deployment
  • Capabilities over ports: health and metrics are declared as capabilities bound to the declared interfaces
  • No replica scaling: high availability and autoscaling belong to the deployment, and v2 has no scaling section

Cron Worker

A scheduled batch job: a stateless worker that runs on a cron schedule.

pactoVersion: "2.0"

service:
  name: report-generator
  version: 1.2.0
  owner:
    team: analytics

interfaces:
  - name: health
    type: openapi
    ref: interfaces/health.yaml
    visibility: internal

workload: scheduled

state:
  type: stateless
  persistence:
    scope: local
    durability: ephemeral
  dataCriticality: low

capabilities:
  - type: health
    binding:
      type: http
      interface: health
      path: /ready

metadata:
  schedule: "0 2 * * *"
  timeout: 3600
  • workload: scheduled: runs on a cron schedule
  • No replica scaling: batch workloads scale in the deployment, and v2 has no scaling section
  • Schedule in metadata: the cron expression is platform-specific, so it lives in metadata
  • Health as a capability: the readiness probe binds to the health interface (see capabilities)

For a job that runs once (e.g., a database migration):

workload: job

state:
  type: stateless
  persistence:
    scope: local
    durability: ephemeral
  dataCriticality: low

capabilities:
  - type: health
    binding:
      type: http
      interface: health
      path: /ready

Event Processor

An event-driven service: a stateless consumer that processes messages from a message broker and exposes an HTTP health endpoint.

pactoVersion: "2.0"

service:
  name: order-processor
  version: 1.4.0
  owner:
    team: orders

interfaces:
  - name: order-events
    type: asyncapi
    ref: interfaces/order-events.yaml
    visibility: internal

  - name: health
    type: openapi
    ref: interfaces/health.yaml
    visibility: internal

configurations:
  - name: default
    required: true
    schema: configuration/schema.json
    values:
      BROKER_HOST: rabbitmq.internal
      BROKER_PORT: 5672
      BROKER_CREDENTIALS: secret://vault/order-processor/broker-credentials
      DEAD_LETTER_QUEUE: orders.dlq
      MAX_RETRIES: 3

dependencies:
  - name: rabbitmq
    ref: oci://ghcr.io/acme/rabbitmq-pacto@sha256:0000000000000000000000000000000000000000000000000000000000000000
    required: true
    compatibility: "^3.13.0"

workload: service

state:
  type: stateless
  persistence:
    scope: local
    durability: ephemeral
  dataCriticality: medium

capabilities:
  - type: health
    binding:
      type: http
      interface: health
      path: /health
  - type: metrics
    binding:
      type: http
      interface: health
      path: /metrics

metadata:
  tier: standard
  consumer-group: order-processing
  • type: asyncapi: declares an event-driven interface; the service consumes messages from a broker
  • ref: interfaces/order-events.yaml: the AsyncAPI event schema is bundled and versioned with the service
  • dataCriticality: medium: event processing failures have moderate impact; dead-letter queues provide a safety net
  • Capabilities on the HTTP interface: health and metrics bind to the health OpenAPI interface (see capabilities)
  • Dependency target: the rabbitmq dependency points to the RabbitMQ example, which publishes version 3.13.7 and satisfies the ^3.13.0 compatibility range
  • Secret reference: broker credentials use secret://, an opaque convention the platform resolves at deployment time (see Secret references)

gRPC Service

A gRPC microservice: a user service exposing a gRPC API with internal visibility.

pactoVersion: "2.0"

service:
  name: user-service
  version: 3.2.0
  owner:
    team: identity

interfaces:
  - name: grpc-api
    type: grpc
    ref: interfaces/user-service.yaml
    visibility: internal

  - name: metrics
    type: openapi
    ref: interfaces/metrics.yaml
    visibility: internal

configurations:
  - name: default
    required: true
    schema: configuration/schema.json
    values:
      DB_HOST: user-db.internal
      DB_PORT: 5432
      DB_PASSWORD: secret://vault/user-service/db-password
      CACHE_TTL_SECONDS: 300

dependencies:
  - name: postgres
    ref: oci://ghcr.io/acme/postgres-pacto@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
    required: true
    compatibility: "^16.0.0"

workload: service

state:
  type: stateless
  persistence:
    scope: local
    durability: ephemeral
  dataCriticality: low

capabilities:
  - type: health
  - type: metrics
    binding:
      type: http
      interface: metrics
      path: /metrics

metadata:
  tier: critical
  • type: grpc: the gRPC service descriptor is bundled in the OCI artifact, so the API contract travels with the service version. The ref file must parse as JSON or YAML (see interface types)
  • Health as a capability with no binding: a health capability without an HTTP binding declares that the service implements the gRPC Health Checking Protocol (see capabilities)
  • Metrics over HTTP: the gRPC interface serves application traffic while the metrics capability binds to a separate HTTP interface exposing Prometheus metrics
  • stateless: the service itself holds no state; data lives in PostgreSQL (the postgres dependency resolves to the PostgreSQL example)

Hybrid Cache API

A service with hybrid state: an API that caches data locally for performance and can rebuild its cache from an upstream source. Losing local state slows the service down until the cache warms up again.

pactoVersion: "2.0"

service:
  name: product-catalog
  version: 2.0.1
  owner:
    team: catalog

interfaces:
  - name: rest-api
    type: openapi
    ref: interfaces/openapi.yaml
    visibility: public

  - name: metrics
    type: openapi
    ref: interfaces/metrics.yaml
    visibility: internal

configurations:
  - name: default
    required: true
    schema: configuration/schema.json
    values:
      UPSTREAM_API: https://inventory.internal/api
      CACHE_MAX_SIZE_MB: 512
      CACHE_TTL_SECONDS: 3600
      WARMUP_ON_START: true
      API_KEY: secret://vault/product-catalog/upstream-api-key

dependencies:
  - name: inventory
    ref: oci://ghcr.io/acme/inventory-pacto@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
    required: true
    compatibility: "^1.0.0"

workload: service

state:
  type: hybrid
  persistence:
    scope: local
    durability: persistent
  dataCriticality: low

capabilities:
  - type: health
    binding:
      type: http
      interface: rest-api
      path: /health
  - type: metrics
    binding:
      type: http
      interface: metrics
      path: /metrics

metadata:
  tier: standard
  cache-strategy: write-through
  • state.type: hybrid: the service caches product data locally for fast reads, but can reconstruct the cache from the upstream inventory service on restart
  • durability: persistent: persisting the cache across restarts avoids cold-start latency, and without it the service warms up first
  • dataCriticality: low: the cache is reconstructible; losing it has no business impact beyond temporary performance degradation
  • Capabilities over ports: health binds to the public rest-api interface and metrics to a separate internal interface (see capabilities)
  • Secret reference: the API key for the upstream service uses secret:// so the contract holds a reference to the credential

When to use hybrid

Choose hybrid over stateless when local state persists across restarts to avoid warm-up but the service still functions after losing it; a purely in-memory cache rebuilt on every start is stateless/ephemeral. The state.type table has the full breakdown.

Using examples as dependencies

You can reference these contracts (once published to a registry) as dependencies in your own pacto.yaml:

dependencies:
  - name: postgres
    ref: oci://ghcr.io/acme/postgres-pacto@sha256:abc1230000000000000000000000000000000000000000000000000000000000
    required: true
    compatibility: "^16.0.0"

  - name: redis
    ref: oci://ghcr.io/acme/redis-pacto@sha256:def4560000000000000000000000000000000000000000000000000000000000
    required: false
    compatibility: "^7.0.0"

The ghcr.io/acme/… refs above are placeholders. The one Pacto contract anyone can pull is the dashboard's own, and pacto explain prints it:

pacto explain oci://ghcr.io/trianalab/pacto/dashboard-contract

See the contract reference for the full dependency schema.

Then run pacto graph from the bundle directory to see the resolved tree:

pacto graph .

It prints the service and one line per dependency. A ref it cannot resolve, such as the placeholders above, becomes an error node in the tree, and the command still exits 0.

One contract, many sections

This contract declares most optional sections at once. Use it as a field checklist. Only pactoVersion and service are required. The three sections it leaves out, readiness, metadata and extensions, are in Contract sections, which is the complete list.

pactoVersion: "2.0"

service:
  name: payments-api
  version: 2.1.0
  owner:
    team: payments
    dri: alice

interfaces:
  - name: rest-api
    type: openapi
    ref: interfaces/openapi.yaml
    visibility: public

capabilities:
  - type: health
    binding:
      type: http
      interface: rest-api
      path: /health
  - type: metrics
    binding:
      type: http
      interface: rest-api
      path: /metrics

configurations:
  - name: default
    schema: configuration/schema.json
    required: true

policies:
  - name: platform-policy
    schema: policy/schema.json

dependencies:
  - name: auth
    ref: oci://ghcr.io/acme/auth-pacto:2.0.0
    required: true
    compatibility: "^2.0.0"

workload: service

state:
  type: stateful
  persistence:
    scope: shared
    durability: persistent
  dataCriticality: high

Writing a contract like this is the first step. Next, tools read it: pacto explain and MCP for people and AI assistants. Then, on Kubernetes, the operator checks the running service against it. The model shows the whole loop.