openapi: 3.1.0 info: title: Heap Partner Webhooks (Data-out API) description: | Heap's partner webhook surface (also called the "Data-out API") delivers behavioral segment membership deltas to partner-hosted endpoints. The only documented webhook action today is `segment.users.sync`, which sends adds and removes for a Heap segment on a roughly 4-hour cadence. Partners register an HTTPS endpoint with Heap and receive POST requests signed with a `Heap-Hash` header (timestamp + HMAC-SHA256 of the body using a shared `webhook_secret_key`). Implementations should verify the timestamp is within tolerance, recompute the signature, and respond `200 OK` to avoid retries. Source: https://github.com/heap/heap-partner-api-reference (webhook_spec.yaml) version: "0.0.1" contact: name: Heap Developers url: https://developers.heap.io/ servers: - url: https://partner.example.com description: Partner-hosted webhook receiver (registered with Heap) tags: - name: Webhooks description: | Partner-registered webhook endpoints invoked by Heap. The only documented action type is `segment.users.sync`, which delivers delta adds/removes for a Heap behavioral segment. Signature verification: 1. Parse the `Heap-Hash` header (comma-separated key:value pairs). 2. Confirm the `ts` value is within the partner's tolerance window. 3. Concatenate `${ts}${requestbody}`. 4. Compute HMAC-SHA256 using the `webhook_secret_key` assigned at webhook creation. 5. Constant-time compare against the `hmac` value from the header. Return `200 OK` on success; `429` or other non-2xx responses trigger retries by Heap. paths: /{partner_webhook_sync_url}: post: summary: segment.users.sync webhook receiver description: | Heap POSTs a delta sync payload to the partner's registered webhook URL whenever segment membership changes need to be propagated. operationId: segmentUsersSync tags: - Webhooks parameters: - name: partner_webhook_sync_url in: path required: true description: Partner-registered HTTPS path that receives segment syncs. schema: type: string example: heap_webhook - $ref: '#/components/parameters/SignatureHeader' requestBody: required: true description: Delta sync payload describing users to add or remove. content: application/json: schema: $ref: '#/components/schemas/WebhookSyncRequest' examples: DeltaSyncAdd: summary: Segment sync to add users value: id_token: '7a36ae58-c4b9-11eb-8529-0242ac130003' action_type: segment.users.sync customer_config: fields: - field_id: workspace field_display_name: Workspace value: id: workspace_1 display_name: Workspace 1 data: segment: id: 1338065 name: Free Customers sync_info: page_number: 1 total_pages: 5 sync_task_id: 'afe74af0-496e-11ec-81d3-0242ac130003' add: - id: user1@email.com - id: user2@email.com DeltaSyncRemove: summary: Segment sync to remove users value: id_token: '7a36ae58-c4b9-11eb-8529-0242ac130003' action_type: segment.users.sync customer_config: fields: - field_id: workspace field_display_name: Workspace value: id: workspace_1 display_name: Workspace 1 data: segment: id: 1338065 name: Free Customers sync_info: page_number: 1 total_pages: 5 sync_task_id: 'afe74af0-496e-11ec-81d3-0242ac130003' remove: - id: user3@email.com - id: user4@email.com responses: "200": description: Sync acknowledged. "403": $ref: '#/components/responses/Unauthorized' "429": $ref: '#/components/responses/TooManyRequests' default: $ref: '#/components/responses/Default' components: parameters: SignatureHeader: name: Heap-Hash in: header required: true description: | Heap signature header. Comma-separated key:value pairs containing a timestamp (`ts`) and HMAC-SHA256 signature (`hmac`). schema: type: string example: ts:150000000,hmac:XXXXXXXXX schemas: WebhookSyncRequest: type: object properties: id_token: type: string format: uuid description: Identifier for the Heap customer driving the sync. action_type: type: string enum: - segment.users.sync description: Webhook action type. Only `segment.users.sync` is documented. customer_config: $ref: '#/components/schemas/CustomerConfig' data: $ref: '#/components/schemas/SegmentDeltaSync' CustomerConfig: type: object description: Optional customer-supplied configuration captured during integration setup. properties: fields: type: array items: type: object properties: field_id: type: string description: ID for the customer-configured field. field_display_name: type: string description: Display label shown to the customer. field_type: type: string enum: - identity_mapping description: Optional field type, e.g. identity mapping selectors. value: type: object properties: id: type: string description: Identifier for the field value selected by the customer. display_name: type: string description: Display label for the selected field value. SegmentDeltaSync: type: object properties: segment: $ref: '#/components/schemas/SegmentInfo' sync_info: $ref: '#/components/schemas/SyncInfo' add: type: array description: Users entering the segment since the last sync. items: type: object properties: id: type: string description: User identifier per the customer's chosen mapping. remove: type: array description: Users exiting the segment since the last sync. items: type: object properties: id: type: string description: User identifier per the customer's chosen mapping. SegmentInfo: type: object properties: id: type: integer format: int64 description: Heap segment ID. name: type: string description: Heap segment name. SyncInfo: type: object properties: page_number: type: integer format: int64 description: Current page number in this sync run. total_pages: type: integer format: int64 description: Total pages in this sync run. sync_task_id: type: string format: uuid description: Unique identifier for this sync run. responses: Unauthorized: description: Signature verification failed. content: application/json: schema: type: object properties: error: type: string description: Specific error. example: error: Invalid signature TooManyRequests: description: Rate limited; Heap will retry. Default: description: Unexpected 4XX/5XX response; Heap will retry.