> ## Documentation Index
> Fetch the complete documentation index at: https://api.vitarelay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Update the CRM facts

> Scope `customers:write`. Updates only `consent`, `attribution` and `booking_ref`; the rest is set with `POST /customers`.



## OpenAPI

````yaml /pharmacy-api/customers-openapi.yaml patch /customers/{id}
openapi: 3.1.0
info:
  title: Pharmacy Customers API
  version: 1.0.0
  description: >
    Connect your CRM (GoHighLevel and similar) to your pharmacy's customers:
    send a provider when your CRM marks it as converted,

    get webhooks when its orders ship or deliver and when it needs a reorder,
    has lapsed or (for a partner rep) has gone

    dormant, and export your providers.


    **Authentication.** `Authorization: Bearer vr_live_...`. A key belongs to
    your pharmacy and carries `customers:read`

    and/or `customers:write` (create it under **Settings → API keys**). Test
    keys (`vr_test_...`) can read; their writes are

    acknowledged with `sandbox: true` and change nothing. Your pharmacy must
    have customers enabled.


    **Ids.** A customer's `id` is its VitaRelay organization id. `external_id`
    is your CRM's own id for the provider (the

    GoHighLevel contact id); sending the same `external_id` again updates the
    provider and never creates a second one.


    **Webhooks.** Subscribe with `POST /customers/webhooks`. Each request is
    signed:

    `X-Webhook-Signature: sha256=<hex HMAC-SHA256 of the exact request body,
    keyed with your endpoint secret>`, with

    `X-Webhook-Event`, `X-Webhook-Delivery` and `X-Webhook-Timestamp` headers.
    Delivery is at least once with exponential

    backoff for about a day; deduplicate on `X-Webhook-Delivery`. Events:
    `order.shipped`, `order.delivered`,

    `order.cancelled`, `customer.reorder_due`, `customer.lapsed`,
    `partner.dormant`. Use `POST /customers/webhooks/ping`

    to send yourself a test event.


    **Lifecycle windows** are days since a customer's last order (reorder due
    30, lapsed 60, partner dormant 90 by default;

    change them with `PUT /customers/settings`). Each event fires once per last
    order. Connecting a CRM does not send events

    for customers that are already past a window: read their `lifecycle_status`
    from `GET /customers`.
servers:
  - url: https://vitarelay.com/api/public/v1
    description: Production
security:
  - bearer: []
paths:
  /customers/{id}:
    patch:
      summary: Update the CRM facts
      description: >-
        Scope `customers:write`. Updates only `consent`, `attribution` and
        `booking_ref`; the rest is set with `POST /customers`.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                consent:
                  $ref: '#/components/schemas/Consent'
                attribution:
                  type: object
                  additionalProperties:
                    type: string
                booking_ref:
                  type: string
      responses:
        '200':
          description: The updated provider
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Customer'
        '404':
          description: Not found (`not_found`)
components:
  schemas:
    Consent:
      type: object
      properties:
        sms:
          $ref: '#/components/schemas/ConsentItem'
        email:
          $ref: '#/components/schemas/ConsentItem'
    Customer:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type: string
          nullable: true
        name:
          type: string
        kind:
          type: string
          enum:
            - practice
            - tele_clinic
        status:
          type: string
          enum:
            - invited
            - active
            - archived
        signup:
          type: object
          properties:
            status:
              type: string
              enum:
                - pending
                - accepted
            invite_emailed:
              type: boolean
        contact:
          type: object
        address:
          type: object
        prescribers:
          type: integer
        consent:
          type: object
        attribution:
          type: object
          nullable: true
        booking_ref:
          type: string
          nullable: true
        orders:
          type: object
          description: >-
            count, last_order_id, last_order_number, last_order_at,
            last_order_total_cents
        days_since_last_order:
          type: integer
          nullable: true
        lifecycle_status:
          type: string
          enum:
            - never_ordered
            - active
            - reorder_due
            - lapsed
        created_at:
          type: string
          format: date-time
    ConsentItem:
      type: object
      required:
        - granted
      properties:
        granted:
          type: boolean
        at:
          type: string
          format: date-time
          description: When consent was given. Defaults to now.
        source:
          type: string
  securitySchemes:
    bearer:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.