Contract Testing
Status: Beta — This feature is fully functional but may receive breaking changes in future releases. Enable it in User Settings → “Enable Contract Testing”.
Contract testing validates that your mocks, API implementations, and specifications stay in sync. It catches mock drift (when mocks diverge from specs), breaking changes (when spec updates break consumers), and provider violations (when real APIs don’t match their contracts).


Tip: Code examples are available for cURL, CLI, and SDK clients (Go, Python, Java). See the SDK Guide for installation and setup. See the CLI User Guide for the command-line tool.
About URLs in examples: All examples use
localhost:5770as the default Mockarty address. If your instance runs on a remote server, replacelocalhost:5770with its actual address (e.g.https://mockarty.company.comorhttp://192.168.1.50:5770). See Tips & Useful Features for details.
Why Contract Testing?
In microservices architectures, teams depend on API contracts. When contracts break silently:
- Mocks return data that the real API no longer provides
- New required fields appear without consumers being updated
- Response types change and break deserialization
- Endpoints get removed without deprecation
Contract testing catches these issues before they reach production.
Three Validation Modes
1. Mock Validation
Validates that your Mockarty mock responses conform to the OpenAPI specification.
What it checks:
- Required fields are present in mock responses
- Field types match the schema (string, integer, array, etc.)
- Enum values are valid
- String patterns and format constraints (email, UUID, date)
- Min/max length and numeric bounds
- Nested object structure
Template-aware: Mockarty template expressions ($.fake.Email, $.req.userId) are detected and skipped for type validation — only structural checks are performed on templated payloads.
Usage:
- Go to Contract Testing → Validate Mocks tab
- Paste your OpenAPI spec (JSON or YAML) or provide a URL
- Optionally filter by tags
- Click Run Validation
API:
cURL
curl -X POST http://localhost:5770/api/v1/contract/validate-mocks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"specContent": "...",
"namespace": "default"
}'
CLI
mockarty-cli contract validate --spec openapi.yaml
Go
result, err := client.Contracts().ValidateMocks(ctx, &mockarty.ContractValidationRequest{
Spec: "...",
Namespace: "default",
})
Python
result = client.contracts.validate_mocks(spec_content="...", namespace="default")
Java
var result = client.contracts().validateMocks("...", "default");
2. Provider Verification
Sends real HTTP requests to your API and validates that responses match the OpenAPI specification.
What it checks:
- Response status codes are documented in the spec
- Response body matches the schema for each status code
- All documented endpoints are reachable
Usage:
- Go to Contract Testing → Verify Provider tab
- Provide the OpenAPI spec
- Enter the base URL of the real API (e.g.,
http://localhost:8080) - Optionally add authorization headers
- Click Run Verification
API:
cURL
curl -X POST http://localhost:5770/api/v1/contract/verify-provider \
-H "Content-Type: application/json" \
-d '{
"specUrl": "https://api.example.com/openapi.json",
"baseUrl": "http://localhost:8080",
"headers": {"Authorization": "Bearer token123"}
}'
CLI
mockarty-cli contract verify --spec openapi.json --target http://localhost:8080
Go
result, err := client.Contracts().VerifyProvider(ctx, &mockarty.ContractValidationRequest{
SpecURL: "https://api.example.com/openapi.json",
TargetURL: "http://localhost:8080",
})
Python
result = client.contracts.verify_provider(
spec_url="https://api.example.com/openapi.json",
base_url="http://localhost:8080",
headers={"Authorization": "Bearer token123"},
)
Java
var result = client.contracts().verifyProvider(
"https://api.example.com/openapi.json",
"http://localhost:8080",
Map.of("Authorization", "Bearer token123")
);
3. Backward Compatibility Check
Compares two versions of an API specification and detects breaking changes.
Breaking changes detected:
- Removed endpoints or HTTP methods
- Removed response fields (consumers depend on them)
- New required request parameters or body fields
- Type changes (e.g.,
string→integer) - Nullable → non-nullable changes
Non-breaking changes reported:
- New endpoints (additive)
- New optional fields
- Removed parameters (non-breaking for consumers)
Usage:
- Go to Contract Testing → Compatibility tab
- Paste the old (baseline) spec on the left
- Paste the new (proposed) spec on the right
- Click Run Check
API:
cURL
curl -X POST http://localhost:5770/api/v1/contract/check-compatibility \
-H "Content-Type: application/json" \
-d '{
"oldSpecContent": "...",
"newSpecContent": "..."
}'
CLI
# Note: check-compatibility is available via API and SDK; CLI support is planned.
# Use cURL or SDK for now:
curl -X POST http://localhost:5770/api/v1/contract/check-compatibility \
-H "Content-Type: application/json" \
-d '{"oldSpecContent": "...", "newSpecContent": "..."}'
Go
result, err := client.Contracts().CheckCompatibility(ctx, map[string]string{
"oldSpecContent": "...",
"newSpecContent": "...",
})
Python
result = client.contracts.check_compatibility(
old_spec_content="...",
new_spec_content="...",
)
Java
var result = client.contracts().checkCompatibility("...", "...");
Multi-Protocol Support
Contract testing works across multiple protocols:
| Protocol | Spec Format | What’s Validated |
|---|---|---|
| HTTP/REST | OpenAPI/Swagger | Response schema, status codes, required fields, types |
| GraphQL | GraphQL Schema (SDL/introspection) | Query/mutation fields exist, return types match |
| gRPC | Service definitions | Services and methods exist in proto |
| SOAP | Operation definitions | Operations exist in WSDL |
| MCP | MCP Tool definitions | Tools and resources exist and match schema |
| AsyncAPI | AsyncAPI Spec | Channel and message schema validation |
Export Formats
Contract test results can be exported for CI/CD integration:
| Format | Use Case | Content-Type |
|---|---|---|
| JSON | CI/CD processing, custom integrations, storage | application/json |
CI/CD Integration
GitHub Actions
- name: Contract Validation
run: |
RESULT=$(curl -s -o /tmp/contract-report.xml -w "%{http_code}" \
-X POST $MOCKARTY_URL/api/v1/contract/validate-mocks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MOCKARTY_TOKEN" \
-d "{\"specUrl\": \"$SPEC_URL\", \"exportFormat\": \"json\"}")
if [ "$RESULT" != "200" ]; then
echo "Contract validation request failed"
exit 1
fi
- name: Publish Test Results
uses: dorny/test-reporter@v1
with:
name: Contract Tests
path: /tmp/contract-report.xml
reporter: json
GitLab CI
contract-test:
script:
- curl -s -X POST "$MOCKARTY_URL/api/v1/contract/check-compatibility"
-H "Content-Type: application/json"
-d "{\"oldSpecContent\": \"$(cat old-spec.json)\", \"newSpecContent\": \"$(cat new-spec.json)\", \"exportFormat\": \"json\"}"
-o contract-results.xml
artifacts:
reports:
json: contract-results.json
AI Agent Integration
The contract testing sub-agent can be invoked from Agent Chat:
- “Validate my mocks against the OpenAPI spec”
- “Check backward compatibility between these two specs”
- “Verify that our API matches the spec”
- “Are there any breaking changes in the new API version?”
Findings Reference
| Finding Type | Severity | Description |
|---|---|---|
missing_required |
error | Required field missing from response |
type_mismatch |
error | Value type doesn’t match schema |
enum_violation |
error | Value not in allowed enum list |
constraint_violation |
error | Min/max/pattern constraint violated |
removed_endpoint |
error | Endpoint removed (breaking) |
removed_field |
error | Response field removed (breaking) |
added_required |
error | New required parameter (breaking) |
type_change |
error | Field type changed (breaking) |
undocumented_endpoint |
warning | Mock endpoint not in spec |
undocumented_status |
warning | Status code not documented |
format_violation |
warning | String format doesn’t match |
additional_property |
warning | Extra field not in schema |
added_endpoint |
info | New endpoint added (non-breaking) |
Quick Start: 3 Steps to Contract Testing
Getting started takes less than 5 minutes:
Step 1: Enable the feature
Go to User Settings (gear icon) → check “Enable Contract Testing”. The “Contracts” item appears in the sidebar.
Step 2: Run your first validation
Open the Contract Testing page → paste your OpenAPI spec → click “Run Validation”. You’ll instantly see which mocks drift from the contract.
Step 3: Add to CI/CD
Copy the curl command from the docs and add it to your pipeline. Results are returned in JSON format for integration with your CI/CD tools.
Real-World Use Cases
For QA Engineers
- Before release: Run mock validation to ensure test doubles match the latest API spec
- After API update: Run backward compatibility check to find breaking changes before they reach consumers
- Regression testing: Schedule periodic provider verification to catch API drift early
For Developers
- During development: Validate your mock responses while building them — catch schema mismatches instantly
- In pull requests: Add contract checks to CI — block merges that introduce breaking changes
- API-first workflow: Write the spec first, then validate that both mocks and implementation match
For DevOps / SRE
- Continuous monitoring: Schedule contract validation every 6 hours — get notified when something drifts
- Multi-environment: Run provider verification against staging and production to compare
- Audit trail: History tab shows all validation runs with who ran them and when
Notifications
When scheduled contract validation detects issues, Mockarty can notify your team through the configured notification channels.
Setting Up Notifications
- Configure at least one notification channel in Admin → Notification Channels (Slack, Telegram, Email, Teams, Discord, etc.)
- Create a contract config in the Contract Testing page with a cron schedule
- When scheduled validation finds errors, a notification is sent to the channel with:
- Number of violations found
- List of breaking changes (if any)
- Link to the full report in Mockarty UI
Webhook Integration
You can also use the Mockarty Webhooks system to trigger external actions when contract tests fail:
# Example: check contract and post result to Slack
RESULT=$(curl -s -X POST "$MOCKARTY_URL/api/v1/contract/validate-mocks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"specUrl": "https://api.example.com/spec.json"}')
ERRORS=$(echo "$RESULT" | jq '.summary.errors')
if [ "$ERRORS" -gt "0" ]; then
curl -X POST "$SLACK_WEBHOOK" \
-d "{\"text\": \"Contract validation failed: $ERRORS errors found\"}"
fi
How Contract Testing Helps Your Product
| Without Contract Testing | With Contract Testing |
|---|---|
| Mocks silently drift from real API | Instant notification when mock diverges from spec |
| Breaking changes discovered in production | Breaking changes caught in CI before merge |
| Manual spec review in pull requests | Automated backward compatibility check |
| “Works on my machine” with stale mocks | Continuous validation ensures mock freshness |
| Hours debugging integration failures | Precise finding: “field X removed in response” |
API Registry (Internal Marketplace)
The API Registry is an internal marketplace where teams publish their API specifications. Other teams can subscribe to specific endpoints they depend on, and get automatic notifications when breaking changes occur.
How It Works
- Publish: Each team publishes their API spec (OpenAPI, gRPC, GraphQL, MCP) to the shared registry
- Subscribe: Other teams subscribe to the endpoints they use, marking which parts are critical
- Monitor: The scheduler periodically checks specs for changes and runs compatibility checks
- Alert: When breaking changes affect subscribers, they get notified automatically
- Generate: Teams can generate mocks directly from registry entries with one click
Publishing an API
cURL
curl -X POST "$MOCKARTY_URL/api/v1/contract/registry" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"serviceName": "UserService",
"specType": "openapi",
"version": "2.1.0",
"description": "User management API",
"visibility": "public",
"specUrl": "https://api.internal.com/user-service/openapi.json"
}'
Go
entry, err := client.Contracts().PublishToRegistry(ctx, &mockarty.RegistryEntry{
ServiceName: "UserService",
SpecType: "openapi",
Version: "2.1.0",
Description: "User management API",
Visibility: "public",
SpecURL: "https://api.internal.com/user-service/openapi.json",
})
Python
entry = await client.contracts.publish_to_registry(
service_name="UserService",
spec_type="openapi",
version="2.1.0",
description="User management API",
visibility="public",
spec_url="https://api.internal.com/user-service/openapi.json",
)
Java
var entry = client.contracts().publishToRegistry(Map.of(
"serviceName", "UserService",
"specType", "openapi",
"version", "2.1.0",
"description", "User management API",
"visibility", "public",
"specUrl", "https://api.internal.com/user-service/openapi.json"
));
Supported spec types: openapi, grpc, graphql, mcp, asyncapi, wsdl
Visibility levels:
- public — visible to all namespaces
- internal — visible within the organization
- restricted — visible only to the publishing namespace
Subscribing to an API
cURL
curl -X POST "$MOCKARTY_URL/api/v1/contract/registry/{id}/subscribe" \
-H "Content-Type: application/json" \
-d '{
"serviceName": "OrderService",
"watchEndpoints": ["GET /api/users/:id", "GET /api/users"],
"notifyOnBreaking": true,
"autoBlock": false
}'
Go
sub, err := client.Contracts().Subscribe(ctx, registryEntryID, &mockarty.Subscription{
ServiceName: "OrderService",
WatchEndpoints: []string{"GET /api/users/:id", "GET /api/users"},
NotifyOnBreaking: true,
})
Python
sub = await client.contracts.subscribe(
registry_entry_id=entry_id,
service_name="OrderService",
watch_endpoints=["GET /api/users/:id", "GET /api/users"],
notify_on_breaking=True,
)
Java
var sub = client.contracts().subscribe(entryId, Map.of(
"serviceName", "OrderService",
"watchEndpoints", List.of("GET /api/users/:id", "GET /api/users"),
"notifyOnBreaking", true
));
Checking Impact Before Publishing Changes
Before updating your API, check who would be affected:
curl -X POST "$MOCKARTY_URL/api/v1/contract/registry/{id}/check-impact" \
-H "Content-Type: application/json" \
-d '{"newSpecContent": "..."}'
Response:
{
"isCompatible": false,
"breakingChanges": 2,
"changedEndpoints": ["GET /api/users/:id"],
"affectedTeams": [
{"namespace": "commerce", "serviceName": "OrderService", "autoBlock": false}
],
"blocked": false
}
Generating Mocks from Registry
Turn any published API into mocks with one click:
curl -X POST "$MOCKARTY_URL/api/v1/contract/registry/{id}/generate-mocks" \
-H "Authorization: Bearer $TOKEN"
Mocks are tagged with registry, source:registry, service:Name, team:Namespace.
Automatic Spec Monitoring
The scheduler periodically checks registry entries with URLs for changes:
- Detects spec modifications via SHA256 hash comparison
- Runs backward compatibility check on changes
- Notifies affected subscribers about breaking changes
- Processes at most 10 entries per cycle to avoid overloading
Consumer-Driven Contracts (Pact)
This feature implements the consumer-driven contract testing pattern popularized by Pact.
Consumer-Driven Contracts flip the testing model: instead of the provider defining the contract, each consumer publishes what it needs from the provider. The provider then verifies its implementation against all consumer contracts.
Why Consumer-Driven?
| Spec-as-Contract (OpenAPI) | Consumer-Driven (Pact) |
|---|---|
| Provider defines the full spec | Consumers define only what they need |
| Changes reviewed manually | Changes auto-verified against all consumers |
| No deployment safety check | “Can I Deploy?” blocks unsafe deployments |
| Full spec required upfront | Minimal contracts, grow incrementally |
Workflow
1. Consumer writes a Pact test → generates Pact JSON
2. Consumer CI publishes Pact to Mockarty: POST /api/v1/contract/pacts
3. Provider CI runs verification: POST /api/v1/contract/pacts/verify
4. Before deploy: POST /api/v1/contract/pacts/can-i-deploy
5. (Optional) Auto-generate mocks from Pact interactions
Publishing a Pact
From your consumer CI/CD pipeline:
cURL
curl -X POST "$MOCKARTY_URL/api/v1/contract/pacts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "{\"pactContent\": $(cat pact.json | jq -Rs .), \"version\": \"$GIT_SHA\"}"
Go
pact, err := client.Contracts().PublishPact(ctx, &mockarty.Pact{
Spec: string(pactJSON),
Version: gitSHA,
})
Python
pact = client.contracts.publish_pact(pact_content=pact_json, version=git_sha)
Java
var pact = client.contracts().publishPact(pactJson, gitSha);
Pact File Format
Mockarty accepts all three specification versions produced by the
pact-foundation ecosystem: v2 (legacy inline matching rules), v3
(the current stable format), and v4 (binary-safe body envelopes and
nested matching rule categories). All three shapes are normalised on
ingest, so consumer libraries — pact-js, pact-python, pact-jvm,
pact-rust, pact-go — can publish directly without conversion.
In addition to HTTP interactions, Mockarty verifies message
interactions from v4 pact files — both Asynchronous/Messages and
Synchronous/Messages. Async messages are verified by POSTing a
{description, providerStates, requestContents} envelope to a
provider-supplied callback URL; the response contents and
metadata are matched against the pact using the same rule engine
used for HTTP bodies. Synchronous messages additionally match the
first expected reply variant from response[] in the pact against
the callback reply. Messages and HTTP interactions can live in the
same pact — Mockarty dispatches each to the appropriate verifier and
reports one aggregated result.
A v3 example:
{
"consumer": { "name": "OrderService" },
"provider": { "name": "UserService" },
"interactions": [
{
"description": "get user by ID",
"request": { "method": "GET", "path": "/api/users/123" },
"response": {
"status": 200,
"body": { "id": 123, "name": "John" },
"matchingRules": {
"$.body.id": { "matchers": [{ "match": "type" }] },
"$.body.name": { "matchers": [{ "match": "type" }] }
}
}
}
]
}
Matching Rules
Mockarty implements the full pact-reference matcher catalogue. For
scalar matchers the rule is terminal: the value at that path is
validated and descent stops. For type / min / max applied to a
composite (object or array), the top-level rule fires and child paths
are still walked so nested rules can trigger.
| Rule | Description | Example |
|---|---|---|
equality |
Exact value match (default when match is omitted) |
{"match": "equality", "value": 42} |
type |
Same JSON type as the template value | {"match": "type"} |
regex |
String matches the pattern; an empty pattern is rejected | {"match": "regex", "regex": "^[A-Z]{2}\\d+$"} |
integer |
Numeric value with no fractional part | {"match": "integer"} |
decimal |
Numeric value | {"match": "decimal"} |
number |
Any number (int or float) | {"match": "number"} |
boolean |
true or false (bool is NOT treated as a number) |
{"match": "boolean"} |
null / notNull |
Value is / is not JSON null |
{"match": "notNull"} |
min |
Array must have at least N elements; every element is validated against the template | {"match": "min", "min": 1} |
max |
Array must have at most N elements | {"match": "max", "max": 100} |
include |
String contains substring | {"match": "include", "value": "@"} |
date |
ISO date; a consumer-supplied regex overrides the default | {"match": "date"} |
time |
HH:MM:SS[.fraction] |
{"match": "time"} |
timestamp / datetime |
RFC 3339 / ISO 8601 datetime with optional offset | {"match": "timestamp"} |
uuid |
Canonical UUID v4 shape | {"match": "uuid"} |
semver |
SemVer 2.0 version | {"match": "semver"} |
ipv4 |
Dotted-quad IPv4 | {"match": "ipv4"} |
contentType |
String prefix match — tolerates ; charset=... parameters |
{"match": "contentType", "value": "application/json"} |
Invalid or empty matcher patterns surface as verification mismatches
rather than being silently skipped — a broken consumer rule must not
turn into a false-green verdict.
Provider Verification
cURL
curl -X POST "$MOCKARTY_URL/api/v1/contract/pacts/verify" \
-H "Content-Type: application/json" \
-d '{
"pactId": "pact-uuid-here",
"providerBaseUrl": "http://localhost:8080",
"headers": {"Authorization": "Bearer test-token"}
}'
Go
result, err := client.Contracts().VerifyPact(ctx, map[string]interface{}{
"pactId": "pact-uuid-here",
"providerBaseUrl": "http://localhost:8080",
"headers": map[string]string{"Authorization": "Bearer test-token"},
})
Python
result = client.contracts.verify_pact(
pact_id="pact-uuid-here",
provider_base_url="http://localhost:8080",
headers={"Authorization": "Bearer test-token"},
)
Java
var result = client.contracts().verifyPact(
"pact-uuid-here",
"http://localhost:8080",
Map.of("Authorization", "Bearer test-token")
);
Can I Deploy?
Before deploying a service, check that all its contracts are verified:
cURL
curl -X POST "$MOCKARTY_URL/api/v1/contract/pacts/can-i-deploy" \
-H "Content-Type: application/json" \
-d '{"participant": "UserService"}'
CLI
mockarty-cli contract can-i-deploy --participant UserService
Go
result, err := client.Contracts().CanIDeploy(ctx, map[string]string{
"participant": "UserService",
})
Python
result = client.contracts.can_i_deploy(participant="UserService")
Java
var result = client.contracts().canIDeploy("UserService");
Response:
{
"deployable": true,
"summary": "UserService: all 3 pact(s) verified successfully",
"matrix": [
{"consumer": "OrderService", "provider": "UserService", "success": true},
{"consumer": "BillingService", "provider": "UserService", "success": true}
]
}
Auto-Generate Mocks from Pacts
Turn consumer contracts into Mockarty mocks with one click:
curl -X POST "$MOCKARTY_URL/api/v1/contract/pacts/{id}/mocks" \
-H "Authorization: Bearer $TOKEN"
This creates HTTP mocks for each interaction, tagged with pact, consumer:Name, provider:Name.
Detect Drift
Compare your mock responses against the real API to find where mocks have diverged from actual behavior:
cURL
curl -X POST http://localhost:5770/api/v1/contract/detect-drift \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"baseUrl": "http://localhost:8080",
"headers": {"Authorization": "Bearer test-token"}
}'
CLI
mockarty-cli contract drift --target http://localhost:8080
Go
report, err := client.Contracts().DetectDrift(ctx, map[string]interface{}{
"baseUrl": "http://localhost:8080",
"headers": map[string]string{"Authorization": "Bearer test-token"},
})
Python
report = client.contracts.detect_drift(
base_url="http://localhost:8080",
headers={"Authorization": "Bearer test-token"},
)
Java
var report = client.contracts().detectDrift(
"http://localhost:8080",
Map.of("Authorization", "Bearer test-token")
);
Pact Broker v2/v3 Compatibility
Mockarty implements a fully compatible Pact Broker API, allowing you to use standard Pact tooling (pact-broker CLI, pact-js, pact-python, pact-jvm, pact-go) without any configuration changes.
Supported Endpoints
| Method | Endpoint | Description |
|---|---|---|
| PUT | /pacts/provider/{provider}/consumer/{consumer}/version/{version} |
Publish pact |
| GET | /pacts/provider/{provider}/consumer/{consumer}/version/{version} |
Get pact |
| GET | /pacts/provider/{provider}/consumer/{consumer}/latest |
Get latest pact |
| GET | /pacts/provider/{provider}/consumer/{consumer}/latest/{tag} |
Get latest by tag |
| DELETE | /pacts/provider/{provider}/consumer/{consumer}/version/{version} |
Delete pact |
| POST | /pacts/provider/{provider}/consumer/{consumer}/pact-version/{version}/verification-results |
Publish verification |
| GET | /can-i-deploy?pacticipant={name}&version={version}&to={env} |
Deployment check (optional to filters by environment tag) |
| GET | /pacticipants |
List participants |
| PUT | /pacticipants/{name}/versions/{version}/tags/{tag} |
Tag version |
| GET | /matrix?q[][pacticipant]={name} |
Compatibility matrix |
Usage with pact-broker CLI
# Configure broker URL
export PACT_BROKER_BASE_URL=http://localhost:5770
# Publish a pact
pact-broker publish ./pacts --consumer-app-version=1.0.0
# Can I Deploy? — environment-aware form:
pact-broker can-i-deploy --pacticipant=MyService --version=1.0.0 --to=production
# Tag a version
pact-broker create-version-tag --pacticipant=MyService --version=1.0.0 --tag=production
Usage with pact-js
const { Publisher } = require('@pact-foundation/pact');
new Publisher({
pactBroker: 'http://localhost:5770',
pactFilesOrDirs: ['./pacts'],
consumerVersion: '1.0.0',
}).publishPacts();
Usage with pact-python
from pact import Broker
broker = Broker(broker_base_url='http://localhost:5770')
broker.publish('ConsumerApp', '1.0.0', pact_dir='./pacts')
Limitations
- Template expressions: Mock responses using template expressions (
$.fake.*,$.req.*, etc.) are validated for structure only (e.g., required fields). Type-specific checks may produce warnings for templated values - Data persistence: Contract testing data is stored in the database. Ensure your Mockarty instance has a configured database for persistent storage
- HTTP only for provider verification: Provider verification sends HTTP requests only; gRPC/GraphQL introspection is planned
- Consumer-Driven Contracts: Accepts Pact v2, v3, and v4 JSON — all three are normalised to the internal flat shape on ingest. Provider state callbacks are optional. Both HTTP and message interactions (
Asynchronous/MessagesandSynchronous/Messages) from v4 pacts are verified; the latter via an HTTP callback endpoint supplied per verification run.
Chaos Testing Integration
Contract testing and Chaos Engineering work together to ensure your services are both correct and resilient.
How They Complement Each Other
| Contract Testing | Chaos Engineering |
|---|---|
| Validates API correctness (schema, types, required fields) | Tests system behavior under failures (pod kills, network partitions) |
| Catches breaking changes before deployment | Catches fragile error handling under stress |
| Static analysis of contracts | Dynamic fault injection in live environments |
Combined Workflow
- Pre-deployment: Run contract validation to ensure mocks match specs and no breaking changes exist
- Post-deployment: Run chaos experiments to verify the service handles failures gracefully
- Continuous: Schedule both contract validation and chaos experiments on a cron to detect regressions
Example: Contract + Chaos Pipeline
# GitHub Actions: validate contracts, then run chaos experiments
- name: Contract Validation
run: |
curl -s -X POST $MOCKARTY_URL/api/v1/contract/validate-mocks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"specUrl": "$SPEC_URL"}'
- name: Chaos Experiment (after deploy)
run: |
curl -s -X POST $MOCKARTY_URL/api/v1/chaos/experiments \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"preset": "network-partition", "target": {"namespace": "staging"}}'
When a chaos experiment reveals that a service fails under stress, use contract testing to verify that the error responses still conform to the API contract – ensuring consumers can handle failures gracefully.
Consumer Contracts (Dependency Bundles)
Consumer contracts declare which provider APIs your service depends on, which endpoints you use, and which fields are critical — both in requests (what you send) and responses (what you read). This enables bidirectional deployment safety checks: if a provider removes a field you depend on, the contract catches it before deployment.
A contract tracks three types of field dependencies per endpoint:
| Field Type | Description | Example |
|---|---|---|
| Response Fields | Fields your service reads from the response body | $.user.email, $.order.total |
| Request Fields | Fields your service sends in the request body | $.body.email, $.body.password |
| Parameters | URL path, query, and header parameters your service uses | $.param.id (path), $.param.limit (query) |
Supported protocols: OpenAPI/REST, gRPC, GraphQL, MCP, WSDL/SOAP, AsyncAPI.
Creating a Consumer Contract
Use the visual wizard in the UI (Contracts tab > New Contract) which guides you through provider selection, endpoint selection, and field configuration. Or use the API:
curl -X POST $MOCKARTY_URL/api/v1/contract/consumer-contracts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "OrderService",
"dependencies": [
{
"registryEntryId": "user-service-api-id",
"providerName": "UserService",
"providerVersion": "latest",
"endpoints": [
{
"route": "GET /api/users/{id}",
"protocol": "openapi",
"expectedStatus": [200],
"requiredFields": [
{"path": "$.id", "type": "integer", "required": true},
{"path": "$.email", "type": "string", "required": true}
],
"requiredParameters": [
{"path": "$.param.id", "type": "string", "required": true}
]
},
{
"route": "PUT /api/users/{id}",
"protocol": "openapi",
"expectedStatus": [200],
"requiredFields": [
{"path": "$.id", "type": "string", "required": true}
],
"requiredRequestFields": [
{"path": "$.body.email", "type": "string", "required": true},
{"path": "$.body.name", "type": "string", "required": true}
],
"requiredParameters": [
{"path": "$.param.id", "type": "string", "required": true}
]
}
]
}
],
"tags": ["critical"]
}'
CLI
# List consumer contracts
mockarty-cli contract consumer-contracts list
# Check a contract
mockarty-cli contract consumer-contracts check --id <contract-id>
# Bidirectional deploy check
mockarty-cli contract deploy-check --role consumer --contract-id <id>
mockarty-cli contract deploy-check --role provider --registry-id <id> --spec new-api.yaml
Can I Deploy? (V2 – Bidirectional)
The enhanced “Can I Deploy?” supports two perspectives:
- As Consumer: “Will my dependencies break me?” – checks your contract against current provider specs
- As Provider: “Will my changes break others?” – checks your new spec against all consumer contracts
# Consumer check
curl -X POST $MOCKARTY_URL/api/v1/contract/can-i-deploy \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"role": "consumer", "contractId": "order-service-contract-id"}'
# Provider pre-deploy check
curl -X POST $MOCKARTY_URL/api/v1/contract/can-i-deploy \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"role": "provider", "registryEntryId": "user-api-id", "newSpec": "{...}"}'
API Registry Version History
Registry entries maintain a version history (up to 10 versions). Compare versions and rollback when needed.
# List versions
curl $MOCKARTY_URL/api/v1/contract/registry/<id>/versions \
-H "Authorization: Bearer $TOKEN"
# Compare two versions
curl $MOCKARTY_URL/api/v1/contract/registry/<id>/versions/1/diff/2 \
-H "Authorization: Bearer $TOKEN"
# Rollback to a previous version
curl -X POST $MOCKARTY_URL/api/v1/contract/registry/<id>/versions/1/rollback \
-H "Authorization: Bearer $TOKEN"
Health Dashboard
Monitor the health of all contracts in your namespace:
curl $MOCKARTY_URL/api/v1/contract/health \
-H "Authorization: Bearer $TOKEN"
Returns traffic-light status (green/yellow/red) per contract based on provider availability, spec changes, and verification results.
See Also
- API Reference – Full REST API documentation
- Chaos Engineering – Fault injection and resilience testing
- Fuzzing – Automated security testing for your APIs
- Performance Testing – Load testing your APIs with JavaScript scripts