Skip to content

Pacto for Developers

You own the service, so you own its contract. This guide shows how to write one next to your code: a pacto.yaml file that says what your service exposes, what it needs and how it behaves. Platform engineers, CI and other teams then read the same file instead of asking you.

New to Pacto? Start with the five-minute Quickstart. The CLI reference lists every command and contract sections lists every field.


Your workflow

flowchart LR
    A[Write code] --> B[Infer schemas]
    B --> C[Define pacto.yaml]
    C --> D[pacto validate]
    D --> F[pacto push]
    F --> G[CI / Platform picks it up]

1. Initialize your contract

pacto init my-service

This creates a my-service/ directory (a bundle: the contract plus the files it points to) with a valid starter contract. Edit pacto.yaml to match your service.

2. Infer schemas from your code (optional)

If your config already ships a JSON Schema — for example your Helm chart's values.schema.json — vendor that file into your bundle and point configurations[].schema at it. If it doesn't, the schema-infer plugin generates one from a config file.

Generating a configuration schema

The --option file= path is resolved relative to the bundle directory, not your shell's working directory, so keep the config file inside the bundle. With config.yaml in my-service/:

pacto generate schema-infer my-service --option file=config.yaml -o my-service

This generates my-service/config.schema.json. Reference it in your contract:

configurations:
  - name: default
    required: true
    schema: config.schema.json

Secret leak trap

The plugin leaves your config.yaml sitting in the bundle, and a bundle directory is published whole. pacto pack and pacto push upload every file under it, so pacto pull hands your config values, secrets included, to anyone who can read the artifact. The input is not part of the contract — the schema inferred from it is. Delete it once the schema exists, or list it in .pactoignore if you want to keep it beside the contract.

Generating an OpenAPI spec

If your service exposes an HTTP API using FastAPI or Huma, use the openapi-infer plugin to extract an OpenAPI 3.1 spec from your source code:

# Auto-detect framework — FastAPI or Huma only (generates interfaces/openapi.yaml)
pacto generate openapi-infer my-service -o my-service

# Override framework detection
pacto generate openapi-infer my-service -o my-service --option framework=fastapi

Both plugins live in a separate repository and are not part of the pacto binary. The installer script fetches them alongside the CLI; go install and make build do not. See Official plugins for how to get them.

3. Define the contract

See Contract sections for interfaces, workload, state and capabilities; Dependencies and state for dependencies; and Configuration and policy for configurations and policies.

4. Validate and push

pacto validate my-service
pacto push oci://ghcr.io/your-org/my-service-pacto -p my-service

See Validation layers for the rules and error codes. push validates before uploading; use --force to overwrite an existing tag.

Running on Kubernetes? The operator can then check what your service actually does on the network against this contract. See runtime conformance.


See also