Spruce Contacts API

List, search, create, retrieve, update, and delete the contacts (patients and other parties) in a Spruce organization, plus manage contact custom fields, contact tags, contact-to-conversation relationships, integration links to external systems (EHR/PM), and send Spruce invites to contacts.

OpenAPI Specification

spruce-health-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Spruce Public API
  description: >-
    The Spruce Public API connects a Spruce Health organization to internal
    tools, electronic health records (EHRs), practice management systems, and
    other external systems so practices can automate workflows, sync data, and
    receive real-time events. It is a RESTful API over HTTPS with a base URL of
    https://api.sprucehealth.com/v1 and Bearer token authentication
    (Authorization: Bearer <your-token>); tokens are generated by administrators
    from the "API Access" section of Settings after Spruce Support enables API
    access for the organization (API access is part of the Communicator plan).


    Grounding note: the base URL and Bearer auth are confirmed from the Spruce
    developer documentation, and the following paths are confirmed directly from
    the API reference: GET /contacts, GET /conversations,
    POST /conversations/{conversationId}/messages, GET /webhooks/endpoints,
    POST /webhooks/endpoints, and GET /internalendpoints. The remaining paths and
    all request/response schemas are honestly MODELED from the published
    operation catalog (developer.sprucehealth.com/llms.txt) and documented
    behavior; exact request/response bodies should be reconciled against the
    live reference and the machine-readable OpenAPI Spruce publishes.
  version: '1.0'
  contact:
    name: Spruce Health
    url: https://developer.sprucehealth.com
  x-endpointsModeled: true
servers:
  - url: https://api.sprucehealth.com/v1
    description: Spruce Public API
security:
  - bearerAuth: []
tags:
  - name: Contacts
    description: Contacts (patients and other parties) in a Spruce organization.
  - name: Conversations
    description: Conversations (message threads) in a Spruce organization.
  - name: Messages
    description: Conversation items, messages, media, endpoints, and scheduled messages.
  - name: Webhooks
    description: Webhook endpoints for real-time contact / conversation events.
