Docs Contract Testing

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).

Contracts — drift report
Contracts — Pact import

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:5770 as the default Mockarty address. If your instance runs on a remote server, replace localhost:5770 with its actual address (e.g. https://mockarty.company.com or http://192.168.1.50:5770). See Tips & Useful Features for details.

OpenAPI Spec Contract source of truth Mockarty Mocks Real API Contract Engine Mock Validation Provider Verification Compatibility Check Multi-protocol Report Findings + Severity JSON CI/CD integration validate compare verify

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:

  1. Go to Contract TestingValidate Mocks tab
  2. Paste your OpenAPI spec (JSON or YAML) or provide a URL
  3. Optionally filter by tags
  4. 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:

  1. Go to Contract TestingVerify Provider tab
  2. Provide the OpenAPI spec
  3. Enter the base URL of the real API (e.g., http://localhost:8080)
  4. Optionally add authorization headers
  5. 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., stringinteger)
  • Nullable → non-nullable changes

Non-breaking changes reported:

  • New endpoints (additive)
  • New optional fields
  • Removed parameters (non-breaking for consumers)

Usage:

  1. Go to Contract TestingCompatibility tab
  2. Paste the old (baseline) spec on the left
  3. Paste the new (proposed) spec on the right
  4. 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

  1. Configure at least one notification channel in Admin → Notification Channels (Slack, Telegram, Email, Teams, Discord, etc.)
  2. Create a contract config in the Contract Testing page with a cron schedule
  3. 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

  1. Publish: Each team publishes their API spec (OpenAPI, gRPC, GraphQL, MCP) to the shared registry
  2. Subscribe: Other teams subscribe to the endpoints they use, marking which parts are critical
  3. Monitor: The scheduler periodically checks specs for changes and runs compatibility checks
  4. Alert: When breaking changes affect subscribers, they get notified automatically
  5. 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/Messages and Synchronous/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

  1. Pre-deployment: Run contract validation to ensure mocks match specs and no breaking changes exist
  2. Post-deployment: Run chaos experiments to verify the service handles failures gracefully
  3. 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