_Docs/
Get StartedModulesPlatformDeployCookbookChangelogReference
_Platform
  • Architecture
    • Single sign-on (SSO) for organizationsEE
    • Access ControlEE
    • Invite users
    • Audit LogsEE
    • Event Streaming
    • Webhooks
  • SDKs
  • Releases policy
  1. Manage
  2. Identity & Access
  3. Audit Logs
enterprise

Audit Logs

The Formance Platform ships with an Audit Log feature that streams every administrative action and every API request against your stacks to a destination of your choice — typically a SIEM such as Splunk, Datadog, or Elastic, or any HTTPS endpoint that accepts JSON POSTs. This page describes what's captured, how forwarding works, and what the events look like on the wire.

To enable Audit Log forwarding, contact your account team.

What's captured#

Two independent streams are available, and you can subscribe to either or both.

Lifecycle events#

Administrative activity at the organisation and stack level: invitations, user and permission changes, stack create / update / delete / upgrade, region changes, module enable / disable, and similar.

Volume is proportional to administrative activity, not to your API traffic, so it tends to be light.

The following lifecycle event types are emitted:

ScopeEvent
organizationsorganizations.created
organizationsorganizations.updated
organizationsorganizations.deleted
organizationsorganizations.join
organizationsorganizations.user.updated
organizationsorganizations.user.deleted
organizationsorganizations.application.enabled
organizationsorganizations.application.disabled
organizationsorganizations.auth-provider.configured
organizationsorganizations.auth-provider.deleted
organizationsorganizations.client.created
organizationsorganizations.client.updated
organizationsorganizations.client.deleted
organizationsorganizations.feature.updated
organizationsorganizations.feature.deleted
invitationsinvitations.created
invitationsinvitations.accepted
invitationsinvitations.accepted-from-link
invitationsinvitations.rejected
invitationsinvitations.cancelled
regionsregions.created
regionsregions.deleted
regionsregions.allowed-access
regionsregions.denied-access
regionsregions.set_connected
regionsregions.set_disconnected
regionsregions.ping
usersusers.created
usersusers.deleted
usersusers.join-domain
usersusers.onboarded
stacksstacks.created
stacksstacks.updated
stacksstacks.deleted
stacksstacks.restored
stacksstacks.enabled
stacksstacks.disabled
stacksstacks.upgraded
stacksstacks.warned
stacksstacks.pruned
stacksstacks.disposal
stacksstacks.disposal-reset
stacksstacks.status.updated
stacksstacks.status.deleted
stacksstacks.reachness.updated
stacksstacks.module.enabled
stacksstacks.module.disabled
stacksstacks.module.status.updated
stacksstacks.module.status.deleted
stacksstacks.stargate.enabled
stacksstacks.stargate.disabled
stacksstacks.user.updated
stacksstacks.user.deleted
stacksstacks.versions.upserted
stacksstacks.versions.deleted

Module HTTP audit#

Every non-streaming API call against your module services (ledger, payments, wallets, reconciliation, orchestration, and so on). Each event captures:

FieldDescriptionPath in payload
Event IDA unique identifier for the eventid
Trace IDThe distributed trace ID for the requesttrace_id
Actor claimsOIDC claims resolved from the JWT used for the callactor.claims
Token validation errorSet when the JWT could not be validatedactor.token_validation_error
OrganisationThe organisation the call was made againstactor.organization_id
StackThe stack the call was made againstactor.stack_id
IP addressThe originating IP addressactor.ip_address
HTTP methodThe request method (GET, POST, etc.)http.request.method
PathThe API endpoint accessedhttp.request.path
HostThe request hosthttp.request.host
Request headersHeaders included in the requesthttp.request.header
Request bodyThe request bodyhttp.request.body
Status codeThe HTTP response status codehttp.response.status_code
Response headersHeaders included in the responsehttp.response.headers
Response bodyThe response bodyhttp.response.body

Volume scales one-to-one with your API call rate.

How forwarding works#

The Formance Platform pushes events to an HTTPS endpoint you provide. There is no queue for you to subscribe to and no agent to deploy — events arrive at your endpoint as POST requests as they happen, with the headers you've configured.

