Traffic Recorder
The Traffic Recorder captures live HTTP/HTTPS traffic flowing through Mockarty and turns it into mocks, test collections, and performance scripts. It acts as an intercepting proxy between your application and the real upstream service, recording every request/response pair in real time.
Why Record Traffic?
- Auto-generate mocks from production traffic. Point your staging environment at the recorder, run your test suite, and export the captured traffic as Mockarty mocks. No manual JSON authoring.
- Debug API integration issues. See the exact bytes your application sends and receives, including headers, timing breakdowns (DNS, TLS handshake, TTFB), and compressed vs. decompressed bodies.
- Regression testing. Record a known-good session, export it as a test collection, and replay it on every CI build to catch contract changes.
- Compliance auditing. Keep a timestamped log of all API calls between your services during a compliance window.
- Chaos engineering. Inject latency, jitter, errors, and bandwidth throttling to see how your application handles degraded networks — without touching the upstream service.
Recording Modes
Reverse Proxy
Your application talks to Mockarty (e.g. http://localhost:8085), and Mockarty forwards every request to the real upstream server (e.g. https://api.stripe.com).
App ──► Mockarty :8085 ──► api.stripe.com
│
(records traffic)
Best for: targeting a single upstream service, local development, CI pipelines.
Forward Proxy
Mockarty acts as a classic HTTP proxy. Configure your application (or OS) to use HTTP_PROXY=http://localhost:8085 and all outbound traffic flows through the recorder.
App ──HTTP_PROXY──► Mockarty :8085 ──► any upstream
│
(records traffic)
HTTP requests are fully captured. HTTPS traffic is tunneled via the CONNECT method. To decrypt HTTPS, enable MITM interception.
Starting a Recording Session
Via the UI
- Navigate to Recorder in the sidebar (
/ui/recorder). - Click New Session.
- Choose a mode (Reverse Proxy or Forward Proxy).
- For reverse proxy, enter the Target URL (e.g.
https://api.example.com). - Optionally set the Listen Port (auto-assigned from 8081–8999 if left blank).
- Configure filters, toxics, modifications, MITM, and Map Local as needed.
- Click Start.
The session begins recording immediately. New entries stream into the UI via WebSocket.
Via the API
curl -X POST http://localhost:5770/ui/api/recorder/start \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"name": "Stripe Integration Test",
"mode": "reverse",
"targetUrl": "https://api.stripe.com",
"listenPort": 8085,
"namespace": "default",
"filters": {
"includePaths": ["/v1/*"],
"excludePaths": ["/v1/health"]
},
"toxics": {
"delayMs": 100,
"delayJitter": 50
}
}'
Response:
{
"session": {
"id": "a1b2c3d4-...",
"name": "Stripe Integration Test",
"mode": "reverse",
"targetUrl": "https://api.stripe.com",
"listenPort": 8085,
"status": "running",
"entryCount": 0,
"createdAt": "2026-03-14T10:00:00Z",
"expiresAt": "2026-03-14T14:00:00Z"
}
}
Session Configuration Options
| Field | Type | Description |
|---|---|---|
name |
string | Human-readable label. Auto-generated if empty. |
mode |
"reverse" or "forward" |
Proxy mode. Default: "reverse". |
targetUrl |
string | Upstream URL. Required for reverse proxy. |
listenPort |
int | Port the proxy listens on. Auto-assigned (8081–8999) if 0. |
namespace |
string | Mockarty namespace. Default: "default". |
toxics |
object | Toxicity rules (delay, jitter, errors, bandwidth). |
filters |
object | Scope filters (hosts, paths, methods, status codes). |
modifications |
object | Request/response modification rules. |
mitm |
object | MITM TLS interception config. |
mapLocal |
object | Auto-responder using Mockarty mocks. |
Scope Filters
Filters control which requests are recorded. An empty filter dimension means “allow all”. All pattern strings support glob syntax.
{
"filters": {
"includeHosts": ["api.example.com", "*.internal.corp"],
"excludeHosts": ["telemetry.example.com"],
"includePaths": ["/api/*", "/v2/*"],
"excludePaths": ["/api/healthcheck", "/api/metrics"],
"includeMethods": ["GET", "POST", "PUT"],
"excludeStatus": [304, 204]
}
}
How Filters Are Evaluated
- If
includeHostsis non-empty, the request host must match at least one pattern. - If the host matches any
excludeHostspattern, the request is skipped. - Same logic for
includePaths/excludePaths. - If
includeMethodsis non-empty, the HTTP method must be in the list. - If the response status code is in
excludeStatus, the entry is discarded.
Glob Pattern Examples
| Pattern | Matches |
|---|---|
*.example.com |
api.example.com, auth.example.com |
/api/v1/* |
/api/v1/users, /api/v1/orders |
/api/*/details |
/api/users/details, /api/orders/details |
Toxicity Simulation
Inject artificial degradation into proxied traffic to test how your application handles real-world network conditions.
{
"toxics": {
"delayMs": 200,
"delayJitter": 100,
"errorRate": 0.05,
"bandwidthKBps": 50
}
}
| Field | Type | Description |
|---|---|---|
delayMs |
int | Fixed latency (ms) added before each response. |
delayJitter |
int | Random jitter in the range +-jitter ms, added on top of delayMs. |
errorRate |
float | Fraction of requests to fail with HTTP 503 (0.0 to 1.0). |
bandwidthKBps |
int | Limit response throughput in KB/s. 0 = unlimited. |
Example scenarios:
- Simulate a slow third-party API:
delayMs: 500, delayJitter: 200 - Test circuit breaker activation:
errorRate: 0.3 - Simulate mobile network conditions:
bandwidthKBps: 25, delayMs: 150
Modification Rules
Modify requests and responses as they pass through the proxy. Rules are applied in order. Changes affect what gets sent upstream and what your application receives, but the original request is still captured in the entry.
Header Modifications
{
"modifications": {
"requestHeaders": [
{ "action": "add", "name": "X-Debug", "value": "recorder" },
{ "action": "replace", "name": "Authorization", "value": "Bearer test-token" },
{ "action": "remove", "name": "X-Internal-ID" }
],
"responseHeaders": [
{ "action": "add", "name": "X-Recorded", "value": "true" }
]
}
}
Header rule actions: add, replace, remove.
URL Rewrites
Regex-based URL rewriting with capture group support:
{
"modifications": {
"urlRewrites": [
{
"match": "/api/v1/(.*)",
"replace": "/api/v2/$1"
}
]
}
}
Body Replacements
Replace text in response bodies using plain strings or regex:
{
"modifications": {
"bodyReplacements": [
{
"match": "production-db.internal",
"replace": "localhost:5432",
"isRegex": false
},
{
"match": "\"apiKey\":\\s*\"[^\"]+\"",
"replace": "\"apiKey\": \"REDACTED\"",
"isRegex": true
}
]
}
}
Updating Modifications on a Running Session
You can update modification rules without restarting the session:
curl -X PUT http://localhost:5770/ui/api/recorder/<session-id>/modifications \
-H "Content-Type: application/json" \
-d '{
"modifications": {
"requestHeaders": [
{ "action": "add", "name": "X-Trace", "value": "123" }
]
}
}'
Map Local (Auto-Responder)
When Map Local is enabled, the proxy checks whether a matching Mockarty mock exists before forwarding to the upstream. If a mock matches, its response is served locally without any network call. The entry is flagged with "mapLocal": true.
{
"mapLocal": {
"enabled": true,
"namespace": "staging"
}
}
Use cases:
- Stub out a flaky upstream endpoint during recording.
- Inject specific error responses for edge-case testing.
- Combine real traffic with mocked endpoints in a single session.
SSL/TLS Interception (MITM)
In forward proxy mode, HTTPS traffic is tunneled via CONNECT and encrypted end-to-end by default. To decrypt and record HTTPS request/response bodies, enable MITM interception.
How It Works
- Mockarty generates a self-signed CA certificate (ECDSA P-256, 10-year validity).
- When a CONNECT tunnel is established, Mockarty generates a leaf certificate for the target hostname, signed by the CA.
- Your application (or browser) performs the TLS handshake with Mockarty’s leaf certificate.
- Mockarty opens a separate TLS connection to the real server.
- Decrypted HTTP traffic is recorded, then re-encrypted and forwarded.
Setup
Step 1: Generate the CA
curl -X POST http://localhost:5770/ui/api/recorder/ca/generate
Step 2: Download and trust the CA certificate
curl -o mockarty-ca.pem http://localhost:5770/ui/api/recorder/ca/download
Install the certificate in your OS or browser trust store:
- macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain mockarty-ca.pem - Linux (Ubuntu/Debian): Copy to
/usr/local/share/ca-certificates/mockarty-ca.crtand runsudo update-ca-certificates - Windows: Double-click the
.pemfile and install to “Trusted Root Certification Authorities” - Node.js: Set
NODE_EXTRA_CA_CERTS=mockarty-ca.pem - Go: Set
SSL_CERT_FILE=mockarty-ca.pem
Step 3: Enable MITM when starting a session
curl -X POST http://localhost:5770/ui/api/recorder/start \
-H "Content-Type: application/json" \
-d '{
"mode": "forward",
"mitm": { "enabled": true },
"listenPort": 8085
}'
Step 4: Configure your application
export HTTP_PROXY=http://localhost:8085
export HTTPS_PROXY=http://localhost:8085
All HTTPS traffic will now be decrypted, recorded, and re-encrypted transparently.
Exporting Recorded Traffic
HAR File
Export the session (or selected entries) as a HAR file, compatible with Chrome DevTools, Charles Proxy, and other tools.
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/export \
-H "Content-Type: application/json" \
-d '{ "entryIds": [] }' \
-o recording.har
Pass specific entryIds to export a subset, or an empty array for all entries.
Mock Generation
Convert recorded entries directly into Mockarty mocks:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/mocks \
-H "Content-Type: application/json" \
-d '{
"entryIds": [],
"namespace": "default",
"prefix": "rec-",
"tags": ["recorded", "payment-api"],
"priority": 5
}'
Options:
| Field | Description |
|---|---|
entryIds |
Entries to convert. Empty = all. |
namespace |
Target namespace for created mocks. |
prefix |
ID prefix for generated mocks (e.g. rec-). |
tags |
Tags applied to every generated mock. |
chainId |
Optional chain ID for linking mocks into a workflow. |
forceUpdate |
Overwrite existing mocks with the same ID. |
priority |
Default priority for generated mocks. |
Test Collection
Export entries as an API Tester collection for replay testing:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/export-collection \
-H "Content-Type: application/json" \
-d '{
"collectionName": "Payment Flow Regression",
"namespace": "default",
"protocol": "http"
}'
Set protocol to "tests" to generate a test script with assertions, or "performance" to generate a performance load script.
Performance Script
Export as a standalone JavaScript performance script:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/export-perf \
-H "Content-Type: application/json" \
-d '{ "entryIds": [] }' \
-o perf-script.js
Test Script
Export as a JavaScript test script with assertions:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/export-test \
-H "Content-Type: application/json" \
-d '{ "entryIds": [] }' \
-o test-script.js
Session Management
Limits
| Limit | Value |
|---|---|
| Max concurrent sessions (global) | 30 |
| Max sessions per user | 2 |
| Max entries per session | 1,000 (FIFO eviction) |
| Session auto-expiry | 4 hours |
| Entry retention after stop | 5 days |
| Listen port range (auto-assign) | 8081–8999 |
| Saved configs per user | 10 |
When a session reaches 1,000 entries, the oldest entry is evicted automatically. WebSocket subscribers receive an eviction notification so the UI stays in sync.
Session Lifecycle
- Running — proxy is active, entries are being captured.
- Stopped — proxy is shut down, entries remain accessible for export.
- Expired — session auto-stopped after 4 hours. Entries are retained for 5 days.
Saved Configurations
Save frequently used session configs for quick reuse:
# Save a config
curl -X POST http://localhost:5770/ui/api/recorder/configs \
-H "Content-Type: application/json" \
-d '{
"name": "Stripe Dev",
"mode": "reverse",
"targetUrl": "https://api.stripe.com",
"filters": { "includePaths": ["/v1/*"] }
}'
# List saved configs
curl http://localhost:5770/ui/api/recorder/configs
# Export a config as JSON
curl http://localhost:5770/ui/api/recorder/configs/<config-id>/export -o config.json
# Import a config from JSON
curl -X POST http://localhost:5770/ui/api/recorder/configs/import \
-H "Content-Type: application/json" \
-d @config.json
Real-Time Streaming
Connect a WebSocket to receive entries as they are captured:
ws://localhost:5770/ui/api/recorder/<session-id>/ws
Each message is a JSON object:
{
"type": "entry",
"entry": {
"id": "...",
"entryType": "http",
"request": { "method": "GET", "url": "..." },
"response": { "statusCode": 200 },
"durationMs": 42,
"timings": { "dnsMs": 2, "connectMs": 5, "tlsMs": 12, "waitMs": 20, "totalMs": 42 }
}
}
An eviction notification looks like:
{ "type": "entry", "entry": { "id": "__evict__", "notes": "<evicted-entry-id>" } }
Entry Annotations
Tag and annotate individual entries for later reference:
curl -X PATCH http://localhost:5770/ui/api/recorder/<session-id>/entries/<entry-id> \
-H "Content-Type: application/json" \
-d '{
"tags": ["bug", "timeout"],
"notes": "This request took 8 seconds — investigate upstream latency"
}'
Entry Replay
Replay a captured request against the original (or a different) server:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/entries/<entry-id>/replay \
-H "Content-Type: application/json" \
-d '{
"url": "http://localhost:5770/api/users/123",
"headers": { "Authorization": "Bearer new-token" }
}'
Override any field (method, url, headers, body) or leave the body empty to replay as-is.
API Reference
All endpoints are under /ui/api/recorder. Authentication required.
Sessions
| Method | Path | Description |
|---|---|---|
POST |
/start |
Start a new recording session |
GET |
/sessions |
List sessions for the current user |
GET |
/:id |
Get a single session |
POST |
/:id/stop |
Stop a running session |
POST |
/:id/restart |
Restart a stopped session (same config, new port if needed) |
DELETE |
/:id |
Delete a session and its entries |
Entries
| Method | Path | Description |
|---|---|---|
GET |
/:id/entries?offset=0&limit=100 |
List entries (paginated) |
PATCH |
/:id/entries/:entryId |
Annotate an entry (tags, notes) |
POST |
/:id/entries/:entryId/replay |
Replay a captured request |
GET |
/:id/ws |
WebSocket stream of new entries |
Export
| Method | Path | Description |
|---|---|---|
POST |
/:id/export |
Export as HAR file |
POST |
/:id/export-perf |
Export as performance script |
POST |
/:id/export-test |
Export as test script |
POST |
/:id/export-collection |
Export as API Tester collection |
POST |
/:id/mocks |
Generate Mockarty mocks from entries |
Modifications
| Method | Path | Description |
|---|---|---|
GET |
/:id/modifications |
Get current modification rules |
PUT |
/:id/modifications |
Update modification rules (live) |
CA Certificate (MITM)
| Method | Path | Description |
|---|---|---|
GET |
/ca/status |
Check if a CA exists |
POST |
/ca/generate |
Generate (or return existing) CA |
GET |
/ca/download |
Download CA certificate PEM file |
Saved Configurations
| Method | Path | Description |
|---|---|---|
GET |
/configs |
List saved configs |
POST |
/configs |
Save a new config (max 10 per user) |
DELETE |
/configs/:id |
Delete a saved config |
GET |
/configs/:id/export |
Export config as JSON file |
POST |
/configs/import |
Import config from JSON |
Utility
| Method | Path | Description |
|---|---|---|
GET |
/ports |
Port pool status (used/max/details) |
GET |
/port-check?port=8085 |
Check if a port is available |
Practical Examples
Example 1: Recording a Payment API Integration
Record all traffic between your checkout service and Stripe during a test purchase:
# 1. Start a recording session
curl -X POST http://localhost:5770/ui/api/recorder/start \
-H "Content-Type: application/json" \
-d '{
"name": "Checkout Flow",
"mode": "reverse",
"targetUrl": "https://api.stripe.com",
"filters": {
"includePaths": ["/v1/charges", "/v1/payment_intents", "/v1/customers"],
"includeMethods": ["POST", "GET"]
}
}'
# Returns session ID and listen port (e.g. 8081)
# 2. Point your checkout service at the recorder
export STRIPE_API_BASE=http://localhost:8081
# 3. Run your test purchase flow
./run-checkout-tests.sh
# 4. Stop the session
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/stop
Example 2: Generating Mocks from a Recording
After recording, convert captured traffic into mocks that replay the same responses:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/mocks \
-H "Content-Type: application/json" \
-d '{
"namespace": "checkout-tests",
"prefix": "stripe-",
"tags": ["stripe", "recorded"]
}'
Now your checkout tests can run against Mockarty mocks with no network dependency.
Example 3: Creating Regression Tests
Export the recording as a test collection that asserts status codes and response shapes:
curl -X POST http://localhost:5770/ui/api/recorder/<session-id>/export-collection \
-H "Content-Type: application/json" \
-d '{
"collectionName": "Stripe Regression Suite",
"protocol": "tests"
}'
The collection appears in the API Tester and can be run on every CI build.
Example 4: Chaos Testing with Toxics
Simulate a degraded Stripe API to test your retry and timeout logic:
curl -X POST http://localhost:5770/ui/api/recorder/start \
-H "Content-Type: application/json" \
-d '{
"name": "Stripe Chaos Test",
"mode": "reverse",
"targetUrl": "https://api.stripe.com",
"toxics": {
"delayMs": 3000,
"delayJitter": 1000,
"errorRate": 0.2
}
}'
20% of requests will return HTTP 503, and the remaining 80% will have 2-4 seconds of added latency.
Supported Entry Types
The recorder captures three types of traffic:
| Type | Description |
|---|---|
http |
Standard HTTP request/response pairs |
websocket |
WebSocket connections with individual frame capture |
sse |
Server-Sent Event streams with individual event capture |
GraphQL requests are automatically detected and annotated with operation name and type in the graphqlInfo field.
See Also
- Quick Start — Get Mockarty running in minutes
- API Reference — Full REST API documentation
- UI User Guide — Web interface walkthrough
- Stores — Global, Chain, and Mock store systems
- Performance Testing — Export recorded traffic as performance scripts
- Webhooks & Callbacks — Trigger HTTP, Kafka, or RabbitMQ callbacks from mocks
- Fuzzing — Import recorded requests as fuzzing seeds