Skip to main content
Use this guide when your authorization requires supporting documents, or when you want to upload a sandbox payer document for test-ingress. This is separate from the Quickstart on purpose. The quickstart is optimized for your first successful submission. This page covers the file flow in detail.

What you will do

In this guide you will:
  1. create a file upload session
  2. upload bytes to the returned URL
  3. complete the file
  4. attach the file to an authorization

What you need

  • Node.js 20+
  • a sandbox or production API key
  • an existing authorization ID if you want to attach the file immediately
export API_BASE_URL="https://api.sandbox.trycollate.ai"
export API_KEY="your-api-key"

File purposes

Use these file purposes:
  • authorization_attachment
    • for clinical notes, labs, and other supporting material attached to an authorization
  • test_ingress_payer_document
    • for sandbox-only payer documents used with /v1/test-ingress/*

Run this example

Save this as file-uploads.ts:
import { readFile } from "node:fs/promises";

const API_BASE_URL = process.env.API_BASE_URL ?? "https://api.sandbox.trycollate.ai";
const API_KEY = process.env.API_KEY;
const AUTHORIZATION_ID = process.env.AUTHORIZATION_ID;

if (!API_KEY) {
  throw new Error("Set API_KEY before running this example.");
}

if (!AUTHORIZATION_ID) {
  throw new Error("Set AUTHORIZATION_ID before running this example.");
}

type RequestOptions = {
  method?: "GET" | "POST";
  body?: unknown;
};

type CreateFileResponse = {
  file: {
    id: string;
    status: string;
  };
  upload: {
    url: string;
    headers: Record<string, string>;
  };
};

type FileRecord = {
  id: string;
  status: string;
  downloadUrl: string | null;
};

async function request<T>(path: string, options: RequestOptions = {}): Promise<T> {
  const response = await fetch(`${API_BASE_URL}${path}`, {
    method: options.method ?? "GET",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: options.body ? JSON.stringify(options.body) : undefined,
  });

  if (!response.ok) {
    throw new Error(`${response.status} ${await response.text()}`);
  }

  return response.json() as Promise<T>;
}

async function main() {
  const bytes = await readFile("./clinical-note.pdf");

  const created = await request<CreateFileResponse>("/v1/files", {
    method: "POST",
    body: {
      fileName: "clinical-note.pdf",
      contentType: "application/pdf",
      purpose: "authorization_attachment",
    },
  });

  console.log("Created file session", created.file.id, created.file.status);

  const uploadResponse = await fetch(created.upload.url, {
    method: "PUT",
    headers: created.upload.headers,
    body: bytes,
  });

  if (!uploadResponse.ok) {
    throw new Error(`Upload failed: ${uploadResponse.status} ${await uploadResponse.text()}`);
  }

  const completed = await request<FileRecord>(`/v1/files/${created.file.id}/complete`, {
    method: "POST",
  });

  console.log("Completed file", completed.id, completed.status);

  const attachment = await request<{ id: string; fileId: string }>(
    `/v1/prior-auth/authorizations/${AUTHORIZATION_ID}/attachments`,
    {
      method: "POST",
      body: {
        fileId: completed.id,
        label: "Clinical note",
      },
    },
  );

  console.log("Attached file", attachment.id, "to authorization", AUTHORIZATION_ID);
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
Run it with:
export AUTHORIZATION_ID="auth_123"
npx tsx file-uploads.ts
Put the PDF you want to upload at ./clinical-note.pdf, or update the path in the script.

What happens

This flow calls:
  1. POST /v1/files
  2. PUT <upload.url>
  3. POST /v1/files/{fileId}/complete
  4. POST /v1/prior-auth/authorizations/{authorizationId}/attachments

How the upload flow works

  • the API creates and tracks the file resource
  • you upload the bytes directly to the returned storage URL
  • the API validates and finalizes the file on complete

When to use this in the authorization flow

Check requirements.documents on the authorization.
  • if it is empty, you do not need to upload anything yet
  • if it contains required items, upload and attach the matching files before submit
  • if it contains recommended items, you can choose whether to include them

Sandbox payer documents

For sandbox testing, create the file with:
{
  "purpose": "test_ingress_payer_document"
}
After that, use the resulting fileId with the sandbox test-ingress endpoint described in Sandbox testing.