A consumer contract is a machine-readable record of what an application needs from a service. It captures an interaction from the consumer’s point of view: the request it sends and the response it expects. Rather than calling the real provider during the consumer test, the consumer exercises a mock provider; successful tests generate a contract that both sides can use as their shared agreement. section 1.1 section 1.4.1
A contract commonly names the consumer and provider, then records interactions with request and response details. It can also include provider state, matching rules for dynamic values, a version, and environment or deployment tags. The important boundary is that it describes only the consumer’s required format and structure—not provider business logic or side effects in other systems. section 3.3 section 2.6.3
A consumer-driven contract follows a practical handoff cycle:
- Define the smallest interaction the consumer needs, including its request, expected status, and required response fields. section 2.6.3
- Register that interaction with a mock provider and run the consumer code against the mock during a unit-time test. section 1.4.1
- Generate and publish the resulting contract to a shared broker or other accessible location. section 1.4.1 section 4.4
- Replay the expected request against the provider and compare its actual response with the consumer-defined response. section 1.4.2
Movies API contract
A web consumer can declare that GET /movies returns 200 and a list of movie objects containing id, name, and year. Pact registers the expectation, runs fetchMovies against its mock URL, and writes a WebConsumer–MoviesAPI JSON contract with the request, response body, headers, and matching rules. This tests whether the consumer understands the agreed response without contacting the live Movies API. section 4.3.4 section 1.5.1
Consumer contracts catch incompatible changes before deployment. For example, changing a required response field from fullName to name breaks a consumer that still expects fullName. They also let one provider support independent contracts for different consumers, so a mobile app can require an additional favorites field without changing the web app’s agreement. section 1.2
A consumer contract is not an API schema. A schema outlines available structure and constraints, but does not reveal which fields each consumer uses. Contract verification instead preserves those concrete consumer expectations as services evolve. It complements integration testing rather than replacing testing of UI, accessibility, security, performance, or unrelated business rules. section 3.3 section 1.6
Listing 3.1 Pact contract example
"consumer": { #1
"name": "Web"
},
"provider": { #1
"name": "API"
},
"interactions": [ #2
{
"description": "GET user token",
"providerState": "user authentication setup",
"request": {
"method": "GET",
"path": "/token/1234",
"headers": {
"Accept": "application/json, text/plain, */*"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"token": "bearer xxx"
},
"matchingRules": { #3
"$.body.token": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "4.0"
}
}
}
Inspect a concrete Pact JSON contract to see consumer and provider names, an interaction, provider state, request and response fields, and matching rules together. section 3.3
