Integrations
Integrate Audit Logs
The workspace ledger is written by the Paycux API itself: every catalog, membership, invite, provider-connection, workspace-lifecycle and agent-connection write appends a hash-chained row. You read it in the console or through two owner/admin routes and verify the chain from the export. An ingestion API for your own application's events is planned.
Available in part — Audit Logs: Every catalog, membership, billing and lifecycle write is appended to the workspace audit ledger today with its actor and payload; search, filtering, export, streaming and retention policies are planned. Items listed as planned below cannot be enabled yet. What Paycux provides today.
Before you begin
- A workspace with an owner or admin session; the audit routes refuse other roles with 403 FORBIDDEN.
- Something to look at: any catalog write, member invite or provider-connection change already produces rows.
- A place to keep exports if you need them longer than the ledger is shown; retention policies are planned.
Install
There is nothing to install. Paycux is a plain HTTPS JSON API, so every example on this page uses curl. Console routes send the dashboard session cookie, end-user routes send the application's realm access token as a bearer credential, and agent routes send the short-lived agent token. The routes that exist today are listed on What exists today.
1# Console routes carry the dashboard session cookie set by sign-in2curl https://api.paycux.com/v1/auth/session \3 -H "Cookie: __Host-paycux_session=<session>"45# End-user routes carry the application's realm access token6curl https://api.paycux.com/v1/<end-user route> \7 -H "Authorization: Bearer <realm access token>"
Configure
Nothing is configured for the ledger; every control-plane write is recorded. Console calls carry the dashboard session cookie. The identifiers below are useful as filters.
1PAYCUX_API_BASE_URL=https://api.paycux.com2PAYCUX_PROJECT_ID=<project id>3PAYCUX_ENVIRONMENT_ID=<environment id>
Then, in the dashboard:
- 1Open Audit in the console navigation (/dashboard/audit). Events are listed newest first across the workspace, project and environment scopes, 50 per page, with Older and Newest links to page through them.
- 2Filter with Scope, Action starts with, Project id and Environment id. The action filter is a prefix match: catalog. lists every catalog action, workspace_member.invited exactly one. An invalid value is reported as not applied, never dropped silently.
- 3Click Export JSON to download the ledger with a chainVerified flag per scope.
- 4For a full account export that includes audit events alongside billing accounts, subscriptions and connections, use the workspace export in Settings.
Implement
There are two read routes. Both require an owner or admin session and stay reachable while a workspace deletion request is open (the console shows its frozen-workspace view in that state, so call the routes directly); both are read-only, because nothing writes to the ledger except the API itself.
Page through events
limit is at most 100 and defaults to 50. Pass nextCursor back as cursor until it is null. Each row carries its scope, sequence, actor, action, the two hashes and payload, which is the canonical event document that was hashed; the event's own data sits inside it under payload.
1curl "https://api.paycux.com/v1/workspace/audit-events?limit=1" \2 --cookie "__Host-paycux_session=<session cookie>"34HTTP 2005{6 "events": [7 {8 "id": "0b1c2d3e-4f50-4a6b-8c7d-8e9f0a1b2c3d",9 "scopeType": "workspace",10 "projectId": null,11 "environmentId": null,12 "sequence": 42,13 "actorType": "user",14 "actorId": "6d1f0b2e-3c4a-4d5e-8f60-7a8b9c0d1e2f",15 "action": "workspace_member.invited",16 "payload": {17 "action": "workspace_member.invited",18 "actorId": "6d1f0b2e-3c4a-4d5e-8f60-7a8b9c0d1e2f",19 "actorType": "user",20 "environmentId": null,21 "payload": {22 "inviteId": "e4d3c2b1-a098-4f7e-8d6c-5b4a39281706",23 "role": "developer",24 "expiresAt": "2026-10-19T09:14:03.220Z"25 },26 "projectId": null,27 "scopeKey": "workspace:3f9d2c1e-5b7a-4c8d-9e0f-1a2b3c4d5e6f",28 "scopeType": "workspace",29 "sequence": 42,30 "workspaceId": "3f9d2c1e-5b7a-4c8d-9e0f-1a2b3c4d5e6f"31 },32 "previousHash": "b9dfd30b27583211844dc26b5ff783142b869a733309c74682e7e6b3756bb13d",33 "eventHash": "677d9cde1f8189ef82bb1cea2d29457b6d0b2afe9a24bbdf279c97598971998e",34 "createdAt": "2026-10-12T09:14:03.220Z"35 }36 ],37 "nextCursor": "<opaque cursor>"38}3940curl "https://api.paycux.com/v1/workspace/audit-events?limit=1&cursor=<opaque cursor>" \41 --cookie "__Host-paycux_session=<session cookie>"
Filter by environment and action
scopeType, projectId, environmentId and action narrow the page; action matches by prefix. Catalog writes live in the environment scope; member, invite and lifecycle writes in the workspace scope.
1curl "https://api.paycux.com/v1/workspace/audit-events?scopeType=environment&projectId=a1000000-0000-4000-8000-000000000002&environmentId=a1000000-0000-4000-8000-000000000003&action=catalog.plan.&limit=1" \2 --cookie "__Host-paycux_session=<session cookie>"34HTTP 2005{6 "events": [7 {8 "id": "1c2d3e4f-5a60-4b7c-9d8e-9f0a1b2c3d4e",9 "scopeType": "environment",10 "projectId": "a1000000-0000-4000-8000-000000000002",11 "environmentId": "a1000000-0000-4000-8000-000000000003",12 "sequence": 18,13 "actorType": "user",14 "actorId": "6d1f0b2e-3c4a-4d5e-8f60-7a8b9c0d1e2f",15 "action": "catalog.plan.created",16 "payload": {17 "action": "catalog.plan.created",18 "actorId": "6d1f0b2e-3c4a-4d5e-8f60-7a8b9c0d1e2f",19 "actorType": "user",20 "environmentId": "a1000000-0000-4000-8000-000000000003",21 "payload": {22 "planId": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",23 "productId": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f70",24 "key": "team",25 "name": "Team",26 "version": 127 },28 "projectId": "a1000000-0000-4000-8000-000000000002",29 "scopeKey": "environment:a1000000-0000-4000-8000-000000000003",30 "scopeType": "environment",31 "sequence": 18,32 "workspaceId": "3f9d2c1e-5b7a-4c8d-9e0f-1a2b3c4d5e6f"33 },34 "previousHash": "176d8ecf891bc3a13b0c43a670b4159e20468c3d0f19e1b76f1bfd1ee6aa2c99",35 "eventHash": "d583c0ed8204d4f038de8403812a8c7554e12c247e0532a3919e9ab86db93850",36 "createdAt": "2026-10-12T10:02:41.117Z"37 }38 ],39 "nextCursor": null40}
Export and check the verification flag
The export is a JSON attachment named paycux-audit-<workspace id>.json: a scopes summary and the rows themselves, ascending by scope and sequence. Each scope carries chainVerified; false means a row was altered, removed or inserted out of order, or the row bound cut the scope (truncated: true). Keep a failing file and contact support. The export is recorded in the ledger as audit.exported and is rate limited per member (429 RATE_LIMITED).
1curl "https://api.paycux.com/v1/workspace/audit-events/export" \2 --cookie "__Host-paycux_session=<session cookie>" \3 -o paycux-audit.json45HTTP 2006content-disposition: attachment; filename="paycux-audit-3f9d2c1e-5b7a-4c8d-9e0f-1a2b3c4d5e6f.json"78# paycux-audit.json (events abridged)9{10 "workspaceId": "3f9d2c1e-5b7a-4c8d-9e0f-1a2b3c4d5e6f",11 "exportedAt": "2026-10-12T11:30:00.000Z",12 "truncated": false,13 "scopes": [14 {15 "scopeKey": "workspace:3f9d2c1e-5b7a-4c8d-9e0f-1a2b3c4d5e6f",16 "scopeType": "workspace",17 "projectId": null,18 "environmentId": null,19 "events": 42,20 "chainVerified": true,21 "truncated": false22 },23 {24 "scopeKey": "environment:a1000000-0000-4000-8000-000000000003",25 "scopeType": "environment",26 "projectId": "a1000000-0000-4000-8000-000000000002",27 "environmentId": "a1000000-0000-4000-8000-000000000003",28 "events": 18,29 "chainVerified": true,30 "truncated": false31 }32 ],33 "events": [ "...60 rows, ascending by scope and sequence..." ]34}
Recompute a chain yourself
The rule is public: eventHash is SHA-256 over previousHash, a newline and the canonical JSON of the event document with keys sorted recursively; the first previousHash is 64 zeros and sequence numbers start at 1 without gaps. The API returns that document as payload. Group the export's events by scopeKey and feed one scope's rows oldest first.
1import { createHash } from "node:crypto";23type AuditEvent = {4 sequence: number;5 previousHash: string;6 eventHash: string;7 payload: unknown;8};910function canonical(value: unknown): unknown {11 if (Array.isArray(value)) return value.map(canonical);12 if (value !== null && typeof value === "object") {13 return Object.fromEntries(14 Object.entries(value as Record<string, unknown>)15 .sort(([left], [right]) => left.localeCompare(right))16 .map(([key, nested]) => [key, canonical(nested)]),17 );18 }19 return value;20}2122// events: one scope, ascending by sequence. payload is the canonical event23// document the API returns for each row.24export function verifyScope(events: AuditEvent[]): boolean {25 let previousHash = "0".repeat(64);26 let sequence = 1;2728 for (const event of events) {29 const expected = createHash("sha256")30 .update(previousHash, "utf8")31 .update("\n", "utf8")32 .update(JSON.stringify(canonical(event.payload)), "utf8")33 .digest("hex");3435 if (event.sequence !== sequence) return false;36 if (event.previousHash !== previousHash) return false;37 if (event.eventHash !== expected) return false;3839 previousHash = event.eventHash;40 sequence += 1;41 }42 return true;43}
Verify
Verify the chain, then verify the access rule.
- 1Create a catalog product in a test environment and confirm catalog.product.created appears at /dashboard/audit in the environment scope.
- 2Export the ledger and confirm chainVerified is true and truncated is false for every scope.
- 3Group the export's events by scopeKey, sort one scope by sequence and recompute each hash; it must equal eventHash.
- 4Sign in as a developer or viewer and call GET /v1/workspace/audit-events. Expect 403 FORBIDDEN.
- 5Search the export for provider keys, invite tokens or raw e-mail addresses. There must be none.
Reference
Request and response shapes for each of these live in the API reference. Paths are relative to https://api.paycux.com.
| Method | Path | What it does |
|---|---|---|
| GET | /v1/workspace/audit-events | Page through the ledger, newest first, with scopeType, projectId, environmentId, action (prefix), limit and cursor (owner/admin). |
| GET | /v1/workspace/audit-events/export | Download the bounded ledger as a JSON attachment with chainVerified per scope (owner/admin). |
| GET | /v1/workspace/export | Secret-free workspace export that includes the audit events (owner/admin). |