openapi: 3.0.3 info: title: Spruce Public Contacts 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 ); 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. 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. components: schemas: 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 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 responses: Forbidden: description: Missing, incorrect, or disabled API token. content: application/json: schema: type: object properties: error: type: string securitySchemes: bearerAuth: type: http scheme: bearer description: Organization API token generated in Settings after Spruce Support enables API access.