Audit Log API
You can publish your own application's events into the same event stream as Keycloak's access and admin events. Published events are delivered to your webhooks alongside the built-in events, so a single endpoint receives everything.
Endpoint
Events are posted to the following endpoint. Replace <your-cluster-host> and <realm> with your values. The endpoint accepts JSON.
POST https://<your-cluster-host>/auth/realms/<realm>/events
Authentication
The caller must have the publish-events role. It is a client role of the realm-management client in each realm, and is included in the realm-admin composite role. Grant it to a service account for backend calls, or to the users whose tokens your application uses. Send the access token in the Authorization header:
Authorization: Bearer <accessToken>
Field definitions
Event
The Event object describes the full action that took place in the system.
| Name | Type | Required | Description |
|---|---|---|---|
| uid | string | provided | An ID unique to this event |
| time | number | optional 1 | UNIX timestamp of the event, in milliseconds |
| realmId | string | provided | The realm ID where the action took place |
| authDetails | AuthDetails | provided | - |
| type | string | required | A description of the action that took place |
| operationType | string | optional | What operation was executed on a resource (CREATE, DELETE, UPDATE, ACTION) |
| resourcePath | string | optional | If the action changed a resource, this is meant to be the / delimited resource path |
| resourceType | string | optional | If the action changed a resource, this is the resource's type |
| details | object | optional | An optional hash of values pertaining to the action that took place |
| error | string | optional | An optional error string for tracing purposes if the action resulted in a failure |
The type must not start with access., admin., or system.. Those prefixes are reserved for events generated by the server.
AuthDetails
The AuthDetails object describes the user or service account that published the event. Omit it when posting an event; the server fills it in from the access token.
| Name | Type | Required | Description |
|---|---|---|---|
| realmId | string | provided | The realm of the caller |
| clientId | string | provided | The client the caller's token was issued to |
| userId | string | provided | The user ID of the caller |
| ipAddress | string | provided | The IP address of the caller |
| username | string | provided | The username of the caller |
| sessionId | string | provided | A unique ID of the current login session, if any |
Responses
HTTP status codes indicate success or failure.
| Status code | Description |
|---|---|
| 202 | Event received |
| 400 | Malformed event, for example a missing type |
| 401 | Missing or invalid token, or the caller lacks publish-events |
| 409 | Reserved event type |
| 5xx | Server error |
Example
curl https://<your-cluster-host>/auth/realms/my-realm/events \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <accessToken>" \
--data '{ "type": "billing.invoice-paid", "details": { "invoiceId": "inv_123" } }'