Skip to content

Quickstart

From zero to a published contract in 2 minutes.


1. Install Pacto

curl -fsSL https://raw.githubusercontent.com/TrianaLab/pacto/main/scripts/get-pacto.sh | bash

Or via Go:

go install github.com/trianalab/pacto/v2/cmd/pacto@latest

See Installation for more options.

2. Scaffold a contract

$ pacto init my-service
Created my-service/
  my-service/pacto.yaml
  my-service/interfaces/
  my-service/configuration/

This scaffolds a bundle with a valid contract, a placeholder OpenAPI spec and a configuration JSON Schema. Only pacto.yaml is required — if your service doesn't use them, remove the interfaces/ and configuration/ directories along with the interfaces:/configurations: sections and any fields that reference them (the scaffold's runtime.health.interface and runtime.metrics.interface both point at the api interface) in pacto.yaml (deleting the directories alone breaks validation).

These are standard formats — OpenAPI for interfaces, JSON Schema for configuration — so you can drop in the interface files you already own (for example your Helm chart's values.schema.json) instead of authoring new ones. Pacto composes the interfaces you already have rather than inventing a config language.

3. Validate

$ pacto validate my-service
my-service is valid

Validation runs four layers — structural, cross-field, semantic and policy enforcement. See the Contract Reference for the full rules.

4. Customize your contract

Edit my-service/pacto.yaml to match your service. A minimal contract only requires pactoVersion and service:

pactoVersion: "1.2"

service:
  name: my-service
  version: 1.0.0
  owner:
    team: backend

Add sections as needed — interfaces, runtime semantics, dependencies, configuration, policy, scaling, readiness. See the Contract Reference for every available field.

5. Add readiness (optional, v1.2)

The readiness section declares operational readiness state for the service. It requires pactoVersion: "1.2" — declaring it under 1.0 or 1.1 is rejected at validation. Add at least one check with a status:

pactoVersion: "1.2"

readiness:
  expires: 2099-12-31
  minScore: 80
  checks:
    - id: dashboard
      type: url
      status: done
      category: observability
      weight: 20
      evidence: https://grafana.example.com/d/service-dashboard
      description: Grafana dashboard exists

    - id: runbook
      type: document
      status: partial
      category: documentation
      weight: 15
      evidence: docs/runbook.md
      description: Basic runbook exists

Then run the opt-in readiness gate:

$ pacto validate my-service --readiness

The gate derives a score from check statuses and weights, comparing it against minScore. The result is time-dependent (expired assessments score 0), so plain pacto validate does not enforce it. See Contract Reference for the full scoring and gate semantics.

6. Pack and push

# Create a tar.gz bundle
$ pacto pack my-service
Packed my-service@1.0.0 -> my-service-1.0.0.tar.gz

# Authenticate (or use gh auth for GitHub registries)
$ pacto login ghcr.io -u your-username

# Push to any OCI registry (auto-tags with the contract version)
# Skips if the artifact already exists; use --force to overwrite
$ pacto push oci://ghcr.io/your-org/my-service-pacto -p my-service
Pushed my-service@1.0.0 -> ghcr.io/your-org/my-service-pacto:1.0.0
Digest: sha256:a1b2c3...

7. Pull and inspect

# Pull from the registry
$ pacto pull oci://ghcr.io/your-org/my-service-pacto:1.0.0

# Human-readable summary
$ pacto explain my-service
Service: my-service@1.0.0
Owner: backend
Pacto Version: 1.2

Runtime:
  Workload: service
  State: stateless
  Persistence: local/ephemeral
  Data Criticality: low

Interfaces (1):
  - api (http, port 8080, internal)

Scaling: 1-3

# Serve an interactive documentation site
$ pacto doc my-service --serve
Serving documentation at http://127.0.0.1:8484

8. Detect breaking changes

Make a change to your contract (e.g. modify a port number) and diff it against the version you just pushed:

# Edit your contract — change the port in pacto.yaml
# Then diff against the published version
$ pacto diff oci://ghcr.io/your-org/my-service-pacto:1.0.0 my-service
Classification: BREAKING
Changes (1):
  [BREAKING] interfaces.port (modified): interfaces.port modified [8080 -> 9090]

Exit code is non-zero when breaking changes are detected — use this in CI to gate merges. See Detecting breaking changes and the official GitHub Actions integration for wiring this into CI.


What to do next

Goal Guide
Understand every contract field Contract Reference
Write and maintain contracts For Developers
Consume contracts for deployment For Platform Engineers
See contracts for real services Examples (PostgreSQL, Redis, RabbitMQ, NGINX, gRPC, and more)
Integrate with CI/CD GitHub Actions
Explore contracts visually Run pacto dashboard to launch the web UI with dependency graph
Runtime compliance in Kubernetes Kubernetes Operator
Build a generation plugin Plugin Development