A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Heap API is how an app or AI agent sends data into a Heap environment: recording a custom server-side event, tying an anonymous visitor to a known identity, attaching properties to a user or an account, and submitting users for deletion. Access is granted through an environment ID that names the project the data lands in, while the user-deletion methods additionally require an account API key, so the credential sets which environment a call can reach. Heap is a one-way ingestion API: data flows in and is read back through reports, and there is no push of events out to an app.
How an app or AI agent connects to Heap determines what it can reach. There is a route for sending data in, which identifies itself with an environment ID, and a separate management route for deleting users, which uses an account API key. Each is governed by the credential behind it.
The ingestion methods take JSON request bodies and authenticate by including app_id, the environment ID, in the body. Standard hosting is at https://heapanalytics.com; EU datacenter environments use https://c.eu.heap-api.com for the same paths. There is no API key, scope, or token on these calls, and Heap publishes no granular permissions for them.
The user-deletion methods sit under a public v0 path and use an account API key rather than just an app_id. An agent POSTs app_id and api_key over HTTP Basic auth to the auth_token method to receive a bearer access_token, then submits and polls deletions with that token. It is used for privacy and data-subject deletion requests.
Heap is now part of Contentsquare, and Contentsquare publishes an official Model Context Protocol server that lets AI agents query experience and analytics data, including coverage for Heap and Hotjar, in plain language. It works with MCP clients like Claude, ChatGPT, Microsoft Copilot, Dust, VS Code, and Cursor. It is a separate analytics-query surface, not the Heap ingestion API documented here, and its tool-call allowances are tied to Contentsquare plans.
The ingestion methods authenticate by including app_id in the request body, the environment ID of the project the data lands in. There is no API key, secret, or token alongside it, and no per-method scopes, so the app_id alone authorizes every ingestion method for that one environment. It is found in Heap under Account, Manage, Privacy & Security.
The user-deletion methods use an account API key. An agent sends app_id and api_key over HTTP Basic auth to the auth_token method and receives a bearer access_token, then puts that token in the Authorization header on the user_deletion and deletion_status calls. The api_key is generated in Heap under Account, Manage, Privacy & Security.
The Heap API is built around sending data in. An agent can record custom events, tie an anonymous visitor to a known identity, and attach properties to users and accounts, one at a time or in bulk. A separate management area lets an agent delete users for privacy requests.
Methods for sending custom events into Heap server-side.
Methods for tying an anonymous visitor to a known identity.
Methods for attaching custom properties to users.
Methods for attaching custom properties to accounts.
Management methods for deleting users and checking deletion status.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
EventsMethods for sending custom events into Heap server-side.2 | ||||||
| POST | /api/track | Send a single custom server-side event for a user, identified by identity or user_id. | write | app_id | Current | |
Authenticated only by app_id in the body; no scopes. Requires identity or user_id, but not both. Limited to 30 requests per 30 seconds per identity per app_id. Acts onevent Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limit30 requests / 30s per identity per app_id SourceOfficial documentation ↗ | ||||||
| POST | /api/track | Send up to 1000 custom events in a single batch, each with its own identity, event, timestamp, and properties. | write | app_id | Current | |
Same path as track, with an events array. Max 1000 events per request. An optional idempotency_key prevents duplicates. Browser fetch, jQuery, and XMLHttpRequest are not supported. Acts onevent Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limit1000 events/min per identity; 15,000 events/min per app_id SourceOfficial documentation ↗ | ||||||
IdentityMethods for tying an anonymous visitor to a known identity.1 | ||||||
| POST | /api/v1/identify | Tie an anonymous user_id from the Heap SDK to a known identity, like an email, so history merges under one profile. | write | app_id | Current | |
Authenticated only by app_id. One identity per user_id; at most 10 user_ids mapped to one identity over a rolling one-month window. identity is case-sensitive, max 255 characters. Acts onidentity Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
User propertiesMethods for attaching custom properties to users.2 | ||||||
| POST | /api/add_user_properties | Attach custom properties to a single identified user without tying them to a session. | write | app_id | Current | |
Authenticated only by app_id. Creates the identity if it does not exist. Use the lowercase key 'email' to write the built-in Email field. Limited to 30 requests per 30 seconds per identity per app_id. Acts onuser Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limit30 requests / 30s per identity per app_id SourceOfficial documentation ↗ | ||||||
| POST | /api/add_user_properties | Attach custom properties to up to 1000 users in a single batch, each entry keyed by identity. | write | app_id | Current | |
Same path as add user properties, with a users array. Max 1000 users per request. Use the lowercase key 'email' for the built-in Email field. Acts onuser Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Account propertiesMethods for attaching custom properties to accounts.2 | ||||||
| POST | /api/add_account_properties | Attach custom account-level properties for a single account, keyed by account_id. | write | app_id | Current | |
Authenticated only by app_id. Requires an account_id (or the Salesforce integration). Each property key and value must be a number or a string under 1024 characters. Acts onaccount Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/add_account_properties | Attach custom account-level properties for up to 1000 accounts in a single batch. | write | app_id | Current | |
Same path as add account properties, with an accounts array of account_id and properties. Max 1000 accounts per request. Acts onaccount Permission (capability) app_idVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
User deletionManagement methods for deleting users and checking deletion status.3 | ||||||
| POST | /api/public/v0/auth_token | Exchange an app_id and account API key for a temporary bearer access_token used by the deletion methods. | read | api_key | Current | |
Uses HTTP Basic auth with app_id as the username and api_key as the password. Returns access_token on a 200; returns 401 when credentials are invalid. The api_key is generated under Account, Manage, Privacy & Security. Acts onauth_token Permission (capability) api_keyVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/public/v0/user_deletion | Submit users to be deleted from Heap and receive a deletion request id. | write | api_key | Current | |
Requires the bearer access_token in the Authorization header. Takes a users array of user_id or identity, up to 10,000 users per request. Permanently removes user data. Acts onuser_deletion Permission (capability) api_keyVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/public/v0/deletion_status/:deletion_request_id | Fetch the status of a previously submitted user-deletion request by its id. | read | api_key | Current | |
Requires the bearer access_token in the Authorization header. The deletion_request_id comes from the user_deletion response. Acts onuser_deletion Permission (capability) api_keyVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Heap does not push events out to an app. Activity recorded through these methods lands in Heap, where it is queried in reports rather than streamed back, so an integration sends data in and does not receive callbacks.
| Event | What it signals | Triggered by |
|---|
Heap limits how fast and how much an app can send. Ingestion is capped per identity and per environment, single calls carry per-field size limits, and bulk calls cap how many records fit in one request.
Heap meters ingestion per identity and per environment, not by a per-method cost. The single track and add user properties methods are limited to 30 requests per 30 seconds per identity per app_id. Bulk track is limited to 1000 events per minute per identity per app_id and 15,000 events per minute per app_id. The Identify method limits one identity per user_id, and at most 10 user_ids mapped to one identity over a rolling one-month window. Going over returns an error response rather than a documented retry header.
The ingestion methods do not page, because they send data in rather than read it back. The user-deletion flow is asynchronous instead of paginated: a deletion request returns an id, and a separate status method is polled with that id to check progress.
A single track call caps the event name at 1024 characters, an identity at 255 characters, and each property key or value at 1024 characters. A bulk track call carries at most 1000 events; bulk add user properties at most 1000 users; bulk add account properties at most 1000 accounts; and a user-deletion request at most 10,000 users. An array property is flattened to a string joined by a double-pipe and capped at 1024 characters.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 200 | OK | The ingestion call was accepted. A successful track, identify, or add-properties call returns an HTTP 200, typically with an empty JSON body. | Treat 200 as accepted. Because ingestion is asynchronous, a 200 confirms the request was taken, not that the data is queryable yet. |
| 400 | Bad Request | The request was malformed or violated a constraint, like a missing required field, both identity and user_id supplied to track, or a property over the size limit. | Read the error message, fix the body to satisfy the field and size rules, and resend. The request is not retryable as-is. |
| 401 | Unauthorized | On the management methods, the app_id and api_key credentials were invalid when requesting an auth_token, or the bearer access_token was missing or expired. | Confirm the api_key and app_id are correct, request a fresh access_token, and send it in the Authorization header. |
Heap's server-side ingestion endpoints carry no dated versioning. Most live under an unversioned path, the Identify method sits under a v1 path, and the user-deletion management endpoints sit under a v0 path.
Heap's server-side ingestion API carries no dated versioning and Heap publishes no public API changelog. The track, add user properties, and add account properties methods live under an unversioned path; the Identify method lives under a v1 path; and the user-deletion management methods live under a public v0 path. There is no version header to set.
Heap extended the server-side ingestion API beyond single calls. Bulk forms of track, add user properties, and add account properties were added, each capped at 1000 records per request, alongside the account-properties methods for attaching data at the account level. Heap does not date these changes in a public changelog.
Heap does not publish a dated API changelog, so there is no version to pin.
Heap API reference ↗Bollard AI sits between a team's AI agents and Heap. Grant each agent exactly the access it needs, read or write, method by method, and every call is checked and logged.