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

# Submit a medical referral

> Send us a patient and their physician order; Scan collects safety answers and books

For who owns checkout, scheduling, and the member experience, start with
[Is this API right for you?](/guides/build-an-imaging-experience).

Before using this guide you need a sandbox and an access token. Request keys from
[Get API keys](https://admin.staging.scan.com/partner/api_access). How to send
`Authorization` is in [Authentication](/authentication). Use synthetic data only
on the initial sandbox. Listing imaging centers, searching or creating practices or
law firms, and submitting an order-form-only referral may be off until Scan enables
them for your account.

**What you will build.** One referral with the patient on file and the physician
order attached. You do not send safety answers or preferred times in this flow.

**What Scan does after.** We reach out for safety screening and scheduling, confirm
the appointment with the patient, and file the radiology report back to you.

If you already have safety answers and the times that work, use
[Submit for scheduling](/guides/submit-for-scheduling) instead. Workers
compensation payers should use
[Workers' compensation and payers](/guides/lines-of-business/workers-comp-and-payers) for
`payment_type`, `order_type`, payer, and claim fields.

## Terms you will see

* **Referral** — the request for imaging. Holds one or more visits.
* **Visit** — one trip to an imaging center, carrying the orders for that trip (modality, body part).
* **Order form** — the physician's signed order PDF, sent as `order_form`. There is no separate medical-referral object.

Safety questions on this referral belong to
[Submit medical questions](/guides/submit-medical-questions). Preferred center and
times belong to [Submit preferred times](/guides/submit-preferred-times).

***

## 1. Tell us who the patient is

Register the person being scanned so the rest of the flow can refer to them.
Patients are scoped to your group, so you only ever see your own. If you would
rather send everything at once, you can nest these same fields as
`referral.patient` in the next step instead.

**POST `/api/v2/patients`**

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl https://api.staging.scan.com/api/v2/patients \
    -H "Authorization: Bearer $SCAN_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "patient": {
        "first_name": "John",
        "last_name": "Doe",
        "phone": "5551234567",
        "patient_profile_attributes": {
          "date_of_birth": "1988-05-21",
          "gender": "male",
          "state": "GA",
          "zip_code": "30301"
        }
      }
    }'
  ```

  ```ruby Ruby theme={"dark"}
  require "net/http"
  require "json"
  require "uri"

  uri = URI("https://api.staging.scan.com/api/v2/patients")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(uri)
  request["Authorization"] = "Bearer #{ENV.fetch("SCAN_API_TOKEN")}"
  request["Content-Type"] = "application/json"
  request.body = {
    patient: {
      first_name: "John",
      last_name: "Doe",
      phone: "5551234567",
      patient_profile_attributes: {
        date_of_birth: "1988-05-21",
        gender: "male",
        state: "GA",
        zip_code: "30301"
      }
    }
  }.to_json

  response = http.request(request)
  puts response.body
  ```

  ```python Python theme={"dark"}
  import os
  import requests

  response = requests.post(
      "https://api.staging.scan.com/api/v2/patients",
      headers={"Authorization": f"Bearer {os.environ['SCAN_API_TOKEN']}"},
      json={
          "patient": {
              "first_name": "John",
              "last_name": "Doe",
              "phone": "5551234567",
              "patient_profile_attributes": {
                  "date_of_birth": "1988-05-21",
                  "gender": "male",
                  "state": "GA",
                  "zip_code": "30301",
              },
          }
      },
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={"dark"}
  const response = await fetch("https://api.staging.scan.com/api/v2/patients", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SCAN_API_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      patient: {
        first_name: "John",
        last_name: "Doe",
        phone: "5551234567",
        patient_profile_attributes: {
          date_of_birth: "1988-05-21",
          gender: "male",
          state: "GA",
          zip_code: "30301",
        },
      },
    }),
  });

  const patient = await response.json();
  ```

  ```php PHP theme={"dark"}
  $ch = curl_init("https://api.staging.scan.com/api/v2/patients");
  curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
      "Authorization: Bearer " . getenv("SCAN_API_TOKEN"),
      "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
      "patient" => [
        "first_name" => "John",
        "last_name" => "Doe",
        "phone" => "5551234567",
        "patient_profile_attributes" => [
          "date_of_birth" => "1988-05-21",
          "gender" => "male",
          "state" => "GA",
          "zip_code" => "30301",
        ],
      ],
    ]),
    CURLOPT_RETURNTRANSFER => true,
  ]);

  $response = curl_exec($ch);
  ```

  ```go Go theme={"dark"}
  package main

  import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "os"
  )

  func main() {
    body, _ := json.Marshal(map[string]any{
      "patient": map[string]any{
        "first_name": "John",
        "last_name":  "Doe",
        "phone":      "5551234567",
        "patient_profile_attributes": map[string]any{
          "date_of_birth": "1988-05-21",
          "gender":        "male",
          "state":         "GA",
          "zip_code":      "30301",
        },
      },
    })
    req, _ := http.NewRequest(
      http.MethodPost,
      "https://api.staging.scan.com/api/v2/patients",
      bytes.NewBuffer(body),
    )
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SCAN_API_TOKEN"))
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    result, _ := io.ReadAll(resp.Body)
    _ = result
  }
  ```
</CodeGroup>

**What you get back.** The patient `id`. Hold onto it as `patient_id` for the next
step.

Full payload: [Creates a patient](/api-reference/patients/creates-a-patient).

***

## 2. Send the referral with the physician order

This is the step that creates the imaging request. It carries three things: the
patient, the signed physician order, and what is being scanned.

The order is the PDF the referring physician signed, sent as `order_form` in a
base64 data URL shaped like
`data:<content_type>;name=<filename>;base64,<payload>`.

What is being scanned lives in `visits`, and each visit carries its orders. Look
up the exact procedure first with
[CPT codes](/api-reference/cpt-codes/returns-cpt-code-mappings), then send its
`id` as `cpt_code_id`. We infer modality, body part, contrast, laterality,
modifier, and number of views from that mapping. Diagnosis IDs come from
[ICD-10 codes](/api-reference/icd-10-codes/returns-a-list-of-icd-10-codes).
You can still send the legacy
[modality](/api-reference/modalities/returns-a-list-of-modalities) and
[body-part](/api-reference/body-parts/returns-a-list-of-body-parts) fields
instead.

**POST `/api/v2/referrals`**

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl https://api.staging.scan.com/api/v2/referrals \
    -H "Authorization: Bearer $SCAN_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "referral": {
        "order_form": "data:application/pdf;name=order.pdf;base64,JVBERi0xLjQ=",
        "payment_type": "pi",
        "order_type": "lien",
        "injury_type": "motor_vehicle_accident",
        "incident_date": "2026-04-01",
        "physician_notes": "Persistent neck pain",
        "referred_by": "Dr. Jane Smith",
        "state_brand_abbreviation": "GA",
        "patient_id": "11111111-1111-1111-1111-111111111111",
        "visits": [
          {
            "orders": [
              {
                "cpt_code_id": "11111111-1111-1111-1111-111111111113"
              }
            ]
          }
        ]
      }
    }'
  ```

  ```ruby Ruby theme={"dark"}
  require "net/http"
  require "json"
  require "uri"

  uri = URI("https://api.staging.scan.com/api/v2/referrals")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(uri)
  request["Authorization"] = "Bearer #{ENV.fetch("SCAN_API_TOKEN")}"
  request["Content-Type"] = "application/json"
  request.body = {
    referral: {
      order_form: "data:application/pdf;name=order.pdf;base64,JVBERi0xLjQ=",
      payment_type: "pi",
      order_type: "lien",
      injury_type: "motor_vehicle_accident",
      incident_date: "2026-04-01",
      physician_notes: "Persistent neck pain",
      referred_by: "Dr. Jane Smith",
      state_brand_abbreviation: "GA",
      patient_id: "11111111-1111-1111-1111-111111111111",
      visits: [
        {
          orders: [
            {
              cpt_code_id: "11111111-1111-1111-1111-111111111113"
            }
          ]
        }
      ]
    }
  }.to_json

  response = http.request(request)
  puts response.body
  ```

  ```python Python theme={"dark"}
  import os
  import requests

  response = requests.post(
      "https://api.staging.scan.com/api/v2/referrals",
      headers={"Authorization": f"Bearer {os.environ['SCAN_API_TOKEN']}"},
      json={
          "referral": {
              "order_form": "data:application/pdf;name=order.pdf;base64,JVBERi0xLjQ=",
              "payment_type": "pi",
              "order_type": "lien",
              "injury_type": "motor_vehicle_accident",
              "incident_date": "2026-04-01",
              "physician_notes": "Persistent neck pain",
              "referred_by": "Dr. Jane Smith",
              "state_brand_abbreviation": "GA",
              "patient_id": "11111111-1111-1111-1111-111111111111",
              "visits": [
                  {
                      "orders": [
                          {
                              "cpt_code_id": "11111111-1111-1111-1111-111111111113",
                          }
                      ],
                  }
              ],
          }
      },
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={"dark"}
  const response = await fetch("https://api.staging.scan.com/api/v2/referrals", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SCAN_API_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      referral: {
        order_form: "data:application/pdf;name=order.pdf;base64,JVBERi0xLjQ=",
        payment_type: "pi",
        order_type: "lien",
        injury_type: "motor_vehicle_accident",
        incident_date: "2026-04-01",
        physician_notes: "Persistent neck pain",
        referred_by: "Dr. Jane Smith",
        state_brand_abbreviation: "GA",
        patient_id: "11111111-1111-1111-1111-111111111111",
        visits: [
          {
            orders: [
              {
                cpt_code_id: "11111111-1111-1111-1111-111111111113",
              },
            ],
          },
        ],
      },
    }),
  });

  const referral = await response.json();
  ```

  ```php PHP theme={"dark"}
  $ch = curl_init("https://api.staging.scan.com/api/v2/referrals");
  curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
      "Authorization: Bearer " . getenv("SCAN_API_TOKEN"),
      "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
      "referral" => [
        "order_form" => "data:application/pdf;name=order.pdf;base64,JVBERi0xLjQ=",
        "payment_type" => "pi",
        "order_type" => "lien",
        "injury_type" => "motor_vehicle_accident",
        "incident_date" => "2026-04-01",
        "physician_notes" => "Persistent neck pain",
        "referred_by" => "Dr. Jane Smith",
        "state_brand_abbreviation" => "GA",
        "patient_id" => "11111111-1111-1111-1111-111111111111",
        "visits" => [
          [
            "orders" => [
              [
                "cpt_code_id" => "11111111-1111-1111-1111-111111111113",
              ],
            ],
          ],
        ],
      ],
    ]),
    CURLOPT_RETURNTRANSFER => true,
  ]);

  $response = curl_exec($ch);
  ```

  ```go Go theme={"dark"}
  package main

  import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "os"
  )

  func main() {
    body, _ := json.Marshal(map[string]any{
      "referral": map[string]any{
        "order_form":                 "data:application/pdf;name=order.pdf;base64,JVBERi0xLjQ=",
        "payment_type":               "pi",
        "order_type":                 "lien",
        "injury_type":                "motor_vehicle_accident",
        "incident_date":              "2026-04-01",
        "physician_notes":            "Persistent neck pain",
        "referred_by":                "Dr. Jane Smith",
        "state_brand_abbreviation":   "GA",
        "patient_id":                 "11111111-1111-1111-1111-111111111111",
        "visits": []map[string]any{
          {
            "orders": []map[string]any{
              {
                "cpt_code_id": "11111111-1111-1111-1111-111111111113",
              },
            },
          },
        },
      },
    })
    req, _ := http.NewRequest(
      http.MethodPost,
      "https://api.staging.scan.com/api/v2/referrals",
      bytes.NewBuffer(body),
    )
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SCAN_API_TOKEN"))
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    result, _ := io.ReadAll(resp.Body)
    _ = result
  }
  ```
