generated: '2026-08-15' method: searched source: https://developer.sprucehealth.com/docs/webhooks-overview.md docs: https://developer.sprucehealth.com/docs/webhooks-overview provider: Spruce Health providerId: spruce-health type: Webhooks description: >- Spruce Health's event surface is outbound HTTPS webhooks. Spruce POSTs a signed event envelope to endpoints an organization registers through the Public API. This is the full published event catalog, its delivery contract and its signature scheme, read from the Spruce Webhooks Overview (last updated by Spruce 2026-07-31). asyncapi_published: false asyncapi_note: >- Spruce publishes no AsyncAPI document. /asyncapi.yaml on the docs host returns 404 and no event schema file appears in the ReadMe registry alongside the OpenAPI. The events below are transcribed from the provider's own documentation and worked example payloads; no AsyncAPI has been authored on Spruce's behalf, because a generated one would assert a machine-readable contract the provider does not actually serve. probe: url: https://developer.sprucehealth.com/asyncapi.yaml http_status: 404 fetched: '2026-08-15' model: direction: outbound transport: HTTPS POST websocket: false websocket_note: >- No ws:// or wss:// surface is documented anywhere in Spruce's developer materials. Real-time delivery is server-to-endpoint HTTP, not a bidirectional socket. scope: >- All events published to an endpoint are scoped to the context of their owning organization. registration: operation: CreateWebhookEndpoint path: POST /webhooks/endpoints reference: https://developer.sprucehealth.com/reference/createwebhookendpoint note: >- The create response returns a signing secret. It is returned ONCE, at creation - subsequent listings never return it. management: list: GET /webhooks/endpoints get: GET /webhooks/endpoints/{endpointId} delete: DELETE /webhooks/endpoints/{endpointId} pause_resume: POST /webhooks/endpoints/{endpointId}/paused delivery_log: GET /webhooks/endpoints/{endpointId}/events delivery_log_retention: 30 days, returned 20 at a time with a pagination token envelope: fields: - name: object value: event description: Constant discriminator identifying the payload as an event envelope. - name: type description: The event type, e.g. contact.created. - name: eventTime format: RFC 3339 UTC description: When the event occurred. - name: data.object description: >- The full current state of the affected resource, itself carrying an `object` field naming its type (contact, conversation, conversationItem, scheduledMessage). example_shape: | { "object": "event", "type": "contact.created", "eventTime": "2024-05-15T00:00:00Z", "data": { "object": { "object": "contact", "id": "entity_...", ... } } } note: >- The envelope carries the whole resource, not a delta, so a consumer does not need a follow-up GET to apply the change. events: - type: contact.created resource: contact description: Occurs when a new contact is created. - type: contact.updated resource: contact description: Occurs when a contact is modified. - type: contact.deleted resource: contact description: Occurs when a contact is deleted. - type: contact.merged resource: contact description: Occurs when contacts are merged. added: '2026-04-15' note: >- Spruce's own event table describes this as "Occurs when contacts are deleted", which reads as a copy error against the event name and the worked merge example. Announced on the changelog 2026-04-15 as "New webhook event: contact.merged". - type: conversation.created resource: conversation description: Occurs when a new conversation is created. - type: conversation.updated resource: conversation description: Occurs when a conversation is modified. - type: conversation.deleted resource: conversation description: Occurs when a conversation is deleted. - type: conversationItem.created resource: conversationItem description: Occurs when a new conversation item is created. correlates_with: - PostConversationMessage (requestID) - PostMessageFromEndpoint (RequestID) - CreateConversation (postMessageRequestId) - type: conversationItem.updated resource: conversationItem description: Occurs when a conversation item is modified. - type: conversationItem.deleted resource: conversationItem description: Occurs when a conversation item is deleted. correlates_with: - DeleteConversationItem (requestId) - type: conversationItem.restored resource: conversationItem description: Occurs when a conversation item is restored. note: >- Deletion is a soft delete that leaves a restorable placeholder, which is why a restore is an event in its own right. - type: scheduledMessage.created resource: scheduledMessage description: Occurs when a message is scheduled. added: '2026-07-31' - type: scheduledMessage.updated resource: scheduledMessage description: Occurs when a scheduled message is modified. added: '2026-07-31' - type: scheduledMessage.deleted resource: scheduledMessage description: Occurs when a scheduled message is deleted before it was sent. added: '2026-07-31' - type: scheduledMessage.sent resource: scheduledMessage description: Occurs when a scheduled message reaches its send time and is posted. added: '2026-07-31' event_count: 15 delivery: scheme_required: https scheme_note: Spruce will only send events to endpoints that support HTTPS. ack_status: 2XX ack_window_seconds: 5 ordering: sent_in_order: true delivered_in_order: false note: >- Events are sent in the order they occur, but may not arrive in that order. Consumers must be able to handle out-of-order events - eventTime is the field to order on. retry: interval_minutes: 2 max_attempts: 10 trigger: any non-2XX response, or no response within the 5-second window rate_limit: events_per_minute: 1000 scope: per endpoint behavior: >- If the limit is exceeded, events resume sending after the rate limit window has passed. signature: header: X-Spruce-Signature algorithm: HMAC-SHA256 encoding: base64 secret_issued: at endpoint creation, returned once and never again verification: >- Base64-decode the X-Spruce-Signature header, HMAC-SHA256 the raw request body with the endpoint secret, and compare the two in constant time. Spruce publishes a Go reference implementation using hmac.Equal in the Webhooks Overview. consumer_guidance: mapping_items_to_contacts: >- A conversationItem event carries the conversation id; pass it to GET /conversations/{conversationId} to resolve the containing thread. For conversations with unsaved or multiple matching contacts, the rawValue of the externalParticipant endpoint can be passed to POST /contacts/search to resolve candidate contacts. polling_alternative: >- Where webhooks are not an option, ListConversations with orderBy=last_message plus startFrom is the documented polling pattern for detecting new activity. access: gated: true note: >- Webhooks are only reachable through the Public API, so they inherit its gate - the Communicator plan plus API access enabled by Spruce Support. request_form: https://sprucehealth.com/spruce-api maintainers: - FN: Kin Lane email: kin@apievangelist.com