Integrations reference

Field-level reference for the Integrations page: endpoints (email, Slack, webhook, stream), event sets picked from the event catalogue, integrations and their templates, Governance Audit delivery limits, and template variables.

Integrations send gateway events to systems outside the dashboard, such as an email when a user registers, a Slack message when a gateway is disabled, or a webhook or stream record for every policy decision. Each integration joins one endpoint, where messages go, with one event set, which events it delivers, and holds the template for the message. One endpoint or event set can serve several integrations, so a Slack channel used for gateway alerts and payment alerts is configured once.

Integrations page

Select Integrations in the sidebar. The page has three tabs, Integrations, Endpoints, and Event Sets, and one filter box that searches all three by name, description, type, and event.

TabColumnsActions
IntegrationsName, Endpoint (name and type), Event set (name and event count), StatusAdd Integration, send a test, edit, delete
EndpointsName, Type, Status, Used byAdd Endpoint, send a test, edit, delete
Event SetsName, Events (count, with an audit badge when the set holds Governance Audit events), Used byAdd Event Set, edit, delete

Used by counts the integrations that use the endpoint or event set, and hovering over it names them. An endpoint or event set in use can’t be deleted: its delete button stays disabled and its tooltip names the integrations using it. Delete or change those integrations first. An integration whose endpoint or event set is missing shows Missing endpoint or Missing event set in red.

Every user with the User role or higher can open the page and see each endpoint’s destination. Stored credentials are never shown. Only administrators can add, change, and test endpoints, event sets, and integrations, and delete them.

Endpoints

An endpoint is where integrations deliver: an SMTP server and its recipients, a Slack incoming webhook, an HTTPS webhook, or a stream topic, with the credentials to reach it. Select Add Endpoint on the Endpoints tab.

FieldRequiredDefaultDescription
NameYesEmptyDisplay name, shown in the Endpoint dropdown of the integration editor.
DescriptionNoEmptyOptional note.
TypeYesEmail (SMTP)Email (SMTP), Slack, Webhook, or Stream (Kafka, Kinesis, Pulsar, Redis). Set once: a saved endpoint keeps its type, because its integrations’ templates are written for it.
ActiveNoOnA disabled endpoint receives nothing, whatever its integrations’ status.

The Configuration card below shows the fields of the selected type.

Email (SMTP)

FieldRequiredDefaultDescription
SMTP hostYesEmptySMTP server hostname, for example smtp.example.com.
SMTP portYes587Usually 587 with STARTTLS or 465 with TLS.
SMTP usernameYesEmptySMTP sign-in name.
SMTP passwordYesEmptySMTP password. A stored credential.
FromYesEmptySender address, for example gateway@example.com.
ToYesEmptyRecipient addresses, one per line or separated by commas.
CcNoEmptyCopy recipients, one per line.
BccNoEmptyBlind copy recipients, one per line.
Use TLSNoOnImplicit TLS, as on port 465.
Use STARTTLSNoOnUpgrades a plain connection to TLS, as on port 587.

Slack

FieldRequiredDefaultDescription
Incoming webhook URLYesEmptyThe Slack incoming webhook URL, for example https://hooks.slack.com/services/.... The URL carries its own credential, so it is a stored credential.
Sender nameNoEmptyDisplay name for the message sender, for example Agent Gateway.
Sender iconNoEmptyEmoji shown as the sender’s icon, for example :robot_face:.

Messages go to the channel the incoming webhook was created for in Slack.

Webhook

FieldRequiredDefaultDescription
URLYesEmptyThe http or https URL that receives each message. Saving refuses a URL whose host resolves to a non-public address, such as a private, loopback, or link-local one.
MethodNoPOSTPOST, PUT, or PATCH.
Signing secretNoEmptyWhen set, each request carries an X-Webhook-Signature-256: sha256=<hex> header so the receiver can check the sender. A stored credential.
HeadersNoEmptyExtra request headers as a JSON object of header names to text values, for example {"Authorization": "Bearer ..."}. A header value may be $SECRET:<secret_id> to use a stored secret. Kept like a password, since headers often carry credentials.

Every webhook request carries an X-Webhook-Timestamp header with the Unix time in seconds, and the signature covers the timestamp and the body, so a receiver can reject replayed requests. The gateway sets Content-Type, X-Webhook-Timestamp, and X-Webhook-Signature-256 itself, so Headers can’t set them, and saving an endpoint that tries to is refused.

Stream

