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

# Submit a referral

> **Permission:** `referrals:write`

Submit a referral to the clinic for its staff to confirm.

The referral is held for review and answers 202 Accepted with a `Location` header pointing at the submission; it is not on the clinic's referral list until staff confirm it (unless the clinic has chosen to accept such submissions automatically). Confirming adds it as `received` - it does not accept the referral or book anything; the clinic decides that next, and a sender cannot. The `Idempotency-Key` header is REQUIRED - a retry with the same key returns the original submission, never a second one. This is a clinical referral, not the clinic referral programme. JSON only: a FHIR ServiceRequest body is not accepted.



## OpenAPI

````yaml /openapi/ehr-api.v1.yaml post /v1/clinics/{clinic_id}/referrals
openapi: 3.1.0
info:
  title: ClinikEHR API
  version: 1.0.0
  description: >-
    Server-to-server REST API for a clinic's own data, reached with a key the
    clinic (or a developer workspace) creates in the developer portal.


    Authenticate every request with `Authorization: Bearer <key>`. Test keys
    reach only your workspace's own synthetic sandbox; live keys reach the
    clinic that created them. Lists wrap their rows as `{ data, has_more,
    next_cursor }`; single resources are returned directly. Errors are
    `application/problem+json` (RFC 9457) with a stable `code`.


    Write requests accept an `Idempotency-Key` header so a retry never repeats a
    change. See the guides for authentication, permissions, pagination, rate
    limits and retries.
servers:
  - url: https://api.clinikehr.com
security:
  - ApiKey: []
paths:
  /v1/clinics/{clinic_id}/referrals:
    post:
      tags:
        - Referrals
      summary: Submit a referral
      description: >-
        **Permission:** `referrals:write`


        Submit a referral to the clinic for its staff to confirm.


        The referral is held for review and answers 202 Accepted with a
        `Location` header pointing at the submission; it is not on the clinic's
        referral list until staff confirm it (unless the clinic has chosen to
        accept such submissions automatically). Confirming adds it as `received`
        - it does not accept the referral or book anything; the clinic decides
        that next, and a sender cannot. The `Idempotency-Key` header is REQUIRED
        - a retry with the same key returns the original submission, never a
        second one. This is a clinical referral, not the clinic referral
        programme. JSON only: a FHIR ServiceRequest body is not accepted.
      operationId: createReferral
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyRequired'
        - name: clinic_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReferralCreate'
      responses:
        '202':
          description: >-
            Accepted - waiting for clinic staff. If the clinic has chosen to
            accept this kind of item from your key or connection without review,
            the body already shows `review_status: confirmed` and
            `accepted_automatically: true`; read `review_status`, not the status
            code.
          headers:
            Location:
              description: The submission, `.../submissions/{submission_id}`.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/Submission'
                  idempotent_replay:
                    type: boolean
                    description: >-
                      Present and true when this Idempotency-Key was already
                      used and the original submission is returned.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      security:
        - ApiKey: []
