--- title: Pact Contract Import, Export & Verification description: Import a Pact v3 consumer contract to create stub expectations, export active expectations as a Pact v3 contract, or verify expectations satisfy a contract — the complete contract-testing loop. shortTitle: Pact Import / Export / Verify layout: page pageOrder: 4 section: 'Verify & Test' subsection: true sitemap: priority: 0.8 changefreq: 'monthly' lastmod: 2026-06-17T00:00:00+00:00 ---
MockServer supports the complete Pact v3 contract-testing loop: import a contract to generate stub expectations, export active expectations as a new contract, and verify that existing expectations satisfy a contract. Each direction is a separate endpoint.
For an overview of how these endpoints fit into a full contract-testing workflow, including the OpenAPI contract-test endpoint (/mockserver/contractTest), see Contract Testing.
Send a PUT request to /mockserver/pact/import with a Pact v3 consumer contract as the request body. MockServer generates one expectation per interaction and returns 201 Created with the generated expectations as JSON.
This is the inverse of the export endpoint below: rather than producing a contract from active expectations, it creates expectations from the contract, turning a published contract into a ready-to-use stub provider.
The same operation is also available at the generic import endpoint with the ?format=pact query parameter, or via auto-detection (a body with a top-level interactions array is auto-detected as Pact). See Importing Expectations for the generic endpoint and redaction options.
For each interaction, the importer builds:
JSON request bodies are matched semantically (key-order and whitespace insensitive). The expectation ID is set to the interaction's description field, or pact-<index> when the description is blank. Re-importing the same contract updates existing expectations in place.
A Pact interaction's provider state — its providerState (v2) or providerStates (v3) "given ..." precondition — is preserved on import. The generated expectation is gated on a scenario named pact-provider-state whose required state is the provider-state name, so the interaction only matches once that provider state has been activated. Interactions without a provider state are unaffected and always match.
During verification MockServer activates each interaction's provider state before matching it, so a contract that uses provider states verifies end-to-end. Provider states are also round-tripped on export. Only the first provider state on an interaction gates matching (a scenario holds one active state at a time).
Pact v3 matchingRules.request are translated to MockServer matcher values:
| Pact rule | MockServer matcher value |
|---|---|
| regex | The supplied regex pattern |
| include | .*<value>.* (substring regex) |
| type / number / integer / decimal / boolean | .+ (any non-empty value) |
| Unrecognised / no rule | The concrete example value (exact match) |
The same redaction rules apply as for HAR and Postman imports: credential-bearing headers and common secret body fields are masked by default. Pass ?redactSensitiveData=false to import values verbatim. See Sensitive Data Redaction for the full list of query parameters.
Each language client has a typed pactImport helper (pact_import / PactImport) that wraps PUT /mockserver/pact/import and returns the upserted expectations. Pass the Pact v3 contract as a JSON string. The REST API tab shows the equivalent raw request.
import org.mockserver.client.MockServerClient;
MockServerClient client = new MockServerClient("localhost", 1080);
String generatedExpectations = client.pactImport("{" +
"\"consumer\": {\"name\": \"frontend\"}," +
"\"provider\": {\"name\": \"users-service\"}," +
"\"interactions\": [{" +
" \"description\": \"get users\"," +
" \"request\": {\"method\": \"GET\", \"path\": \"/api/users\"}," +
" \"response\": {\"status\": 200, \"headers\": {\"content-type\": [\"application/json\"]}, \"body\": {\"users\": []}}" +
"}]," +
"\"metadata\": {\"pactSpecification\": {\"version\": \"3.0.0\"}}" +
"}");
// generatedExpectations holds the upserted expectations as a JSON array string
var mockServerClient = require('mockserver-client').mockServerClient;
var pact = {
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "headers": {"content-type": ["application/json"]}, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
};
mockServerClient("localhost", 1080).pactImport(JSON.stringify(pact)).then(
function (expectations) {
console.log(expectations); // the upserted expectations, one per interaction
},
function (error) {
console.log(error);
}
);
import json
from mockserver.client import MockServerClient
pact = {
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "headers": {"content-type": ["application/json"]}, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}
client = MockServerClient("localhost", 1080)
generated_expectations = client.pact_import(json.dumps(pact))
# generated_expectations holds the upserted expectations as a JSON array string
require 'mockserver-client'
require 'json'
pact = {
"consumer" => { "name" => "frontend" },
"provider" => { "name" => "users-service" },
"interactions" => [{
"description" => "get users",
"request" => { "method" => "GET", "path" => "/api/users" },
"response" => { "status" => 200, "headers" => { "content-type" => ["application/json"] }, "body" => { "users" => [] } }
}],
"metadata" => { "pactSpecification" => { "version" => "3.0.0" } }
}
client = MockServer::Client.new('localhost', 1080)
generated_expectations = client.pact_import(pact.to_json)
# generated_expectations holds the upserted expectations as a JSON array string
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
pactJSON := `{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "headers": {"content-type": ["application/json"]}, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}`
expectations, _ := client.PactImport(pactJSON)
// expectations holds the upserted expectations, one per interaction
using MockServer.Client;
using var client = new MockServerClient("localhost", 1080);
var pactJson = @"{
""consumer"": {""name"": ""frontend""},
""provider"": {""name"": ""users-service""},
""interactions"": [{
""description"": ""get users"",
""request"": {""method"": ""GET"", ""path"": ""/api/users""},
""response"": {""status"": 200, ""headers"": {""content-type"": [""application/json""]}, ""body"": {""users"": []}}
}],
""metadata"": {""pactSpecification"": {""version"": ""3.0.0""}}
}";
var expectations = client.PactImport(pactJson);
// expectations holds the upserted expectations, one per interaction
use mockserver_client::ClientBuilder;
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
let pact_json = r#"{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "headers": {"content-type": ["application/json"]}, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}"#;
let expectations = client.pact_import(pact_json).unwrap();
// expectations holds the upserted expectations, one per interaction
use MockServer\MockServerClient;
$pactJson = <<<'JSON'
{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "headers": {"content-type": ["application/json"]}, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}
JSON;
$client = new MockServerClient('localhost', 1080);
$generatedExpectations = $client->pactImport($pactJson);
// $generatedExpectations holds the upserted expectations as a JSON array string
curl -v -X PUT "http://localhost:1080/mockserver/pact/import" \
-H "Content-Type: application/json" \
-d '{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "headers": {"content-type": ["application/json"]}, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}'
MockServer returns 201 Created with the generated expectations as JSON:
[ {
"id" : "get users",
"httpRequest" : {
"method" : "GET",
"path" : "/api/users"
},
"httpResponse" : {
"statusCode" : 200,
"headers" : {
"content-type" : [ "application/json" ]
},
"body" : "{\"users\":[]}"
}
} ]
Send a PUT request to /mockserver/pact to export the currently active response expectations as a Pact v3 consumer contract JSON document.
| Query parameter | Required | Default | Description |
|---|---|---|---|
| consumer | No | consumer | The consumer name written into the Pact contract's consumer.name field. |
| provider | No | provider | The provider name written into the Pact contract's provider.name field. |
MockServer responds with HTTP 200 and the Pact contract as pretty-printed JSON.
Only expectations that have a concrete HTTP request matcher and a response action are exported. Expectations using forward, callback, or template actions have no direct Pact equivalent and are skipped.
Given an active expectation that mocks GET /api/users, export a Pact contract for the frontend consumer and users-service provider:
Each language client has a typed pactExport(consumer, provider) helper (pact_export / PactExport) that wraps PUT /mockserver/pact and returns the generated Pact v3 contract. The REST API tab shows the equivalent raw request.
import org.mockserver.client.MockServerClient;
MockServerClient client = new MockServerClient("localhost", 1080);
String pactContract = client.pactExport("frontend", "users-service");
// pactContract holds the Pact v3 contract as JSON
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).pactExport("frontend", "users-service").then(
function (pactContract) {
console.log(pactContract); // the Pact v3 contract as JSON
},
function (error) {
console.log(error);
}
);
from mockserver.client import MockServerClient
client = MockServerClient("localhost", 1080)
pact_contract = client.pact_export("frontend", "users-service")
# pact_contract holds the Pact v3 contract as JSON
require 'mockserver-client'
client = MockServer::Client.new('localhost', 1080)
pact_contract = client.pact_export(consumer: 'frontend', provider: 'users-service')
# pact_contract holds the Pact v3 contract as JSON
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
pactContract, _ := client.PactExport("frontend", "users-service")
// pactContract holds the Pact v3 contract as JSON
using MockServer.Client;
using var client = new MockServerClient("localhost", 1080);
var pactContract = client.PactExport("frontend", "users-service");
// pactContract holds the Pact v3 contract as JSON
use mockserver_client::ClientBuilder;
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
let pact_contract = client.pact_export("frontend", "users-service").unwrap();
// pact_contract holds the Pact v3 contract as JSON
use MockServer\MockServerClient;
$client = new MockServerClient('localhost', 1080);
$pactContract = $client->pactExport('frontend', 'users-service');
// $pactContract holds the Pact v3 contract as JSON
curl -v -X PUT "http://localhost:1080/mockserver/pact?consumer=frontend&provider=users-service"
MockServer returns HTTP 200 with the contract as JSON:
{
"consumer" : {
"name" : "frontend"
},
"provider" : {
"name" : "users-service"
},
"interactions" : [ {
"description" : "GET /api/users",
"request" : {
"method" : "GET",
"path" : "/api/users"
},
"response" : {
"status" : 200,
"headers" : {
"content-type" : [ "application/json" ]
},
"body" : {
"users" : [ ]
}
}
} ],
"metadata" : {
"pactSpecification" : {
"version" : "3.0.0"
}
}
}
A typical workflow using MockServer with Pact:
Recordings made through MockServer's proxy/spy mode (see Operating Mode) can also be exported: after recording real traffic through a SPY or CAPTURE session, the captured response expectations appear as active expectations and can be exported directly.
Send a PUT request to /mockserver/pact/verify with a Pact v3 contract as the request body. MockServer verifies that its currently-active expectations satisfy every interaction in the contract.
For each interaction, MockServer:
| HTTP Status | Meaning |
|---|---|
| 202 Accepted | All interactions verified successfully. The response body is a JSON summary with "verified": true. |
| 406 Not Acceptable | One or more interactions failed verification. The response body is a JSON summary with "verified": false and per-interaction failure reasons. |
| 400 Bad Request | The request body is empty, not valid JSON, or contains no interactions. |
The JSON response body contains an overall verified flag and a per-interaction breakdown:
{
"verified" : false,
"interactions" : [ {
"description" : "get users",
"verified" : true
}, {
"description" : "create user",
"verified" : false,
"reason" : "status code mismatch: expected 201 but was 200"
} ]
}
Each language client has a typed pactVerify helper (pact_verify / PactVerify) that wraps PUT /mockserver/pact/verify. The server replies 202 Accepted when every interaction verifies and 406 Not Acceptable otherwise — a FAIL is a normal outcome and does not raise. The return type reflects how each language exposes that pass/fail verdict: Java, Python, and Ruby return the verification report string (inspect its verified flag); Node returns the parsed report object; Go returns (passed bool, report string, err error); Rust returns a PactVerification with passed and report fields; and .NET and PHP return a bool. The REST API tab shows the equivalent raw request.
import org.mockserver.client.MockServerClient;
MockServerClient client = new MockServerClient("localhost", 1080);
String verificationReport = client.pactVerify("{" +
"\"consumer\": {\"name\": \"frontend\"}," +
"\"provider\": {\"name\": \"users-service\"}," +
"\"interactions\": [{" +
" \"description\": \"get users\"," +
" \"request\": {\"method\": \"GET\", \"path\": \"/api/users\"}," +
" \"response\": {\"status\": 200, \"body\": {\"users\": []}}" +
"}]," +
"\"metadata\": {\"pactSpecification\": {\"version\": \"3.0.0\"}}" +
"}");
// verificationReport holds the per-interaction verification result as JSON
var mockServerClient = require('mockserver-client').mockServerClient;
var pact = {
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
};
mockServerClient("localhost", 1080).pactVerify(JSON.stringify(pact)).then(
function (report) {
console.log("verified: " + report.verified); // report carries the per-interaction breakdown
},
function (error) {
console.log(error);
}
);
import json
from mockserver.client import MockServerClient
pact = {
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}
client = MockServerClient("localhost", 1080)
report = client.pact_verify(json.dumps(pact)) # the verification report JSON string
verified = json.loads(report)["verified"]
require 'mockserver-client'
require 'json'
pact = {
"consumer" => { "name" => "frontend" },
"provider" => { "name" => "users-service" },
"interactions" => [{
"description" => "get users",
"request" => { "method" => "GET", "path" => "/api/users" },
"response" => { "status" => 200, "body" => { "users" => [] } }
}],
"metadata" => { "pactSpecification" => { "version" => "3.0.0" } }
}
client = MockServer::Client.new('localhost', 1080)
report = client.pact_verify(pact.to_json) # the verification report JSON string
verified = JSON.parse(report)['verified']
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
pactJSON := `{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}`
passed, report, err := client.PactVerify(pactJSON)
// passed == true when every interaction verified (202); report holds the report JSON
_ = report
_ = err
using MockServer.Client;
using var client = new MockServerClient("localhost", 1080);
var json = @"{
""consumer"": {""name"": ""frontend""},
""provider"": {""name"": ""users-service""},
""interactions"": [{
""description"": ""get users"",
""request"": {""method"": ""GET"", ""path"": ""/api/users""},
""response"": {""status"": 200, ""body"": {""users"": []}}
}],
""metadata"": {""pactSpecification"": {""version"": ""3.0.0""}}
}";
bool verified = client.PactVerify(json);
// verified == true when every interaction verified (202), false otherwise (406)
use mockserver_client::ClientBuilder;
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
let pact_json = r#"{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}"#;
let verification = client.pact_verify(pact_json).unwrap();
// verification.passed == true on 202, false on 406; verification.report holds the report JSON
use MockServer\MockServerClient;
$pactJson = <<<'JSON'
{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}
JSON;
$client = new MockServerClient('localhost', 1080);
$verified = $client->pactVerify($pactJson);
// $verified === true when every interaction verified (202), false otherwise (406)
curl -v -X PUT "http://localhost:1080/mockserver/pact/verify" \
-H "Content-Type: application/json" \
-d '{
"consumer": {"name": "frontend"},
"provider": {"name": "users-service"},
"interactions": [{
"description": "get users",
"request": {"method": "GET", "path": "/api/users"},
"response": {"status": 200, "body": {"users": []}}
}],
"metadata": {"pactSpecification": {"version": "3.0.0"}}
}'
If all interactions verify, MockServer returns HTTP 202:
{
"verified" : true,
"interactions" : [ {
"description" : "get users",
"verified" : true
} ]
}
With import, export, and verify, MockServer supports the complete consumer-driven contract testing loop: