> ## 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.

# Order for your customer, charged to your card

> Place an order that ships to your customer's address.

**Wholesale** (no `price_cents`): VitaRelay charges **your default card on file**, or the Accept.js card you
send, at the wholesale price (always read from our catalog) and fulfills and ships it.

**Your own prices**: set `price_cents` on any line above wholesale. The customer pays your prices through
Accept.js (send `opaque_data` and `billing` now, or pay later with `POST /wholesale/orders/{id}/pay`), and the
difference is yours (`your_markup_cents`). Your card on file is never charged for these orders.

No patient, customer record or invite is created. You collect from your customer yourself. The buyer must
confirm they are 21+, will use the products for research only, and accept the terms (`attestation`, all three
`true`). Send your own `external_order_id` to make retries safe. A declined card returns the order with
`payment.status: failed`; nothing ships until it is paid. Needs `orders:write`.




## OpenAPI

````yaml /partner-api/openapi.yaml post /wholesale/orders
openapi: 3.1.0
info:
  title: VitaRelay Partner API
  version: 1.0.0
  description: >-
    The Partner API is for rep organizations (a Vita Rep, or a dual Rep + Clinic
    account) that recruit clinics and other reps. Create the invite you would
    otherwise send from the "Refer a Tele Clinic" form, get the signup link
    back, track whether it was accepted, and revoke it.
servers:
  - url: https://vitarelay.com/api/public/partner/v1
security:
  - bearerAuth: []
tags:
  - name: Wholesale
    description: >-
      Order research-use products for your own customers at VitaRelay's
      wholesale price, charged to your card on file. You show your own prices
      and collect from your customer yourself. Rep accounts only.
  - name: Store
    description: >-
      Sell research-use products to your own customers from your own landing
      page, using VitaRelay for fulfillment and payment processing. Customers
      are not patients: no patient, intake or prescription is created. Rep
      accounts only. Needs `store:read` / `store:write`.
  - name: Invites
    description: Clinic and rep invites sent by your organization.
paths:
  /wholesale/orders:
    post:
      tags:
        - Wholesale
      summary: Order for your customer, charged to your card
      description: >
        Place an order that ships to your customer's address.


        **Wholesale** (no `price_cents`): VitaRelay charges **your default card
        on file**, or the Accept.js card you

        send, at the wholesale price (always read from our catalog) and fulfills
        and ships it.


        **Your own prices**: set `price_cents` on any line above wholesale. The
        customer pays your prices through

        Accept.js (send `opaque_data` and `billing` now, or pay later with `POST
        /wholesale/orders/{id}/pay`), and the

        difference is yours (`your_markup_cents`). Your card on file is never
        charged for these orders.


        No patient, customer record or invite is created. You collect from your
        customer yourself. The buyer must

        confirm they are 21+, will use the products for research only, and
        accept the terms (`attestation`, all three

        `true`). Send your own `external_order_id` to make retries safe. A
        declined card returns the order with

        `payment.status: failed`; nothing ships until it is paid. Needs
        `orders:write`.
      operationId: createWholesaleOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWholesaleOrder'
      responses:
        '200':
          description: A retry of an order already created with this `external_order_id`.
        '201':
          description: The order and the payment result.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/WholesaleOrder'
                  payment:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - paid
                          - failed
                          - pending
                      message:
                        type: string
                  checkout:
                    type: object
                    nullable: true
                    description: >-
                      Accept.js keys, present when the order is `pending` and
                      waits for `POST /wholesale/orders/{id}/pay`.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: '`no_payment_method`: no card on file.'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/DuplicateRequest'
        '422':
          $ref: '#/components/responses/ValidationFailed'
components:
  schemas:
    CreateWholesaleOrder:
      type: object
      additionalProperties: false
      required:
        - items
        - ship_to
        - attestation
      properties:
        items:
          type: array
          items:
            type: object
            required:
              - product_id
              - quantity
            properties:
              product_id:
                type: string
                format: uuid
              quantity:
                type: integer
                minimum: 1
                maximum: 999
              price_cents:
                type: integer
                description: >-
                  Your price per unit to your customer, in cents. Omit for the
                  wholesale price. Never below wholesale (`422
                  price_below_cost`). Anything above wholesale is yours, and the
                  order is paid by your customer's card (Accept.js), not your
                  card on file.
        ship_to:
          type: object
          required:
            - first_name
            - last_name
            - phone
            - line1
            - city
            - state
            - postal_code
          properties:
            first_name:
              type: string
            last_name:
              type: string
            email:
              type: string
            phone:
              type: string
            line1:
              type: string
            line2:
              type: string
            city:
              type: string
            state:
              type: string
            postal_code:
              type: string
            country:
              type: string
              default: US
        shipping_method:
          type: string
          enum:
            - ground_rnd
            - overnight
          default: ground_rnd
        attestation:
          type: object
          required:
            - age_confirmed
            - research_use_only
            - terms_accepted
          properties:
            age_confirmed:
              type: boolean
            research_use_only:
              type: boolean
            terms_accepted:
              type: boolean
        external_order_id:
          type: string
          maxLength: 128
          description: Your own id for the order. Makes the call safe to retry.
        opaque_data:
          type: object
          description: >-
            Optional Accept.js token. Send with `billing` to charge that card
            instead of your card on file.
          required:
            - dataDescriptor
            - dataValue
          properties:
            dataDescriptor:
              type: string
            dataValue:
              type: string
        billing:
          type: object
          description: The card's billing details. Required with `opaque_data`.
          required:
            - first_name
            - last_name
            - address
            - city
            - state
            - zip
          properties:
            first_name:
              type: string
            last_name:
              type: string
            address:
              type: string
            city:
              type: string
            state:
              type: string
            zip:
              type: string
            country:
              type: string
            email:
              type: string
            phone:
              type: string
    WholesaleOrder:
      type: object
      properties:
        id:
          type: string
          format: uuid
        order_number:
          type: string
          nullable: true
        status:
          type: string
        payment_status:
          type: string
        external_order_id:
          type: string
          nullable: true
        subtotal_cents:
          type: integer
          nullable: true
        shipping_cents:
          type: integer
          nullable: true
        tax_cents:
          type: integer
          nullable: true
        total_cents:
          type: integer
          nullable: true
        currency:
          type: string
        your_markup_cents:
          type: integer
          description: >-
            What you earn on this order (your prices minus wholesale), before
            VitaRelay's platform fee.
        ship_to:
          type: object
          properties:
            first_name:
              type: string
              nullable: true
            last_name:
              type: string
              nullable: true
            email:
              type: string
              nullable: true
            phone:
              type: string
              nullable: true
            address:
              type: object
              nullable: true
        items:
          type: array
          items:
            type: object
            properties:
              product_id:
                type: string
                nullable: true
              name:
                type: string
              quantity:
                type: integer
              unit_price_cents:
                type: integer
        tracking:
          type: object
          properties:
            number:
              type: string
              nullable: true
            carrier:
              type: string
              nullable: true
            url:
              type: string
              nullable: true
            status:
              type: string
              nullable: true
            shipped_at:
              type: string
              nullable: true
            delivered_at:
              type: string
              nullable: true
        created_at:
          type: string
          format: date-time
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    Unauthorized:
      description: Missing, invalid or revoked API key (`unauthorized`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        `insufficient_scope` (the key lacks the scope) or `not_available` (your
        organization is not a rep or dual Rep + Clinic account).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    DuplicateRequest:
      description: >-
        A conflicting request with the same external id is in flight
        (`duplicate_request`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ValidationFailed:
      description: >-
        `validation_failed` — a field is missing or invalid; the message says
        which.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        VitaRelay API key (`vr_live_...` or `vr_test_...`) with the `invites:*`
        scopes.

````

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