FieldRequiredDefaultDescription
PlatformYesApache KafkaApache Kafka, Amazon Kinesis, Apache Pulsar, or Redis Streams.
Topic or streamYesEmptyThe topic (Kafka, Pulsar) or stream (Kinesis, Redis Streams) to publish to.
BrokersYes, for Kafka and PulsarEmptyBroker addresses separated by commas, for example broker-1:9092,broker-2:9092. Shown for Kafka and Pulsar.
AuthenticationNoNoneNone or SASL PLAIN. Shown for Kafka.
SASL usernameYes, with SASL PLAINEmptyShown when Authentication is SASL PLAIN.
SASL passwordYes, with SASL PLAINEmptyShown when Authentication is SASL PLAIN. A stored credential.
AWS regionYes, for KinesisEmptyRegion of the Kinesis stream, for example eu-west-1. The gateway uses its host’s AWS credentials. Shown for Kinesis.
Partition keyNoEmptyKinesis partition key. Shown for Kinesis.
Redis URLYes, for Redis StreamsEmptyRedis connection URL, for example redis://cache:6379. The URL may carry a password, so it is a stored credential. Shown for Redis Streams.

Stored credentials

SMTP password, Incoming webhook URL, Signing secret, Headers, SASL password, and Redis URL are write-only. Once saved, the form shows A value is stored. It is never shown. with these buttons:

  • Replace opens the field for a new value. Keep stored value cancels the replacement.
  • Clear removes the stored value when you save, and Undo cancels that. Required fields have no Clear.

Instead of typing a value into SMTP password, Incoming webhook URL, Signing secret, SASL password, or Redis URL, pick a secret from Use a stored secret below the field. The field then holds $SECRET:<secret_id>, shown as written, and the gateway reads the secret’s current value from Secrets at each delivery. One credential can then serve several endpoints, and changing the secret’s value takes effect on the next delivery. The list offers appliance-wide secrets to users who can view secrets.

A secret that an endpoint uses can’t be deleted. The Secrets page reports the failed delete with the names of the endpoints using it. Point those endpoints at another value first.

Endpoint test

Send test on a saved endpoint, or the paper-plane icon on its row, sends the endpoint type’s default message once, without retries. Save your changes first: the test uses the saved endpoint. A successful test shows Test message sent to the endpoint name. A failed one shows Test failed: with the reason, and stays until dismissed.

Event sets

An event set picks the events an integration delivers, from the whole event catalogue. One event set can serve several integrations. Select Add Event Set on the Event Sets tab.

FieldRequiredDescription
NameYesDisplay name, shown in the Event set dropdown of the integration editor.
DescriptionNoOptional note.
EventsYes, at least oneThe events to deliver, grouped by family, with Governance Audit events grouped by area. A group checkbox selects or clears the whole group, and Search events filters by name and description.

An event is delivered for every gateway, user, or connection point that raises it. There is no filter by resource.

While integrations use the event set, the form names them. A change that leaves one of them with template variables that no remaining event fills is refused.

Event catalogue

GroupEvents
GatewayGateway Created, Gateway Updated, Gateway Deleted, Gateway Status Changed (enabled or disabled), Gateway Accessed (viewed)
UserUser Registered, User Approved, User Updated (role, status, or profile changed), User Deleted, User Login, User Profile Accessed
Connection PointConnection Point Connected: someone connected through a connection point with its secret
x402 Paymentsx402 Verification Failed, x402 Settlement Failed, x402 Transaction Completed, x402 Cleanup Completed
MPP PaymentsMPP Verification Failed, MPP Payment Verified, MPP Challenge Issued
Governance AuditEvery audit event, grouped as Governance Audit: Policies, Governance Audit: Trust, and so on. The same events as Events to keep on the Settings Security tab.

A SAML sign-in that creates a user raises User Registered, and one that changes the user’s role, status, or primary flag raises User Updated, before User Login.

Integrations

An integration sends the events of an event set to an endpoint. Select Add Integration on the Integrations tab.

FieldRequiredDefaultDescription
NameYesEmptyDisplay name.
DescriptionNoEmptyOptional note.
EndpointYesNoneWhere to deliver. Disabled endpoints are marked disabled in the list. Add an endpoint opens a new endpoint form.
Event setYesNoneWhich events to deliver, with each set’s event count. Add an event set opens a new event set form.
ActiveNoOnA disabled integration delivers nothing.

The Template card shows its fields once an endpoint is selected, and the Governance Audit delivery card appears when the event set holds Governance Audit events.

Each event goes to every active integration whose event set holds it and whose endpoint is active. Each integration is delivered on its own, so a slow or unreachable endpoint doesn’t hold up the others. A transient failure, such as a timeout or a 5xx or 429 response, is retried up to five times with growing delays. Other failures, such as a 4xx response, aren’t retried. Governance Audit records follow their own delivery rules, described under Governance Audit delivery.

Template

The Template card shows the fields of the endpoint’s type. A field left empty sends the default shown in it, so an empty template still sends a complete message.