components:
  parameters:
    IdempotencyKeyRequired:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        A unique value you choose for this request, such as a UUID. Sending the
        same key again returns the first answer instead of doing the work twice,
        so a timed-out request is safe to retry. Reusing a key for a different
        request is refused with `409 idempotency_key_conflict`, and retrying
        while the first request is still running with `409
        idempotency_key_reused`. See Retries and idempotency.
      schema:
        type: string
        minLength: 1
  schemas:
    ReferralCreate:
      type: object
      additionalProperties: false
      description: >-
        A referral to this clinic, submitted for clinic staff to confirm. It
        does not appear on the clinic's referral list until they do (unless the
        clinic has chosen to accept such submissions automatically); either way
        it lands as `received` and the clinic decides whether to accept, decline
        or schedule it. This is a clinical referral, not the clinic referral
        programme. Send `code` on `service` or `reason` only with its `system`.
        `client_reference` (your own id, up to 200 characters) makes a second
        submission of the same record with different content a
        `client_reference_conflict`.
      required:
        - patient_id
        - service
        - reason
      properties:
        patient_id:
          type: string
          format: uuid
        service:
          type: object
          additionalProperties: false
          required:
            - text
          properties:
            text:
              type: string
              minLength: 1
              maxLength: 300
            code:
              type: object
              additionalProperties: false
              required:
                - system
                - code
              properties:
                system:
                  type: string
                  enum:
                    - local
                    - snomed-ct
                code:
                  type: string
                  minLength: 1
                  maxLength: 64
                  description: A `snomed-ct` code is 6 to 18 digits.
        reason:
          type: object
          additionalProperties: false
          required:
            - text
          properties:
            text:
              type: string
              minLength: 1
              maxLength: 1000
            code:
              type: object
              additionalProperties: false
              required:
                - system
                - code
              properties:
                system:
                  type: string
                  enum:
                    - local
                    - icd-10-cm
                    - icd-10
                    - snomed-ct
                code:
                  type: string
                  minLength: 1
                  maxLength: 64
                  description: >-
                    An `icd-10-cm` or `icd-10` code must be a recognised
                    diagnosis code; a `snomed-ct` code is 6 to 18 digits.
        priority:
          type: string
          enum:
            - routine
            - urgent
            - asap
            - stat
          default: routine
        needed_by:
          type: string
          format: date
          description: Not earlier than yesterday.
        clinical_summary:
          type: string
          minLength: 1
          maxLength: 8000
        requester:
          type: object
          additionalProperties: false
          minProperties: 1
          properties:
            name:
              type: string
              minLength: 1
              maxLength: 200
            organization:
              type: string
              minLength: 1
              maxLength: 200
            npi:
              type: string
              pattern: ^[0-9]{10}$
        client_reference:
          type: string
          maxLength: 200
        origin_assistant_name:
          type: string
          maxLength: 200
    Submission:
      type: object
      description: >-
        What the clinic's review queue holds for something this key sent: one
        outside record waiting for, or already past, a clinician's decision.
      required:
        - submission_id
        - patient_id
        - resource_type
        - action
        - review_status
      properties:
        submission_id:
          type: string
          format: uuid
        patient_id:
          type: string
          format: uuid
        resource_type:
          type: string
          enum:
            - condition
            - allergy
            - medication_statement
            - referral
          description: The kind of record.
        action:
          type: string
          enum:
            - create
            - update
            - retract
        target_id:
          type:
            - string
            - 'null'
          format: uuid
          description: The existing record an update or retract is about.
        review_status:
          type: string
          enum:
            - pending
            - confirmed
            - rejected
            - withdrawn
        accepted_automatically:
          type: boolean
          description: >-
            True when the clinic has chosen to accept this kind of item from
            this key or connection without review; the item is then already on
            the chart and `review_status` is `confirmed`. False for everything a
            clinician decides, and while it is pending.
        source:
          type: string
          enum:
            - api
        submitted_at:
          type:
            - string
            - 'null'
          format: date-time
        decided_at:
          type:
            - string
            - 'null'
          format: date-time
        decision_reason:
          type:
            - string
            - 'null'
          description: Present only when rejected.
        result_record_id:
          type:
            - string
            - 'null'
          format: uuid
          description: The record this became, once confirmed.
        client_reference:
          type:
            - string
            - 'null'
        origin_assistant_name:
          type:
            - string
            - 'null'
        payload:
          type: object
          description: What was submitted.
    Problem:
      type: object
      description: RFC 9457 application/problem+json.
      required:
        - type
        - title
        - status
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        code:
          type: string
        request_id:
          type: string
        errors:
          type: array
          items:
            type: object
            required:
              - pointer
              - message
            properties:
              pointer:
                type: string
              message:
                type: string
  responses:
    BadRequest:
      description: >-
        The request failed validation (unknown query parameter, limit out of
        range, malformed body).
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: >-
        Missing, malformed, unknown, revoked or expired key, or the wrong
        secret.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Forbidden:
      description: >-
        The key or connection lacks the required scope, the plan does not
        include this resource, the request came from an address this key's IP
        allow-list does not permit, a TEST-environment workspace key asked for a
        clinic_id other than its own workspace's sandbox (`sandbox_only`), or a
        LIVE workspace key asked for a real clinic while its workspace's
        verification has lapsed (`not_verified`) — the response never names
        which addresses ARE allowed, nor which clinic actually is the sandbox.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotFound:
      description: The record is absent, or out of the key's scope — one message for both.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Conflict:
      description: >-
        The request is well-formed but conflicts with the CURRENT STATE of the
        record — a double-booked slot (`slot_taken`), a clinician's calendar
        blocked at that time (`out_of_office`), nobody eligible free
        (`no_provider_available`), an item that still has stock
        (`item_has_stock`), a ledger movement that cannot be covered
        (`insufficient_stock`, `expired_stock_not_transferable`), a note already
        signed or clinician-touched (`note_not_editable`), an Idempotency-Key
        already used for a different request or still in flight
        (`idempotency_key_conflict`, `idempotency_key_reused`), or an
        external-stock batch rejected as structurally invalid or a suspicious
        shrink versus the clinic's last accepted batch (`batch_rejected`), or an
        outside record that conflicts with what was already submitted or
        decided: the same `client_reference` sent again with different content
        (`client_reference_conflict`), or a submission a clinician has already
        decided (`submission_not_pending`), or an insurance write that conflicts
        with the clinic's setup or the coverage's state: the patient already has
        a coverage for that payer (`coverage_exists`, the existing coverage's id
        is in `detail` when the caller can see that patient), a payer the clinic
        has not enabled in Settings → Insurance (`payer_not_enabled`), or
        `coverage_active: true` sent through the API
        (`activation_requires_staff` — only clinic staff activate a coverage),
        or a change to an outside care provider the clinic added rather than an
        app (`care_provider_clinic_managed` — only the clinic can change or
        remove it).
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    TooManyRequests:
      description: Rate limited. See the Retry-After header.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      bearerFormat: ehr_live_<keyId>_<secret> or ehr_test_<keyId>_<secret>

````

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