List an installed app's activity
The app_installations.activity operation: GET /api/v1/app_installations/{id}/activity in the REST API and the app_installations_activity tool in the MCP server.
/api/v1/app_installations/{id}/activityThe installed app's activity feed in this organization, newest first, from the audit log: every change it made
(outcome: "succeeded"), every call that asked for approval instead of running (approval_requested, with the
approval's current status), and every run a person approved (ran_after_approval), each with the operation,
its target, the mode, the entity or brand, the surface (via), the app's OAuth client and the installer the
call was attributed to (onBehalfOfUserId). Reads aren't in the audit log, so they aren't listed. Both modes
are listed; usage is today's use (UTC) of its daily limits in the request's mode. Paginate with limit
(1–100, default 10) and starting_after.
At a glance
- REST:
GET /api/v1/app_installations/{id}/activity - MCP tool:
app_installations_activity - Operation ID:
app_installations.activity - Scope: Organization
- Permission:
audit:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Pagination:
limit(at most 100) andstarting_after - Authentication: API key with the
audit:readscope - Since: M10
Request
Path parameters
| Field | Type | Description |
|---|---|---|
id | ains_… ID |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
limit | integer (1 to 100) | No | |
starting_after | aud_… ID | No |
Response
200 OK with a JSON object, a page of the list (newest first):
| Field | Type | Description |
|---|---|---|
object | "list" | |
data | array of object | |
data[].id | aud_… ID | |
data[].object | "activity_entry" | |
data[].at | string | |
data[].action | string | |
data[].operationId | string or null | |
data[].target | string | |
data[].livemode | boolean or null | |
data[].entityId | ent_… ID or null | |
data[].brandId | brd_… ID or null | |
data[].via | one of console, api, mcp, assistant, portal, job or null | |
data[].clientId | string or null | |
data[].onBehalfOfUserId | string or null | |
data[].appInstallationId | ains_… ID or null | |
data[].outcome | one of succeeded, approval_requested, ran_after_approval | |
data[].approval | object or null | |
has_more | boolean | |
next_cursor | aud_… ID or null | |
usage | object | |
usage.day | string | |
usage.livemode | boolean | |
usage.mutations | integer | |
usage.amounts | array of object | |
usage.amounts[].operationId | string | |
usage.amounts[].amount | money |
Examples
A refund above the daily limit, approved and run
GET /api/v1/app_installations/ains_01m4ttwd3veh9apbewxheq5xhc/activity
Authorization: Bearer or_test_…
Response (200):
{
"object": "list",
"data": [
{
"object": "activity_entry",
"livemode": false,
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"via": "mcp",
"clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
"onBehalfOfUserId": "usr_01m4ttwd3veh9apbewxheq5xh6",
"appInstallationId": null,
"id": "aud_01m4ttwd3veh9apbewxheq5xhh",
"at": "2026-10-26T15:02:11.000Z",
"action": "refunds.create",
"operationId": "refunds.create",
"target": "re_01m4ttwd3veh9apbewxheq5xhj",
"outcome": "ran_after_approval",
"approval": {
"id": "apr_01m4ttwd3veh9apbewxheq5xhk",
"status": "executed",
"approvedBy": ["usr_01m4ttwd3veh9apbewxheq5xh7"]
}
},
{
"object": "activity_entry",
"livemode": false,
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"via": "mcp",
"clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
"onBehalfOfUserId": "usr_01m4ttwd3veh9apbewxheq5xh6",
"appInstallationId": null,
"id": "aud_01m4ttwd3veh9apbewxheq5xhf",
"at": "2026-10-26T14:30:00.000Z",
"action": "approvals.request",
"operationId": "refunds.create",
"target": "apr_01m4ttwd3veh9apbewxheq5xhk",
"outcome": "approval_requested",
"approval": {
"id": "apr_01m4ttwd3veh9apbewxheq5xhk",
"status": "executed",
"approvedBy": ["usr_01m4ttwd3veh9apbewxheq5xh7"]
}
},
{
"object": "activity_entry",
"livemode": false,
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"via": "mcp",
"clientId": "ocl_01m4ttwd3veh9apbewxheq5xha",
"onBehalfOfUserId": "usr_01m4ttwd3veh9apbewxheq5xh6",
"appInstallationId": null,
"id": "aud_01m4ttwd3veh9apbewxheq5xhg",
"at": "2026-10-26T14:10:00.000Z",
"action": "refunds.create",
"operationId": "refunds.create",
"target": "re_01m4ttwd3veh9apbewxheq5xhm",
"outcome": "succeeded",
"approval": null
}
],
"has_more": false,
"next_cursor": null,
"usage": {
"day": "2026-10-26",
"livemode": false,
"mutations": 2,
"amounts": [
{
"operationId": "refunds.create",
"amount": {
"amount": "450000000",
"currency": "EUR"
}
}
]
}
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | limit or starting_after is invalid. | Fix the fields listed in details.issues and send the request again. |
resource_not_found | 404 | No installation with this ID exists in the organization. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
permission_denied | 403 | You can't read the organization's audit log. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, dry_run_not_supported, rate_limited, internal_error.