Endpoint typeFieldDefaultDescription
EmailSubject${EVENT_NAME}Email subject.
EmailBody${EVENT_SUMMARY}Email body.
EmailFormatPlain textPlain text or HTML. With Plain text, a body that contains <html or <body tags is sent as HTML. In HTML, values filled into the body are escaped so they can’t add markup or links.
SlackMessage*${EVENT_NAME}* and ${EVENT_SUMMARY} on the next lineSlack mrkdwn. Values are escaped so they can’t mention people or add links.
Webhook, StreamPayloadThe default payload belowA JSON object. Saving fails until the text is a JSON object.

The default webhook and stream payload is:

{
  "event_type": "${EVENT_TYPE}",
  "event_name": "${EVENT_NAME}",
  "timestamp": "${TIMESTAMP}",
  "appliance_id": "${APPLIANCE_ID}",
  "summary": "${EVENT_SUMMARY}",
  "data": "${EVENT_DATA}"
}

In a webhook or stream payload, a string that is exactly ${EVENT_DATA} or ${AUDIT_RECORD} is sent as a JSON object. Inside other text, and in email and Slack messages, these variables are inserted as JSON text.

The Variables list beside the template shows every variable the event set’s events fill, with a description. Select one to insert it at the cursor. A template that uses a variable no event of the event set fills can’t be saved, and a warning names it. A variable with no value for the delivered event is sent empty.

Integration test

Send test in the editor, or the paper-plane icon on the integration’s row, sends one real message for one event of the event set, the one whose event ID sorts first, filled with sample values. It is delivered, not simulated. In the editor, the test sends the integration as it stands on screen, saved or not, and is unavailable while the form has a problem that would stop it being saved. A successful test shows Test message for the event sent to the endpoint name.

Governance Audit delivery

Shown when the event set holds Governance Audit events. Audit records are kept in a journal on the appliance and retried until delivered, unless these limits skip them.

FieldDefaultDescription
Give up on a record afterEmpty: retry until deliveredUnder Delivery limits, in attempts. After this many failed attempts, the integration skips the record so the records after it can be delivered. While the destination is down, records are also skipped once they reach this limit.
Skip records older thanEmpty: deliver records of any ageUnder Delivery limits, in seconds. Records older than this are skipped for this integration instead of delivered, including a record still being retried.

Each value is a whole number of 1 or more, or empty.

  • Each audit record is one delivery, so an email or Slack integration sends one message per record. Webhook and stream integrations suit busy appliances.
  • Delivery is at least once, so a record can arrive more than once, for example after a restart. Every new record carries a unique event_id, so deduplicate on it at the receiver.
  • A destination that stops accepting records falls behind and catches up in order once it recovers. Without delivery limits, its oldest records are skipped only when the backlog grows past its cap.
  • Turning off Active on the integration or its endpoint pauses delivery. A paused integration lets go of its undelivered records, and once active again it receives only the records produced after that.
  • Records leave the appliance with the caller’s email and name, request details, and the signed VP. Send them only to a destination cleared for that data.

To start an audit integration from the Audit page, select Forward records. It opens a new event set named Governance Audit with every audit event selected. Once an integration receives audit records, the button reads Forwarding to N integrations and opens the Integrations page.

Template variables

Use ${VARIABLE} in any template field. Every event fills the common variables. Each event also fills its own, and the Variables list in the editor shows exactly which ones the selected event set offers.

Common variables

VariableDescription
${EVENT_TYPE}The event’s ID, for example gateway.created or audit.policy_decision.
${EVENT_NAME}The event’s display name, for example Gateway Created.
${EVENT_SUMMARY}One line on what happened, written for people.
${EVENT_DATA}The event’s values as JSON. For a Governance Audit event, the audit record.
${TIMESTAMP}RFC 3339 time the event occurred. For an audit record, the record’s own timestamp.
${APPLIANCE_ID}The Appliance ID set on the Settings System tab. Empty while none is set.

Gateway events

VariableDescription
${OLD_STATE}The gateway before the change, as JSON. Empty for a create.
${NEW_STATE}The gateway after the change, as JSON. Empty for a delete.
${GATEWAY_ID}ID of the gateway.
${GATEWAY_NAME}Name of the gateway.
${GATEWAY_DESCRIPTION}Description of the gateway.
${GATEWAY_DID}Decentralised Identifier (DID) of the gateway.
${GATEWAY_TYPE}Type of the gateway.
${GATEWAY_STATUS}Status of the gateway after the event.
${GATEWAY_OLD_STATUS}Status of the gateway before the change. Gateway Status Changed only.

User events

VariableDescription
${OLD_STATE}The user before the change, as JSON. Empty for a create.
${NEW_STATE}The user after the change, as JSON. Empty for a delete.
${USER_ID}ID of the user.
${USERNAME}Username of the user.
${USER_EMAIL}Email of the user, when known.
${USER_ROLE}Role of the user.
${USER_STATUS}Status of the user.

