Audit framework API
Use this API to query audit log events for a Medallia Experience Cloud instance via HTTP request to evaluate, assess, and mitigate security risks, and also to find the root cause of configuration issues.
Audit logs are essential for conducting investigations following an incident. For accountability and transparency, Medallia provides comprehensive audit logs that document user activities and system events.
Query audit events asynchronously
The audit query service allows you to query for data in an asynchronous manner. Create a request to query the audit framework with filtering capabilities. Then use the returned job id to check the job's status, cancel or resume it, and retrieve its results once completed.
Audit events
Medallia's audit framework is an engine that collects a variety of security-related events and makes them queryable via this public API.
See the list of events ingested to the audit log from Medallia Experience Cloud below:
Login module events
-
USER_LOGIN — {user} attempted to login with {method}.
-
USER_LOGOUT — {type} user {user} logout.
-
USER_SWITCH_INTO — user switched into {user}.
-
USER_SWITCH_BACK — user switched back from {user}.
Permissions module events
-
GRANT_ROLE_TO_USER — {user} was granted {role}.
-
REVOKE_ROLE_TO_USER — {user} was revoked {role}.
-
GRANT_PERMISSION_TO_ROLE — {role} was granted {permission}.
-
REVOKE_PERMISSION_TO_ROLE — {role} was revoked {permission}.
Admin commands module events
-
CMD_CENTER_COMMAND — In Cmd Center, user executed {cmd}.
-
COMMAND_CENTER_ACTION — In Command Center {action} action was performed on property {property_name}.
Internal admin SSO events
-
BIFROST_GRANT_USER — In Bifrost, {user} was granted user {environment} access to {application} in {company} in {data center} because of {reason}.
-
BIFROST_REVOKE_USER — In Bifrost, {user} was revoked user {environment} access to {application} in {company} in {data center} because of {reason}.
-
BIFROST_GRANT_MANAGER — In Bifrost, {user} was granted manager access to {application} in {company} in {data center} because of {reason}.
-
BIFROST_REVOKE_MANAGER — In Bifrost, {user} was revoked manager access to {application} in {company} in {data center} because of {reason}.
-
BIFROST_UPDATE_ROLE — In Bifrost, updated {role} for {user}.
System connections module events
-
SYSTEM_CONNECTIONS_CREATE — System connection {id} was created.
-
SYSTEM_CONNECTIONS_READ — System connection {id} was read.
-
SYSTEM_CONNECTIONS_DELETE — System connection {id} was deleted.
-
SYSTEM_CONNECTIONS_UPDATE — System connection {id} was updated.
-
SYSTEM_CONNECTIONS_LIST — System connection list operation was executed.
PGP-key management module events
-
TENANT_KEY_CHANGE — The tenant key for company {company} was changed to type {keyType}.
Changelog events
-
CHANGELOG — A {changeType} was performed on an entity of {type} in the entity {field} by an {initiator} during a {transaction}, {group} and {session}.
-
type — The type of entity affected by the change {account, translation}. This value is stored in the
extra_fields
value of this event. -
field — The field that was affected by the change (or database column) (field:"account.email", field:"translation.transtext"). This value is stored in the
extra_fields
value of this event. -
changeType — The type of entity change: {deletion, creation, update}. This value is stored in the
extra_fields
value of this event. -
Initiator — account, component.
-
component — Changes initiated (either directly or indirectly) by the given system component (component:"Express web").
-
-
group — Changes that were done as part of the change group with the given id (group:"6439"). This value is stored in the
extra_fields
value of this event. -
session — Changes performed in the change session with the given id (session:"current"). This value is stored in the
extra_fields
value of this event.
-
Query API events
-
QUERY_API — A request of {type} was performed against the reporting query api with the following {parameters} and {request_context}.
-
type — GET, POST.
-
parameters — All the request parameters are stored in the extra_fields of this event.
-
request_context — All the request context as headers are stored in the
extra_fields
of this event.
-
Restrictions and limits
The Audit query API can handle up to 10 requests per second and 10,000 requests per day.
For security reasons, users of this API are only allowed to query events for the company in which they have access and access one at a time. You cannot query more than one company in the same request even if you have access to different instances.
Authentication and authorization
Authentication identifies who is making an API request, and authorization identifies what data the requester may access. OAuth is an industry standard for authorizing limited access to services and data. Applications must obtain a secure token that identifies the application that makes the request. The token is passed to the resource server (API server) with each API request. For more information, see Authenticate APIs with OAuth.
To use the Records API:
-
The application must have an account.
-
The account's role must have permission to access the API. In this case:
-
Medallia Audit Role
-
-
API access is authenticated with OAuth. To use OAuth, the application must first obtain an OAuth access token, by requesting one for the application's client ID and secret. For detailed information, see Authenticating APIs with OAuth.
Each Medallia instance serves as an OAuth authorization server and issues tokens to access the Audit Framework through the API gateway.
There is a default OAuth client created in each Medallia Experience Cloud named medallia_audit_query
to use for this purpose. This client is configured with the authorization code grant and through it, Experience Cloud issues an OpenID token to receive both access_token
and id_token
when requesting the token.
Request/response formats
-
A required
Content-Type
header field describing the content. The acceptable type is: application/json for JSON. -
An optional
Accept
field tells the Records API how to format the response. The acceptable type is: application/json for JSON.Parameter Description Required Values Bearer Access token Required See Authentication and authorization. api_token ID token encoded as a JSON Web Token (JWT) with additional information about the user Required See Authentication and authorization. The API validates the JWT token in this header using the OAuth token endpoint. For information about this endpoint, see Configuration screen. Content-Type Format of request data Required application/json. Accept Format of response data Optional application/json. -
No other header fields are expected.
-
The request URL:
-
Always use the base instance for the company's Medallia installation.
-
cURL example
This curl invocation makes a request from the endpoint using the previously issued access token and including it as a "bearer" token, and the issued ID token as the "API token":
Create a request to get audit events
Use this endpoint to query the audit log and find events for a given tenant and a time range.
Requests are HTTP GET protocol. The API accesses resources from a URL that follows this format to create a request to fetch audit events.
-
api-host is the server for your company's Experience Cloud instance.
-
service is
audit-query-service
. -
api-version is
v2
. -
endpoint is
export
.
Make query requests with the query parameters shown in the table below. The API supports additional parameters to filter the matching audit events. Each filter specified restricts the amount of data queried and returned (logical AND, not OR).
Parameter | Description | Type | Required | Notes |
---|---|---|---|---|
tenantId | Unique identifier of the tenant to whom the event is associated. | String | Required | — |
startTime | Absolute start time of the filter period, encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Required | Format is: yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
endTime | Absolute end time of the filter period, encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Required | Format is: yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
f.category | Filter using the event category name. Use it to filter security events and configuration events. | String | Optional | For example: 'security'. |
f.application | Filter using application or product name. | String | Optional | For example: 'express'. |
f.username | Filter using the username value in the event. | String | Optional | — |
f.attrName | Filter using other event metadata attributes. | String | Optional | Format is: ?f.attrName=x&f.attrVal=123 . |
f.attrVal | Filter using other event metadata attribute values. | String | Optional | Format is: ?f.attrName=x&f.attrVal=123 . |
Event attributes
Query parameters f.attrName
and f.attrVal
provide a way to filter events having some extra attributes set in them. To filter by multiple attribute names and values, send comma-separated strings for each parameter. Each attribute name and value should correlate to each other.
For example, the call below filters by both color and tenant name attributes:
Response
When the job is successfully created, the response returns a unique UUID value. Use it to get the results of the job at a later point when the job has transitioned to the COMPLETED state. The response is a JSON object that includes:
Element | Description | Type | Notes |
---|---|---|---|
status | Status of the audit query job. | String | Values:
|
jobId | UUID of the audit job. | String | — |
statusTime | Audit query job timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
Sample request
Sample response
Check the status of a job
Use this endpoint to get the current status of a previously scheduled job. Use the previously returned job id value as a path parameter.
Requests are HTTP GET protocol. The API accesses resources from a URL that follows this format to retrieve the status of a job.
-
api-host is the server for your company's Experience Cloud instance.
-
service is
audit-query-service
. -
api-version is
v2
. -
endpoint is
export
. -
jobId identifies the audit query job whose status you are querying.
Response
A valid success response will return the original query parameters and the status of the job.
If the job has completed successfully, the filePath
parameter will indicate the path where the results are available.
If the job has erred for any reason, the failureReason
parameter will provide additional information related to the exception.
Element | Description | Type | Notes |
---|---|---|---|
id | Server generated event identifier. | String | — |
jobId | UUID of the audit job. | String | — |
params | Original query parameters. | Parameter data object | — |
status | Status of the action intended by the user. | String | Shows whether the action intended by the user succeeded. It is useful to monitor failed authentication attempts as suspicious behavior. |
filePath | Path where the results are available. | String | — |
createdAt | Audit query job timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
completedAt | Completion date timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
failureReason | Additional information related to the exception. | String | — |
timestamp | Timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | This element is only returned when the job could not be processed. Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
status | HTTP error code. | String | This element is only returned when the job could not be processed. |
error | Error description. | String | This element is only returned when the job could not be processed. |
path | Status check path and query parameters. | String | This element is only returned when the job could not be processed. |
Sample request
Sample success response
Sample error response
Get the job results
Use this endpoint to retrieve the results of a COMPLETED or FAILED job.
Requests are HTTP GET protocol. The API accesses resources from a URL that follows this format to retrieve the results of a job.
-
api-host is the server for your company's Experience Cloud instance.
-
service is
audit-query-service
. -
api-version is
v2
. -
endpoint is
export
. -
jobId identifies the audit query job whose status you are querying.
Response
When the job has successfully completed, all matching audit events are returned in the JSON Lines format with UTF-8 encoding, which is nothing but a JSON payload for each matching event delimited by a newline character. Each row represents one matching event in JSON format.
Element | Description | Type | Notes |
---|---|---|---|
timestamp | Event timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
dateTime | Audit event timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
eventId | UUID of the audit event identifier. | String | — |
actorId | Identifier of the user that triggered the audit event. | String | — |
name | Name of the user that triggered the audit event. | String | The name of the event is the identifier of the action itself. |
category | Audit event category name. | String | For example: 'security'. |
username | Username of the user that triggered the audit event. | String | — |
application | Application or product name. | String | For example: 'express'. |
tenant | Tenant name. | String | The tenant is usually the name of the company. |
tenantId | Tenant identifier. | String | The identifier is the same across instances and products. For example: "100440" for a company is the same when deployed in QA or in a production instance or across applications like Express, Digital, etc. |
instanceId | Instance identifier. | String | The identifier is unique per instance. For example: "101432" is the instance containing "100440" This instanceId differs between QA and production instances and across applications. |
instanceUrl | Instance URL. | String | — |
attributes | Fields with additional properties related to the audit event. | Attribute data object | — |
Sample request
Sample response
Cancel an existing job
Existing export jobs can be canceled if they are currently in PROCESSING or PENDING state and not progressing due to any issues. Use this endpoint to cancel jobs.
Requests are HTTP GET protocol. The API accesses resources from a URL that follows this format to cancel an existing job.
-
api-host is the server for your company's Experience Cloud instance.
-
service is
audit-query-service
. -
api-version is
v2
. -
endpoint is
export
. -
jobId identifies the audit query job whose status you are querying.
Response
When the job has successfully completed, all matching audit events are returned in the JSON Lines format with UTF-8 encoding, which is nothing but a JSON payload for each matching event delimited by a newline character. Each row represents one matching event in JSON format.
Element | Description | Type | Notes |
---|---|---|---|
status | Status of the audit query job. | String | Values:
|
jobId | UUID of the audit job. | String | — |
statusTime | Audit query job timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
timestamp | Timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | This element is only returned when the job could not be cancelled. Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
status | HTTP error code. | String | This element is only returned when the job could not be cancelled. |
error | HTTP error code description. | String | This element is only returned when the job could not be cancelled. |
message | Error description. | String | This element is only returned when the job could not be cancelled. |
path | Status check path and query parameters. | String | This element is only returned when the job could not be cancelled. |
Sample request
Sample success response
Sample error response
Resume an existing job
Existing export jobs which are not already in PENDING or PROCESSING state can be resumed. Use this endpoint to resume jobs.
Requests are HTTP GET protocol. The API accesses resources from a URL that follows this format to resume an existing job.
-
api-host is the server for your company's Experience Cloud instance.
-
service is
audit-query-service
. -
api-version is
v2
. -
endpoint is
export
. -
jobId identifies the audit query job whose status you are querying.
Response
This will restart and schedule the job to be run with the same query parameters as the original export job.
Element | Description | Type | Notes |
---|---|---|---|
status | Status of the audit query job. | String | Values:
|
jobId | UUID of the audit job. | String | — |
statusTime | Audit query job timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
timestamp | Timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | This element is only returned when the job could not be cancelled. Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
status | HTTP error code. | String | This element is only returned when the job could not be resumed. |
error | HTTP error code description. | String | This element is only returned when the job could not be resumed. |
message | Error description. | String | This element is only returned when the job could not be resumed. |
path | Status check path and query parameters. | String | This element is only returned when the job could not be resumed. |
Sample request
Sample response
Sample error response — Job is not pending, failed, cancelled
Delete an existing job
Existing export jobs can be deleted if they are currently in PROCESSING or PENDING state and not progressing due to any issues. Use this endpoint to delete jobs.
Requests are HTTP DELETE protocol. The API accesses resources from a URL that follows this format to delete an existing job.
-
api-host is the server for your company's Experience Cloud instance.
-
service is
audit-query-service
. -
api-version is
v2
. -
endpoint is
export
. -
jobId identifies the audit query job whose status you are querying.
Response
Existing export jobs which are not already in PENDING or PROCESSING state can be deleted.
Element | Description | Type | Notes |
---|---|---|---|
status | Status of the audit query job. | String | Values:
|
jobId | UUID of the audit job. | String | — |
statusTime | Audit query job timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
timestamp | Timestamp encoded as a JSON string of an ISO-8601 timestamp. | Datetime | This element is only returned when the job could not be cancelled. Format is yyyy-MM-dd HH:mm:ssZZ (e.g. 2024-01-01 11:30:00-0800). |
status | HTTP error code. | String | This element is only returned when the job could not be deleted. |
error | HTTP error code description. | String | This element is only returned when the job could not be deleted. |
message | Error description. | String | This element is only returned when the job could not be deleted. |
path | Status check path and query parameters. | String | This element is only returned when the job could not be deleted. |
Sample request
Sample response
Sample error response — Invalid job id