Skip to main content
This guide walks through the intended sandbox integration sequence:
  1. create the authorization
  2. inspect the current blockers
  3. patch the missing data
  4. upload and attach supporting files
  5. generate a preview
  6. submit
  7. test payer outcomes through the sandbox
The examples use curl and jq.

Prerequisites

export API_BASE_URL="https://api.sandbox.trycollate.ai"
export AUTH_TOKEN="your-bearer-token"
This guide is sandbox-only. The same API_BASE_URL and AUTH_TOKEN work for the full sandbox API, including /v1/sandbox/*.
Production uses https://api.trycollate.ai and a separate production credential. Do not reuse your sandbox token against production.

1. Create the authorization

The create call is also the requirement-resolution call. You send payer coverage context plus a coded service, and the response returns a draft authorization with the resolved FHIR R4 Questionnaire.
AUTHORIZATION=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Idempotency-Key: create-auth-001" \
  -d @- <<JSON
{
  "patient": {
    "identifiers": [{ "type": "mrn", "value": "MRN-001" }],
    "firstName": "Jane",
    "lastName": "Doe",
    "dateOfBirth": "1988-05-09",
    "address": {
      "line1": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "zip": "94105"
    }
  },
  "coverage": {
    "payerId": "payer_aetna",
    "memberId": "W123456789",
    "groupNumber": "GRP-123",
    "planType": "commercial",
    "insuranceState": "CA"
  },
  "providers": [{
    "role": "prescribing",
    "identifiers": [
      { "type": "npi", "value": "1234567890" },
      { "type": "dea", "value": "AB1234567" }
    ],
    "firstName": "Ajay",
    "lastName": "Patel",
    "specialty": "hematologist",
    "phone": "415-555-0100",
    "fax": "415-555-0101",
    "address": {
      "line1": "100 Main St",
      "city": "San Francisco",
      "state": "CA",
      "zip": "94105"
    }
  }],
  "requestedBy": {
    "firstName": "Alicia",
    "lastName": "Gomez",
    "phone": "415-555-0100"
  },
  "service": {
    "code": "J0791",
    "codeSystem": "hcpcs",
    "drugName": "Adakveo",
    "requestedStartDate": "2026-03-13",
    "requestedEndDate": "2026-09-13"
  },
  "diagnoses": [
    { "code": "D57.00", "codeSystem": "icd_10" }
  ]
}
JSON
)

echo "$AUTHORIZATION" | jq
export AUTHORIZATION_ID="$(echo "$AUTHORIZATION" | jq -r '.id')"
The response includes:
  • the authorization ID
  • the resolved questionnaire
  • contextRequirements
  • questionStates
  • activeRequirementGroups
  • validationIssues
  • supportingDocumentRequests
  • supportingDocumentationGuidance
  • reduced sourceForm metadata
  • the current workflowState
If workflowState is needs_input, use contextRequirements, questionStates, activeRequirementGroups, and validationIssues together to see what is still missing or currently blocked.

2. Patch the missing data

The exact blockers depend on the payer template and the answers you have already provided. Use validationIssues, contextRequirements, questionStates, and activeRequirementGroups from the authorization response to decide what to patch next. For example, to patch one missing questionnaire answer:
AUTHORIZATION=$(curl -s -X PATCH "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d '{
    "questionnaireResponse": {
      "resourceType": "QuestionnaireResponse",
      "status": "completed",
      "item": [
        { "linkId": "acknowledgment_date", "answer": [{ "valueDate": "2026-03-13" }] }
      ]
    }
  }')

echo "$AUTHORIZATION" | jq
The API rejects answers for questionnaire items that are currently disabled. Use questionStates from the authorization or preview response before sending follow-up answers into a conditional branch.

3. Upload a supporting file

Create a file resource first:
FILE=$(curl -s -X POST "$API_BASE_URL/v1/files" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d '{
    "fileName": "lipid-panel.pdf",
    "contentType": "application/pdf",
    "purpose": "authorization_attachment"
  }')

echo "$FILE" | jq
export FILE_ID="$(echo "$FILE" | jq -r '.file.id')"
Upload the bytes:
curl -s -X PUT "$API_BASE_URL/v1/files/$FILE_ID/content" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @"./lipid-panel.pdf"
Mark the file ready:
READY_FILE=$(curl -s -X POST "$API_BASE_URL/v1/files/$FILE_ID/complete" \
  -H "Authorization: Bearer $AUTH_TOKEN")

echo "$READY_FILE" | jq

4. Attach the file to the authorization

ATTACHMENT=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/attachments" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d @- <<JSON
{
  "fileId": "$FILE_ID",
  "label": "Recent clinical note"
}
JSON
)

echo "$ATTACHMENT" | jq
export ATTACHMENT_ID="$(echo "$ATTACHMENT" | jq -r '.id')"

5. Generate a preview

Preview is an explicit command because it renders documents and refreshes preview state.
PREVIEW=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/preview" \
  -H "Authorization: Bearer $AUTH_TOKEN")

echo "$PREVIEW" | jq
Check:
  • submittable
  • validationIssues
  • contextRequirements
  • questionStates
  • activeRequirementGroups
  • supportingDocumentRequests
  • documents.filledForm
  • documents.draftPacket
Only proceed to submit when submittable is true. If it is false, continue patching top-level context or questionnaire answers until the remaining blocking issues are cleared.

6. Submit

AUTHORIZATION=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/submit" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Idempotency-Key: submit-auth-001")

echo "$AUTHORIZATION" | jq
On success:
  • workflowState becomes pending_payer
  • decisionState becomes pending
  • submission artifacts are generated

7. Read events and artifacts

curl -s "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/events" \
  -H "Authorization: Bearer $AUTH_TOKEN" | jq '.data'

curl -s "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/artifacts" \
  -H "Authorization: Bearer $AUTH_TOKEN" | jq '.data'
Use the authorization, actions, artifacts, events, and webhooks to track the case after submission.

8. Sandbox: inject a payer request for information

The /v1/sandbox/* routes use the same bearer token as the rest of the API. Create a payer document file:
PAYER_DOCUMENT=$(curl -s -X POST "$API_BASE_URL/v1/files" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d '{
    "fileName": "payer-rfi.pdf",
    "contentType": "application/pdf",
    "purpose": "sandbox_payer_document"
  }')

export PAYER_DOCUMENT_FILE_ID="$(echo "$PAYER_DOCUMENT" | jq -r '.file.id')"

curl -s -X PUT "$API_BASE_URL/v1/files/$PAYER_DOCUMENT_FILE_ID/content" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @"./payer-rfi.pdf"

curl -s -X POST "$API_BASE_URL/v1/files/$PAYER_DOCUMENT_FILE_ID/complete" \
  -H "Authorization: Bearer $AUTH_TOKEN" | jq
Inject the payer event:
AUTHORIZATION=$(curl -s -X POST "$API_BASE_URL/v1/sandbox/prior-auth/authorizations/$AUTHORIZATION_ID/payer-events" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d @- <<JSON
{
  "type": "more_info_request",
  "documentFileId": "$PAYER_DOCUMENT_FILE_ID",
  "message": "Payer requested updated clinical notes documenting prior therapy response.",
  "requestedDocuments": ["Updated clinical notes documenting prior therapy response"],
  "resolutionHint": "Attach updated clinical notes, resolve the action, and resubmit."
}
JSON
)

echo "$AUTHORIZATION" | jq
export ACTION_ID="$(echo "$AUTHORIZATION" | jq -r '.actions[] | select(.type == "payer_request_for_information" and .status == "open") | .id' | head -n 1)"

9. Resolve the payer action and resubmit

Upload and attach a new supporting file the same way as before, then resolve the action by attachment ID:
UPDATED_FILE=$(curl -s -X POST "$API_BASE_URL/v1/files" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d '{
    "fileName": "updated-clinical-notes.pdf",
    "contentType": "application/pdf",
    "purpose": "authorization_attachment"
  }')

export UPDATED_FILE_ID="$(echo "$UPDATED_FILE" | jq -r '.file.id')"

curl -s -X PUT "$API_BASE_URL/v1/files/$UPDATED_FILE_ID/content" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @"./updated-clinical-notes.pdf"

curl -s -X POST "$API_BASE_URL/v1/files/$UPDATED_FILE_ID/complete" \
  -H "Authorization: Bearer $AUTH_TOKEN" | jq

UPDATED_ATTACHMENT=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/attachments" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d @- <<JSON
{
  "fileId": "$UPDATED_FILE_ID",
  "label": "Updated clinical notes"
}
JSON
)

export UPDATED_ATTACHMENT_ID="$(echo "$UPDATED_ATTACHMENT" | jq -r '.id')"

AUTHORIZATION=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/actions/$ACTION_ID/resolve" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d @- <<JSON
{
  "attachmentIds": ["$UPDATED_ATTACHMENT_ID"],
  "resolutionNote": "Updated clinical documentation attached."
}
JSON
)

echo "$AUTHORIZATION" | jq

AUTHORIZATION=$(curl -s -X POST "$API_BASE_URL/v1/prior-auth/authorizations/$AUTHORIZATION_ID/submit" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Idempotency-Key: submit-auth-002")

echo "$AUTHORIZATION" | jq

10. Sandbox: inject an approval

APPROVAL_DOCUMENT=$(curl -s -X POST "$API_BASE_URL/v1/files" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d '{
    "fileName": "payer-approval.pdf",
    "contentType": "application/pdf",
    "purpose": "sandbox_payer_document"
  }')

export APPROVAL_DOCUMENT_FILE_ID="$(echo "$APPROVAL_DOCUMENT" | jq -r '.file.id')"

curl -s -X PUT "$API_BASE_URL/v1/files/$APPROVAL_DOCUMENT_FILE_ID/content" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/pdf" \
  --data-binary @"./payer-approval.pdf"

curl -s -X POST "$API_BASE_URL/v1/files/$APPROVAL_DOCUMENT_FILE_ID/complete" \
  -H "Authorization: Bearer $AUTH_TOKEN" | jq

AUTHORIZATION=$(curl -s -X POST "$API_BASE_URL/v1/sandbox/prior-auth/authorizations/$AUTHORIZATION_ID/payer-events" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -d @- <<JSON
{
  "type": "approval",
  "documentFileId": "$APPROVAL_DOCUMENT_FILE_ID",
  "certificationNumber": "AUTH-2026-ABC123",
  "approvedStartDate": "2026-03-12T00:00:00.000Z",
  "approvedEndDate": "2026-09-08T00:00:00.000Z",
  "approvalExpiresAt": "2027-03-12T00:00:00.000Z",
  "payerReferenceNumber": "PAYER-123"
}
JSON
)

echo "$AUTHORIZATION" | jq
At this point the authorization should be completed with decisionState = approved.