For user events, ${OLD_STATE} and ${NEW_STATE} carry only user_id, role, status, is_primary, created_at, and updated_at. Add ${USERNAME} or ${USER_EMAIL} only when the destination needs them.

Connection point events

VariableDescription
${CP_ID}ID of the connection point that received the connection.
${CP_NAME}Name of the connection point.
${CP_DESCRIPTION}Description of the connection point.
${GATEWAY}, ${GATEWAY_ID}ID of the connection point’s gateway.
${MEDIATOR_ID}ID of the mediator the connection arrived through.
${MESSAGE_ID}ID of the connection-setup message.
${MESSAGE_TYPE}DIDComm type of the connection-setup message.
${FROM_DID}DID of whoever connected.
${MESSAGE_BODY}Body of the connection-setup message, as JSON.
${RECEIVED_AT}RFC 3339 time the connection-setup message was received.
${DATE}, ${TIME}, ${DATETIME}Delivery date (YYYY-MM-DD), time (HH:MM:SS), and both (YYYY-MM-DD HH:MM:SS).

Payment events

VariableEventsDescription
${CORRELATION_ID}x402 events except x402 Cleanup CompletedID correlating the payment’s requests.
${SURFACE_ID}MPP events, and x402 events except x402 Cleanup CompletedID of the Agent Surface that took the payment.
${SURFACE_NAME}MPP eventsName of the Agent Surface that took the payment.
${TX_HASH}x402 events except x402 Cleanup CompletedOn-chain transaction hash.
${AMOUNT}, ${NETWORK}x402 Transaction CompletedAmount paid and the network it settled on.
${SETTLEMENT_METHOD}x402 Settlement Failed, x402 Transaction CompletedHow the payment was settled.
${ERROR_MESSAGE}x402 Verification Failed, x402 Settlement Failed, MPP Verification FailedWhy the payment step failed.
${TRANSACTIONS_DELETED}, ${RETENTION_DAYS}x402 Cleanup CompletedTransactions the cleanup removed, and the days transactions are kept.
${PAYMENT_METHOD}MPP Verification Failed, MPP Payment VerifiedPayment method the caller used.
${RESOURCE_URL}MPP eventsURL of the paid resource.
${REFERENCE}MPP Payment VerifiedPayment reference returned by the verifier.
${SEVERITY}All payment eventsinfo or error.

Governance Audit events

VariableDescription
${AUDIT_RECORD}The complete audit record as JSON, in the same shape as a VP Audit Log entry, including its event_id and signed VP.
${AUDIT_CATEGORY}The audit event, for example policy_decision, trust_check, or auth_failed. ${EVENT_TYPE} carries the same value as audit.<event>.
${AUDIT_TRACE_ID}Request trace ID shared by every audit record written for the same request.
${AUDIT_SURFACE_ID}ID of the surface the record belongs to.
${AUDIT_SURFACE_NAME}Name of the surface the record belongs to.
${AUDIT_PROTOCOL}Protocol of the surface, for example a2a or mcp.
${AUDIT_AGENT_DID}DID of the agent the record was written for.
${AUDIT_VIA_FABRIC}true when the request crossed a gateway-to-gateway connection, otherwise false.
${AUDIT_PRINCIPAL}The authenticated caller: their email, else display name, else the authenticated subject such as the JWT sub, API key name, DID, or mTLS principal. Empty when the request had no authenticated caller.
${AUDIT_PRINCIPAL_EMAIL}Email of the authenticated caller, when their credential carries one.
${AUDIT_PRINCIPAL_NAME}Display name of the authenticated caller, when their credential carries one.
${AUDIT_AUTH_METHOD}How the caller authenticated, for example jwt_bearer, api_key, did_auth, or mtls. Empty for an unauthenticated request.
${AUDIT_DECISION}allow or deny on a policy decision record. Empty on other records.
${AUDIT_DENY_REASON}Deny reason reported by the policy on a denied policy decision record. Empty otherwise.
${AUDIT_POLICY_NAME}Name of the policy that made a policy decision. Empty on other records.
${AUDIT_POLICY_VERSION}Version of the enforced policy revision on a policy decision record, when the policy is versioned.
${AUDIT_POLICY_CONTENT_HASH}sha256:<hex> hash of the exact Rego enforced on a policy decision record, when known.
${AUDIT_VP_JWT}Signed Verifiable Presentation (JWT) attached to the record.
${AUDIT_VP_FINGERPRINT}sha256:<hex> fingerprint of the signed VP attached to the record.

The default payload’s "data": "${EVENT_DATA}" already carries the full audit record, including its event_id, as a JSON object. ${AUDIT_RECORD} and ${AUDIT_VP_JWT} are large, so keep them out of email and Slack messages.