</CodeGroup>

**What you get back.** The full referral, including its `id`. Hold onto it to
track the referral below.

You can stop here. Scan will collect safety answers and book. If you already have
safety answers, continue with
[Submit medical questions](/guides/submit-medical-questions). If you already have
preferred times, continue with
[Submit preferred times](/guides/submit-preferred-times). If you already have
safety answers and preferred times, use
[Submit for scheduling](/guides/submit-for-scheduling).

Full payload: [Creates a referral](/api-reference/referrals/creates-a-referral).

***

## 3. Follow the referral to the report

You have two ways to stay current. Subscribe to the
[status changed webhook](/webhooks/status-changed) and we push each change to you,
or poll the referral when you need a snapshot.

**GET `/api/v2/referrals/{referral_id}`**

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl "https://api.staging.scan.com/api/v2/referrals/$REFERRAL_ID" \
    -H "Authorization: Bearer $SCAN_API_TOKEN"
  ```

  ```ruby Ruby theme={"dark"}
  require "net/http"
  require "uri"

  uri = URI("https://api.staging.scan.com/api/v2/referrals/#{ENV.fetch("REFERRAL_ID")}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request["Authorization"] = "Bearer #{ENV.fetch("SCAN_API_TOKEN")}"

  response = http.request(request)
  puts response.body
  ```

  ```python Python theme={"dark"}
  import os
  import requests

  referral_id = os.environ["REFERRAL_ID"]
  response = requests.get(
      f"https://api.staging.scan.com/api/v2/referrals/{referral_id}",
      headers={"Authorization": f"Bearer {os.environ['SCAN_API_TOKEN']}"},
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={"dark"}
  const referralId = process.env.REFERRAL_ID;
  const response = await fetch(
    `https://api.staging.scan.com/api/v2/referrals/${referralId}`,
    { headers: { Authorization: `Bearer ${process.env.SCAN_API_TOKEN}` } },
  );

  const referral = await response.json();
  ```

  ```php PHP theme={"dark"}
  $referral_id = getenv("REFERRAL_ID");
  $ch = curl_init("https://api.staging.scan.com/api/v2/referrals/{$referral_id}");
  curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("SCAN_API_TOKEN")],
    CURLOPT_RETURNTRANSFER => true,
  ]);

  $response = curl_exec($ch);
  ```

  ```go Go theme={"dark"}
  package main

  import (
    "fmt"
    "io"
    "net/http"
    "os"
  )

  func main() {
    url := fmt.Sprintf(
      "https://api.staging.scan.com/api/v2/referrals/%s",
      os.Getenv("REFERRAL_ID"),
    )
    req, _ := http.NewRequest(http.MethodGet, url, nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SCAN_API_TOKEN"))

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    _ = body
  }
  ```
</CodeGroup>

**What you get back.** Once we book, `visits[].location` and `visits[].start_time`
tell you where and when the patient is going.

When the scan is read, pull the radiology report PDF with
[GET /api/v2/order\_documents/report](/api-reference/order-documents/returns-the-radiology-report-pdf-for-an-order).

Full payload: [Returns a referral by ID](/api-reference/referrals/returns-a-referral-by-id).