To set up forwarding, share with your account team:

  • The HTTPS URL where events should be delivered.
  • Any authentication headers to include on the POST. For Splunk HEC this is typically Authorization: Splunk <hec-token>.
  • Which stream(s) you want — lifecycle, module, or both.
  • The stacks the integration should cover, if you have multiple.
  • Whether you want events batched. By default each event is delivered as its own POST; we can batch into bulk POSTs on request.

Provisioning is operated by Formance.

Event format#

Both streams share a common envelope:

JSON
{
  "date": "<ISO 8601 UTC timestamp>",
  "app": "gateway | membership",
  "version": "v2",
  "type": "<event type>",
  "payload": { ... }
}

The shape of payload depends on the stream and event type.

Module audit event#

JSON
{
  "date": "2026-04-30T09:23:41.123Z",
  "app": "gateway",
  "version": "v2",
  "type": "AUDIT",
  "payload": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "actor": {
      "claims": { "sub": "...", "email": "...", "iss": "..." },
      "organization_id": "...",
      "stack_id": "...",
      "ip_address": "..."
    },
    "http": {
      "request": {
        "method": "POST",
        "path": "/api/ledger/v2/main/transactions",
        "host": "...",
        "header": { "Content-Type": ["application/json"] },
        "body": "..."
      },
      "response": {
        "status_code": 200,
        "headers": { "Content-Type": ["application/json"] },
        "body": "..."
      }
    }
  }
}

When the request's JWT can't be validated, actor.claims is omitted and actor.token_validation_error carries the reason instead.

Lifecycle event#

Example — a stack creation:

JSON
{
  "date": "2026-04-30T09:15:00Z",
  "app": "membership",
  "version": "v2",
  "type": "stacks.created",
  "payload": {
    "ownerId": "...",
    "organizationId": "...",
    "subject": "...",
    "data": {
      "id": "...",
      "name": "prod-stack",
      "regionId": "..."
    }
  }
}

The structure of payload.data varies by event type. The full list of lifecycle payload shapes is available on request from your account team.

What's stripped before delivery#

Module audit events are intentionally complete. Auditors and security teams need to be able to reconstruct exactly what happened, so headers and bodies are captured verbatim — with three exceptions, applied at the source:

  • The Authorization request header is removed.
  • The response body for /api/auth/oauth/token is cleared.
  • Request and response bodies for streaming endpoints (Content-Type application/vnd.formance*-stream or application/octet-stream) are not captured.

Everything else is preserved as it appeared on the wire.

Module audit events will contain whatever your API calls contain. For ledger that means transaction amounts, account references, and any metadata you've attached. For payments, counterparty details and amounts. Once events are delivered to your SIEM, they live under your access controls, retention rules, and downstream pipelines — treat the audit stream as an extension of the data plane it observes, and apply the same data governance you'd apply to any system handling financial or personal information.

Delivery semantics#

Events are delivered at least once. If your endpoint returns a non-2xx response or is unreachable, the Formance Platform retries. During extended outages on your side, events may be queued internally up to a bounded retention window; sustained outages can cause queued events to be lost. Treat the destination receiver as durable storage rather than relying on the Formance Platform as a long-term buffer.

There is no API to replay historical events from before forwarding was set up. If you need historical data, request it during onboarding.

Inspection from the command line#

For ad-hoc inspection of lifecycle events, fctl provides direct access:

Shell
fctl cloud org history <organization-id>
fctl stack history <stack-id>

This is intended for occasional review rather than continuous ingestion. For SIEM integration, use forwarding as described above.

FAQ#

Which destinations are supported? Any HTTPS endpoint that accepts JSON POSTs. Splunk HEC, Datadog, Elastic, and custom endpoints are all in production with existing customers.

Can we filter events at the source? Not today — the configured stream is forwarded in full. Filter at your destination.

Are the two streams delivered on the same connection? They share an envelope but come from independent forwarders. Distinguish on the app field (gateway for module audit, membership for lifecycle) and on type.

Is the schema stable? Yes. The current schema version is v2. Changes will be coordinated with your account team.

What's the latency from event to delivery? Module audit events are forwarded as the request completes. Lifecycle events are forwarded as they occur. End-to-end latency to your endpoint is typically sub-second under normal conditions.

Invite usersEvent Streaming
On This Page
  • What's captured
  • Lifecycle events
  • Module HTTP audit
  • How forwarding works
  • Event format
  • Module audit event
  • Lifecycle event
  • What's stripped before delivery
  • Delivery semantics
  • Inspection from the command line
  • FAQ