Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.formance.com/llms.txt

Use this file to discover all available pages before exploring further.

This feature is part of Formance Enterprise Edition.
The Formance Platform ships with an Audit Log feature that allows you to stream 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

The Formance Platform audit log system operates at three levels. 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. Around thirty event types in total. Volume is proportional to administrative activity, not to your API traffic, so it tends to be light. The following lifecycle event types are available:
ScopeEvent
organizationsorganizations.created
organizationsorganizations.deleted
organizationsorganizations.updated
organizationsorganizations.user.deleted
organizationsorganizations.user.updated
invitationsinvitations.created
invitationsinvitations.accepted
invitationsinvitations.accepted-from-link
invitationsinvitations.rejected
regionsregions.created
regionsregions.deleted
usersusers.created
usersusers.join-domain
stacksstacks.created
stacksstacks.deleted
stacksstacks.restored
stacksstacks.updated
stacksstacks.enabled
stacksstacks.disabled
stacksstacks.upgraded
stacksstacks.disposal
stacksstacks.disposal-reset
stacksstacks.warned
stacksstacks.pruned
stacksstacks.status.updated
stacksstacks.reachness.updated
stacksstacks.module.enabled
stacksstacks.module.disabled
stacksstacks.module.status.updated

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 claimsClaims resolved from the JWT used for the callactor.claims
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 for you 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:
{
  "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

{
  "date": "2024-11-14T09: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": "..."
      }
    }
  }
}

Lifecycle event

Example — a stack creation:
{
  "date": "2024-11-14T09: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 event types and their 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.
  • Responses with streaming content types (application/vnd.formance*-stream, application/octet-stream) are not captured.
Everything else is preserved as it appeared on the wire.

Plan for the data you’ll receive

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