paths:
  /contacts:
    get:
      operationId: listContacts
      tags:
        - Contacts
      summary: List contacts
      description: Lists all contacts available to a given organization. Confirmed path.
      parameters:
        - name: pageSize
          in: query
          schema:
            type: integer
            format: int32
            minimum: 1
            maximum: 200
        - name: paginationToken
          in: query
          schema:
            type: string
      responses:
        '200':
          description: A list of contacts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Contact'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: createContact
      tags:
        - Contacts
      summary: Create a contact
      description: Creates a new contact in the organization. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Contact'
      responses:
        '200':
          description: The created contact.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Contact'
        '403':
          $ref: '#/components/responses/Forbidden'
  /contacts/search:
    get:
      operationId: searchContacts
      tags:
        - Contacts
      summary: Search contacts
      description: Search contacts by name, phone, email, or other fields. Modeled.
      parameters:
        - name: query
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Matching contacts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Contact'
  /contacts/{contactId}:
    parameters:
      - name: contactId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: contact
      tags:
        - Contacts
      summary: Get a contact
      description: Retrieves a single contact by ID. Modeled.
      responses:
        '200':
          description: The requested contact.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Contact'
        '403':
          $ref: '#/components/responses/Forbidden'
    patch:
      operationId: updateContact
      tags:
        - Contacts
      summary: Update a contact
      description: Updates fields on an existing contact. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Contact'
      responses:
        '200':
          description: The updated contact.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Contact'
    delete:
      operationId: deleteContact
      tags:
        - Contacts
      summary: Delete a contact
      description: Deletes a contact from the organization. Modeled.
      responses:
        '204':
          description: Contact deleted.
  /contacts/{contactId}/conversations:
    parameters:
      - name: contactId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: contactConversations
      tags:
        - Contacts
      summary: List a contact's conversations
      description: Lists the conversations associated with a contact. Modeled.
      responses:
        '200':
          description: Conversations for the contact.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Conversation'
  /contacts/{contactId}/integration-links:
    parameters:
      - name: contactId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: contactIntegrationLinks
      tags:
        - Contacts
      summary: List a contact's integration links
      description: Lists links between a contact and external systems (EHR/PM). Modeled.
      responses:
        '200':
          description: Integration links for the contact.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/IntegrationLink'
    post:
      operationId: createContactIntegrationLink
      tags:
        - Contacts
      summary: Create a contact integration link
      description: Links a contact to a record in an external system. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntegrationLink'
      responses:
        '200':
          description: The created integration link.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationLink'
  /contacts/fields:
    get:
      operationId: contactFields
      tags:
        - Contacts
      summary: List contact custom fields
      description: Lists the custom fields defined for contacts. Modeled.
      responses:
        '200':
          description: Contact fields.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
    post:
      operationId: createContactField
      tags:
        - Contacts
      summary: Create a contact custom field
      description: Creates a new custom field for contacts. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: The created contact field.
  /contacts/tags:
    get:
      operationId: contactTags
      tags:
        - Contacts
      summary: List contact tags
      description: Lists the tags that can be applied to contacts. Modeled.
      responses:
        '200':
          description: Contact tags.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Tag'
    post:
      operationId: createContactTag
      tags:
        - Contacts
      summary: Create a contact tag
      description: Creates a new contact tag. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Tag'
      responses:
        '200':
          description: The created contact tag.
  /conversations:
    get:
      operationId: listConversations
      tags:
        - Conversations
      summary: List conversations
      description: Lists conversations in the organization. Confirmed path and parameters.
      parameters:
        - name: pageSize
          in: query
          schema:
            type: integer
            format: int32
            minimum: 1
            maximum: 200
          description: How many conversations to return at one time (max 200).
        - name: paginationToken
          in: query
          schema:
            type: string
          description: Token to fetch subsequent pages; cannot be combined with startFrom.
        - name: orderBy
          in: query
          required: true
          schema:
            type: string
            enum:
              - created
              - last_message
          description: Order results by creation time or last message.
        - name: startFrom
          in: query
          schema:
            type: string
            format: date-time
          description: Only return conversations whose ordering field value is at or after this RFC 3339 timestamp.
      responses:
        '200':
          description: A list of conversations.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Conversation'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: createConversation
      tags:
        - Conversations
      summary: Create a conversation
      description: Creates a new conversation. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Conversation'
      responses:
        '200':
          description: The created conversation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'
  /conversations/{conversationId}:
    parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: conversation
      tags:
        - Conversations
      summary: Get a conversation
      description: Retrieves a single conversation by ID. Modeled.
      responses:
        '200':
          description: The requested conversation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'
    patch:
      operationId: updateConversation
      tags:
        - Conversations
      summary: Update a conversation
      description: Updates an existing conversation. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Conversation'
      responses:
        '200':
          description: The updated conversation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'
  /conversations/tags:
    get:
      operationId: conversationTags
      tags:
        - Conversations
      summary: List conversation tags
      description: Lists the tags that can be applied to conversations. Modeled.
      responses:
        '200':
          description: Conversation tags.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Tag'
    post:
      operationId: createConversationTag
      tags:
        - Conversations
      summary: Create a conversation tag
      description: Creates a new conversation tag. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Tag'
      responses:
        '200':
          description: The created conversation tag.
  /conversations/{conversationId}/messages:
    parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: postConversationMessage
      tags:
        - Messages
      summary: Post a message to a conversation
      description: Posts a new message into a conversation. Confirmed path.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageCreate'
      responses:
        '200':
          description: The created conversation item (message).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationItem'
        '403':
          $ref: '#/components/responses/Forbidden'
  /conversations/{conversationId}/items:
    parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: conversationItems
      tags:
        - Messages
      summary: List conversation items
      description: Lists the items (messages, calls, faxes, events) in a conversation. Modeled.
      responses:
        '200':
          description: Conversation items.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ConversationItem'
  /conversations/{conversationId}/items/{itemId}:
    parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
      - name: itemId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: conversationItem
      tags:
        - Messages
      summary: Get a conversation item
      description: Gets a conversation item for a given id. Modeled path (operation confirmed).
      responses:
        '200':
          description: The conversation item.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationItem'
    delete:
      operationId: deleteConversationItem
      tags:
        - Messages
      summary: Delete a conversation item
      description: Deletes a conversation item. Modeled.
      responses:
        '204':
          description: Item deleted.
  /internalendpoints:
    get:
      operationId: internalEndpoints
      tags:
        - Messages
      summary: List internal endpoints
      description: Lists all internal endpoints (phone lines / addresses) an organization can communicate with. Confirmed path.
      responses:
        '200':
          description: Internal endpoints.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Endpoint'
  /internalendpoints/{endpointId}/messages:
    parameters:
      - name: endpointId
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: postMessageFromEndpoint
      tags:
        - Messages
      summary: Send a message from an internal endpoint
      description: Sends a message (e.g. SMS/secure) from a given internal endpoint. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageCreate'
      responses:
        '200':
          description: The created conversation item.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationItem'
  /proxy-calls:
    post:
      operationId: postCreateProxyCall
      tags:
        - Messages
      summary: Create a proxy call
      description: Creates a proxy (bridge) call between a member and a contact. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: The created proxy call.
  /media:
    post:
      operationId: uploadMedia
      tags:
        - Messages
      summary: Upload media
      description: Uploads media for use as a message attachment. Modeled.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
      responses:
        '200':
          description: The uploaded media reference.
  /scheduled-messages:
    get:
      operationId: listScheduledMessages
      tags:
        - Messages
      summary: List scheduled messages
      description: Lists scheduled messages for the organization. Modeled.
      responses:
        '200':
          description: Scheduled messages.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
  /conversations/{conversationId}/scheduled-messages:
    parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: listConversationScheduledMessages
      tags:
        - Messages
      summary: List a conversation's scheduled messages
      description: Lists scheduled messages for a conversation. Modeled.
      responses:
        '200':
          description: Scheduled messages for the conversation.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
    post:
      operationId: scheduleConversationMessage
      tags:
        - Messages
      summary: Schedule a message in a conversation
      description: Schedules a message to be sent in a conversation at a future time. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageCreate'
      responses:
        '200':
          description: The scheduled message.
  /scheduled-messages/{scheduledMessageId}:
    parameters:
      - name: scheduledMessageId
        in: path
        required: true
        schema:
          type: string
    delete:
      operationId: deleteScheduledMessage
      tags:
        - Messages
      summary: Delete a scheduled message
      description: Deletes a scheduled message before it is sent. Modeled.
      responses:
        '204':
          description: Scheduled message deleted.
  /saved-messages:
    get:
      operationId: listSavedMessages
      tags:
        - Messages
      summary: List saved messages
      description: Lists saved (canned/template) messages for the organization. Modeled.
      responses:
        '200':
          description: Saved messages.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
  /webhooks/endpoints:
    get:
      operationId: listWebhookEndpoints
      tags:
        - Webhooks
      summary: List webhook endpoints
      description: Lists the endpoints an organization has registered for webhooks (secret keys are not returned). Confirmed path.
      responses:
        '200':
          description: Webhook endpoints.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/WebhookEndpoint'
    post:
      operationId: createWebhookEndpoint
      tags:
        - Webhooks
      summary: Create a webhook endpoint
      description: >-
        Registers a new HTTPS webhook endpoint with a name and destination URL.
        The response includes a signing secret used to verify event signatures;
        the endpoint must respond 2XX within 5 seconds. Confirmed path.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEndpointCreate'
      responses:
        '200':
          description: The created webhook endpoint, including its signing secret.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
        '403':
          $ref: '#/components/responses/Forbidden'
  /webhooks/endpoints/{endpointId}:
    parameters:
      - name: endpointId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: webhookEndpoint
      tags:
        - Webhooks
      summary: Get a webhook endpoint
      description: Retrieves a webhook endpoint by ID. Modeled.
      responses:
        '200':
          description: The webhook endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
    delete:
      operationId: deleteWebhookEndpoint
      tags:
        - Webhooks
      summary: Delete a webhook endpoint
      description: Deletes a webhook endpoint. Modeled.
      responses:
        '204':
          description: Webhook endpoint deleted.
  /webhooks/endpoints/{endpointId}/events:
    parameters:
      - name: endpointId
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: listWebhookEndpointEvents
      tags:
        - Webhooks
      summary: List a webhook endpoint's events
      description: Lists the events delivered (or attempted) for a webhook endpoint. Modeled.
      responses:
        '200':
          description: Webhook endpoint events.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/WebhookEvent'
  /webhooks/endpoints/{endpointId}/paused:
    parameters:
      - name: endpointId
        in: path
        required: true
        schema:
          type: string
    put:
      operationId: modifyWebhookEndpointPaused
      tags:
        - Webhooks
      summary: Pause or resume a webhook endpoint
      description: Pauses or resumes dispatch of events to a webhook endpoint. Modeled.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                paused:
                  type: boolean
      responses:
        '200':
          description: The updated webhook endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Organization API token generated in Settings after Spruce Support enables API access.
  responses:
    Forbidden:
      description: Missing, incorrect, or disabled API token.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
  schemas:
    Contact:
      type: object
      properties:
        id:
          type: string
        displayName:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        phones:
          type: array
          items:
            type: object
            properties:
              value:
                type: string
              label:
                type: string
        emails:
          type: array
          items:
            type: object
            properties:
              value:
                type: string
              label:
                type: string
        tags:
          type: array
          items:
            type: string
    IntegrationLink:
      type: object
      properties:
        id:
          type: string
        externalId:
          type: string
        system:
          type: string
    Tag:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        color:
          type: string
    Conversation:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        createdAt:
          type: string
          format: date-time
        lastMessageAt:
          type: string
          format: date-time
        tags:
          type: array
          items:
            type: string
    ConversationItem:
      type: object
      properties:
        id:
          type: string
        conversationId:
          type: string
        type:
          type: string
          description: Item type, e.g. message, call, fax, or secure conversation event.
        body:
          type: string
        createdAt:
          type: string
          format: date-time
    MessageCreate:
      type: object
      properties:
        body:
          type: string
        mediaIds:
          type: array
          items:
            type: string
    Endpoint:
      type: object
      properties:
        id:
          type: string
        displayName:
          type: string
        type:
          type: string
        value:
          type: string
    WebhookEndpointCreate:
      type: object
      required:
        - name
        - url
      properties:
        name:
          type: string
        url:
          type: string
          format: uri
        events:
          type: array
          items:
            type: string
    WebhookEndpoint:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        url:
          type: string
          format: uri
        secret:
          type: string
          description: Signing secret, returned only on creation.
        paused:
          type: boolean
        events:
          type: array
          items:
            type: string
    WebhookEvent:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
          description: e.g. contact.created, conversation.updated, conversationItem.created.
        createdAt:
          type: string
          format: date-time
        deliveryStatus:
          type: string