Help improve docs quality by sharing anonymous interaction telemetry (no PII or token data).

Audit and Trace

Propagate request IDs end-to-end and correlate API activity, webhook deliveries, and the audit log.

When a customer disputes a charge, an integration silently breaks, or a compliance reviewer asks "who changed this and when," you need a chain of evidence that spans your logs, MonetizeKit's API responses, and the workspace's Audit Log. Every layer of that chain is connected by IDs — this guide shows how to propagate and use them.

Every response carries a request ID

Every REST response — success or error — includes an X-Request-Id header. Supply your own value and it's echoed back exactly; omit it and MonetizeKit generates a UUID v4 for you. Log this value at the call site so it's the join key between your application logs and any downstream investigation.

bash
curl -i \  -H "Authorization: Bearer $MONETIZEKIT_API_KEY" \  "$MONETIZEKIT_BASE_URL/plans?page=1&pageSize=1" \  | rg -i "^x-request-id:"# X-Request-Id: 7c2f6e1a-0e3b-4b9a-9a9f-8e2c9e6f0d21
bash
curl -i \  -H "Authorization: Bearer $MONETIZEKIT_API_KEY" \  -H "X-Request-Id: my-trace-9f2c1a" \  "$MONETIZEKIT_BASE_URL/plans?page=1&pageSize=1" \  | rg -i "^x-request-id:"# X-Request-Id: my-trace-9f2c1a  -- echoed back exactly as sent
javascript
const requestId = `svc-${crypto.randomUUID()}`;const response = await fetch(`${baseUrl}/plans?page=1&pageSize=1`, {  headers: {    Authorization: `Bearer ${apiKey}`,    "X-Request-Id": requestId,  },});logger.info("monetizekit_call", { requestId, status: response.status });
Generate one ID per logical operation, not per HTTP call

If a single user action fans out into three API calls (check an entitlement, record usage, create a subscription), give all three the same X-Request-Id prefix or a shared correlation field in your own logs. Tracing a single MonetizeKit request ID only gets you one leg of the journey.

Error responses include the same ID

Every error envelope — regardless of status code — nests code, message, and request_id under a single top-level error object (plus details for field-level validation errors). When a customer reports a failure, ask for error.request_id first; it's the fastest way to pull the exact request from logs without guessing at timestamps. Cross-reference error.code against the Error Codes reference for known causes and resolutions before escalating.

json
{  "error": {    "code": "NOT_FOUND",    "message": "Customer not found: cust_dev_9999",    "request_id": "7c2f6e1a-0e3b-4b9a-9a9f-8e2c9e6f0d21"  }}

Correlate with the Audit Log

The workspace Audit Log (Enterprise mode, under /audit in the dashboard) is the compliance-grade record of security-relevant actions: CRUD on governed resources, authentication events, approval decisions, and data exports. Each entry records an actor, an actor type, an IP address, the affected resource, and free-form metadata — cross-reference the metadata against the request IDs and delivery IDs you logged on your side.

Action categories

ActionMeaning
create / update / deleteCRUD on a governed resource (contract, plan, API key, customer, workspace, etc.).
login / logoutSession-level authentication events for dashboard users.
approve / rejectDecisions on an approval workflow (e.g. a contract or override request).
transferOwnership changes — workspace transfer, credit wallet reassignment.
read / exportSensitive reads and data exports, including audit log CSV exports themselves.

Actor types

ActorMeaning
userA dashboard user acting through the UI.
api_keyA REST/GraphQL call authenticated with a service token.
webhookAn inbound integration (e.g. a Stripe webhook) that triggered a state change.
systemAn automated internal process (scheduled jobs, reconciliation).
integrationA connected third-party integration acting on the workspace's behalf.

Correlate webhook deliveries

Webhook-triggered changes appear in the Audit Log with actorType: "webhook". Log the delivery's X-MonetizeKit-Delivery ID (see the Webhooks guide ) alongside the audit entry's timestamp and resource ID — together they let you prove exactly which delivery attempt caused which downstream state change, which is essential when disputing whether an event was processed once or twice. The same correlation strategy applies to disputed usage events — see the Usage Metering Best Practices guide for the reconciliation job that catches drift before an invoice does.

Exporting for external review

Pull audit entries programmatically with GET /audit (scope audit:view) — the same API-key auth, rate limiting, and X-Request-Id/error-envelope handling as every other REST call in this guide.

bash
curl -s \  -H "Authorization: Bearer $MONETIZEKIT_API_KEY" \  "$MONETIZEKIT_BASE_URL/audit"# { "data": [ { "id": "...", "timestamp": "...", "actor": "...", "actorType": "...",#              "actorIp": "...", "action": "...", "resource": "...", "resourceId": "...",#              "description": "...", "metadata": { ... } }, ... ] }

REST API (programmatic, most recent 500)

GET /audit returns the workspace's 500 most recent entries, newest first — there's no query-param filtering or pagination yet, so page further back or filter by actor/action/date in the dashboard instead. It isn't listed in the API Reference explorer because of that limited surface, but the endpoint itself is fully functional today.

CSV export (bulk, filtered)

The Audit Log page's "Export CSV" action exports the currently filtered entries — narrow the filters first (actor, action, date range) so the export matches the scope of your review, then hand the file to a compliance team or archive it externally.

No self-serve SIEM streaming yet

If your compliance workflow needs continuous, real-time ingestion into a SIEM rather than periodic polling of GET /audit or manual CSV export, that's not a built-in feature today — drive interim alerting off request IDs and webhook delivery correlation as described above.

Common pitfalls

Not logging the request ID at the call site

If you only discover you need a request ID after an incident, it's too late — log it on every call, success and failure alike, from day one.

Reusing one request ID across retries

A retried call is a distinct request. Reusing the same X-Request-Id across retries makes it impossible to tell, from the ID alone, whether a request succeeded on the first or third attempt.

Exporting unfiltered audit data

CSV exports are themselves an export action recorded in the log. Filter to the minimum necessary scope before exporting, both for review clarity and for data-minimization compliance requirements.

Assuming the audit API paginates

GET /audit has no page/cursor params — it always returns the 500 most recent entries. Don't build automation that assumes it can page through the full history; use the dashboard's date-range filters and CSV export for anything older.

FAQ

Can I set my own X-Request-Id and have it accepted?

Yes — any non-empty string is accepted and echoed back verbatim. If you omit the header, MonetizeKit generates a UUID v4 for you and returns it, so the header is always present either way.

Does the audit log capture read-only API calls?

Sensitive reads (like revealing a webhook signing secret) are recorded as read actions. Routine, high-volume reads (entitlement checks, usage lookups) are not, to keep the log focused on security- and governance-relevant events rather than every API call.

How long is audit log data retained?

It's a per-workspace setting (Settings → Security → auditRetentionDays), defaulting to 365 days if unset. Whatever you configure is clamped to between 90 and 730 days — export data you need to retain longer than that via CSV export rather than assuming indefinite retention.

Related guides

Webhook Verification and Retries

Delivery IDs are the join key for webhook-triggered audit entries.

Open guide

Migration Guide

Use request IDs to isolate errors introduced during a migration rollout.

Open guide

Entitlement Evaluation Patterns

Overrides are auditable exceptions — see how they resolve.

Open guide

Was this page helpful?