generated: '2026-08-15' method: searched source: https://developer.sprucehealth.com/docs/overview.md docs: - https://developer.sprucehealth.com/docs/overview - https://developer.sprucehealth.com/docs/integration-guide - https://developer.sprucehealth.com/docs/webhooks-overview provider: Spruce Health providerId: spruce-health description: >- Cross-cutting runtime semantics of the Spruce Health API, read from the Spruce API Overview and confirmed against the OpenAPI Spruce publishes for developer.sprucehealth.com. Spruce documents an unusually complete runtime contract for a company of its size: an idempotency key on every mutating request, four rate-limit response headers across two windows, a cursor pagination scheme, a correlation id on every response, and a single structured error envelope. baseURL: https://api.sprucehealth.com/v1 authentication: style: bearer-token scheme: http header: 'Authorization: Bearer ' securityScheme: spruceAPIToken issuance: >- Tokens are generated by an administrator from the "API Access" section of Settings in the web application, and only after Spruce Support has enabled API access for the organization. API access is part of the Communicator plan. failure_status: 403 failure_note: Use of an incorrect or disabled token returns a 403. scope: organization see: authentication/spruce-health-authentication.yml idempotency: supported: true header: s-idempotency-key applies_to: All POST and PATCH requests (optional header parameter) key_max_length: 255 key_generation: caller-generated retention: 24 hours duplicate_behavior: >- Multiple requests to the same path with a duplicate idempotency key are rejected with a 422 error status. Spruce does NOT replay the original response - a repeat is an error, not a cached success, so a client retrying after a network timeout must treat 422 as "the first attempt landed" rather than as a validation failure. declared_in_spec: true spec_component: '#/components/parameters/s-idempotency-key' operations_carrying_the_header: 14 operations: - CreateContact - UpdateContact - CreateContactIntegrationLink - CreateContactField - CreateContactTag - CreateConversation - UpdateConversation - PostConversationMessage - ScheduleConversationMessage - CreateConversationTag - PostCreateProxyCall - PostMessageFromEndpoint - CreateWebhookEndpoint - ModifyWebhookEndpointPaused source: https://developer.sprucehealth.com/docs/overview.md pagination: style: cursor request_params: - name: pageSize in: query note: >- The OpenAPI declares pageSize (int32) as the page-size parameter; maximum 500 on ListContacts and ListConversations. The prose overview calls the same concept "limit". Trust the spec parameter name - pageSize is what the operations declare. - name: paginationToken in: query note: >- Omit or send the empty string to start from the beginning of available data; send the non-empty value from a previous response to fetch the next page. response_fields: - name: hasMore note: true when further results remain. - name: paginationToken note: cursor to pass on the next request. - name: totalCount note: total matching records. collection_envelope: >- List responses are objects keyed by the resource name (contacts, conversations, conversationItems, ...), not bare arrays. ordering: parameter: orderBy values: - created - last_message note: >- ListConversations supports orderBy plus startFrom (RFC 3339). Ordering by last_message combined with startFrom is the documented way to poll for conversations with new activity without a webhook. consistency: >- Listing conversations and conversation items is an eventually consistent view; new records may take a short time to appear. rate_limiting: scope: per-organization scope_note: 'Rate limits are applied on a per-organization basis, NOT per-credential.' windows: - 60 seconds - 24 hours response_headers: - name: s-ratelimit-limit meaning: Maximum calls currently allowed in the 60-second window. declared_in_spec: true - name: s-ratelimit-remaining meaning: Remaining calls in the current 60-second window. declared_in_spec: true - name: s-ratelimit-daily-limit meaning: Maximum calls currently allowed in the 24-hour window. declared_in_spec: false - name: s-ratelimit-daily-remaining meaning: Remaining calls in the current 24-hour window. declared_in_spec: false absent_header_semantics: >- If a given throttling header is not present, the request is not rate limited on that dimension. numeric_limits_published: false exhaustion_status: not-documented retry_after: not-documented see: rate-limits/spruce-health-rate-limits.yml tracing: request_id_header: s-request-id direction: response declared_in_spec: true example_shape: 0E5QDGJC030000E5QDGJC03000 note: >- Returned on responses as the id of the request. Distinct from the requestId / postMessageRequestId values returned in message and delete response BODIES, which correlate an asynchronous operation with the conversationItem.created or conversationItem.deleted webhook event that completes it. async_correlation: pattern: request-id-to-webhook description: >- Several mutations complete asynchronously. The API returns immediately with a correlation id in the body, and the caller matches it against the requestID field of the webhook event that fires when the work actually finished. cases: - operation: PostConversationMessage field: requestID completes_with: conversationItem.created - operation: PostMessageFromEndpoint field: RequestID completes_with: conversationItem.created - operation: CreateConversation field: postMessageRequestId completes_with: conversationItem.created note: Only when a message is included in the conversation-creation request. - operation: DeleteConversationItem field: requestId completes_with: conversationItem.deleted note: Soft delete - a restorable placeholder is created, not a permanent removal. versioning: style: uri-path current: v1 in_base_url: true spec_version: 1.0.0 policy_published: false note: >- The version lives in the base path (https://api.sprucehealth.com/v1). Spruce publishes no written versioning or deprecation policy, and no operation in the OpenAPI carries deprecated: true. Additive change is announced on the What's New feed rather than through a version bump. see: lifecycle/spruce-health-lifecycle.yml errors: envelope: custom-json rfc9457: false content_type: application/json shape: statusCode: integer type: string message: string example: | { "statusCode": 400, "type": "invalid_input", "message": "invalid input" } spec_component: '#/components/schemas/error' see: errors/spruce-health-problem-types.yml field_expansion: supported: false note: No expand / fields / sparse-fieldset parameter is declared on any operation. metadata: supported: partial note: >- There is no free-form metadata bag. Extensibility is modelled as first-class resources instead - organization contact fields (customContactFields / organizationContactFields on a contact), contact tags and conversation tags - each with its own create and list operations. identifiers: style: prefixed-opaque note: >- Resource ids carry a type prefix followed by an opaque token, so an id is self-describing at a glance. prefixes: - prefix: entity_ applies_to: contacts, organizations, organization members, teams - prefix: entityContact_ applies_to: a phone number or email address on a contact - prefix: entityCustomField_ applies_to: a custom field value on a contact - prefix: t_ applies_to: conversations (threads) - prefix: ti_ applies_to: conversation items source: https://developer.sprucehealth.com/docs/webhooks-overview.md note_on_evidence: >- Prefixes are read from the worked example payloads Spruce publishes in the Webhooks Overview, not from an id-format reference page - Spruce does not publish one. webhooks: signature_header: X-Spruce-Signature algorithm: HMAC-SHA256 encoding: base64 transport: HTTPS only ack_window_seconds: 5 ack_status: 2XX see: asyncapi/spruce-health-webhooks.yml media: upload: multipart/form-data on POST /media note: >- Returns a reusable media ID for the attachmentID field of message operations. The Content-Type and Content-Disposition headers on the multipart media field carry filename and type metadata and affect how the file renders in the app. maintainers: - FN: Kin Lane email: kin@apievangelist.com