HealthcareParse → Extract

Prior Authorization Request Form

Extracts provider, member, and diagnosis information from healthcare prior authorization requests.

Ship it with Extend

Live pipeline

a real document, processed end to end · view only
Source documentPrior auth doc sample.jpg

Step-by-step

A prior authorization request form is a healthcare document submitted by providers to obtain payer approval for covered medical services, containing member demographics, provider credentials, diagnosis codes, and treatment details necessary for authorization decisions. This template takes in Prior Authorization Request Form and outputs markdown (.md) preserving the form's full text and structure, and JSON (.json) with extracted provider, member, diagnosis, and service authorization fields per the extraction schema by using Extend's Parse, Extract primitives.

Input
Prior Authorization Request Form
Compatible document types (full list)
.pdf.docx.xlsx.png.jpg.jpeg.tiff.tif.svg.heic.heif.bmp.gif.webp.psd.xls.xltm.xltx.ods.doc.wpd.dotx.odt.pptx.ppt.ppm.csv.txt.html.xml.rtf.lis.md.eml.pcx
Step 1

Parse

Converts the document into clean, layout-aware markdown plus structured blocks with spatial metadata.

InputSource document — PDF, image, spreadsheet, presentation, or scan
Config
blockOptions.text.agentic.enabledtruechanged
chunkingStrategy.type"document"
engine"parse_performance"
OutputMarkdown chunked by page or section, plus typed blocks (text, table, figure) with bounding boxes

You can learn more about Parse configuration in Extend's Parse documentation.

Step 2

Extract

Pulls a defined set of fields from the document and returns them as structured JSON matching a schema.

InputOutput of the Parse step
Config
schemacustom schema — 23 fieldschanged
advancedOptions.advancedMultimodalEnabledtruechanged
advancedOptions.reviewAgent.enabledtruechanged
baseProcessor"extraction_performance"
OutputJSON shaped to the extraction schema, with per-field confidence scores and citations grounding each value to its source location

You can learn more about Extract configuration in Extend's Extract documentation.

Example code

{
  "name": "Prior Authorization (PA) Request Form (RF) Processing Pipeline",
  "steps": [
    {
      "name": "startTrigger1",
      "type": "TRIGGER",
      "next": [
        {
          "step": "parse1"
        }
      ]
    },
    {
      "name": "parse1",
      "type": "PARSE",
      "config": {
        "parseConfig": {
          "blockOptions": {
            "text": {
              "agentic": {
                "enabled": true
              }
            }
          },
          "chunkingStrategy": {
            "type": "document"
          }
        }
      },
      "next": [
        {
          "step": "extraction2"
        }
      ]
    },
    {
      "name": "extraction2",
      "type": "EXTRACT",
      "config": {
        "extractorConfig": {
          "schema": {
            "type": "object",
            "required": [
              "date_signed",
              "member_name",
              "process_type",
              "member_gender",
              "service_lines",
              "total_charges",
              "member_address",
              "authorization_number",
              "member_date_of_birth",
              "billing_provider_name",
              "primary_diagnosis_code",
              "billing_provider_number",
              "first_date_of_treatment",
              "requested_pa_start_date",
              "billing_provider_address",
              "prescribing_provider_npi",
              "secondary_diagnosis_code",
              "prescribing_provider_name",
              "member_identification_number",
              "primary_diagnosis_description",
              "requesting_provider_signature",
              "billing_provider_taxonomy_code",
              "secondary_diagnosis_description"
            ],
            "properties": {
              "date_signed": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request.",
                "extend:type": "date"
              },
              "member_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service."
              },
              "process_type": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar."
              },
              "member_gender": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text."
              },
              "service_lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "charge",
                    "modifiers",
                    "service_code",
                    "place_of_service",
                    "quantity_requested",
                    "service_description",
                    "rendering_provider_number",
                    "rendering_provider_taxonomy_code"
                  ],
                  "properties": {
                    "charge": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "The monetary charge associated with this service line, representing the requested reimbursement for this specific service."
                    },
                    "modifiers": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes."
                    },
                    "service_code": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested."
                    },
                    "place_of_service": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code."
                    },
                    "quantity_requested": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar."
                    },
                    "service_description": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details."
                    },
                    "rendering_provider_number": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar."
                    },
                    "rendering_provider_taxonomy_code": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The taxonomy code for the provider rendering this service line, indicating their specialty or classification."
                    }
                  },
                  "additionalProperties": false
                },
                "description": "The individual services, procedures, or items being requested for prior authorization. Each entry represents a distinct service line with associated codes, descriptions, and charges. These may be presented in a table or list format and can vary in number and structure."
              },
              "total_charges": {
                "type": "object",
                "required": [
                  "amount",
                  "iso_4217_currency_code"
                ],
                "properties": {
                  "amount": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "iso_4217_currency_code": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "description": "The total amount of charges associated with all requested services on this prior authorization form. This is the sum of all line item charges and represents the total financial request.",
                "extend:type": "currency",
                "additionalProperties": false
              },
              "member_address": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The complete address of the member or patient, including street, city, state, and ZIP code."
              },
              "authorization_number": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The unique identifier assigned to this prior authorization request. This number is used to track and reference the authorization throughout the review and claims process. May be labeled as 'PA Number', 'Authorization #', or similar, and can include letters, numbers, or special characters."
              },
              "member_date_of_birth": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The date of birth of the member or patient. Used to verify identity and eligibility. May appear in various date formats.",
                "extend:type": "date"
              },
              "billing_provider_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The full name of the provider or organization submitting the billing for this authorization request. This is the entity responsible for providing the service and requesting payment."
              },
              "primary_diagnosis_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The primary diagnosis code (such as ICD-10) that justifies the need for the requested service. This is the main clinical reason for the authorization request."
              },
              "billing_provider_number": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The unique identification number assigned to the billing provider by the payer or regulatory body. May be labeled as 'Provider Number', 'Billing Provider ID', or similar."
              },
              "first_date_of_treatment": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The first date on which the requested service or treatment is expected to be provided. May be labeled as 'First Date of Treatment' or similar.",
                "extend:type": "date"
              },
              "requested_pa_start_date": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The requested start date for the prior authorization period. This is when the provider wishes the authorization to begin.",
                "extend:type": "date"
              },
              "billing_provider_address": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The complete address of the billing provider, including street, city, state, and ZIP code. This identifies the location of the provider submitting the request."
              },
              "prescribing_provider_npi": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The National Provider Identifier (NPI) for the prescribing, referring, or ordering provider. This is a unique 10-digit identification number for healthcare providers in the United States."
              },
              "secondary_diagnosis_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "An additional diagnosis code (such as ICD-10) relevant to the request. This may support the medical necessity of the service."
              },
              "prescribing_provider_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The full name of the provider who is prescribing, referring, or ordering the service for which prior authorization is requested. May be labeled as 'Prescribing Provider', 'Referring Provider', or 'Ordering Provider'."
              },
              "member_identification_number": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The unique identification number assigned to the member or patient for whom the prior authorization is being requested. May be labeled as 'Member ID', 'Recipient Number', or similar."
              },
              "primary_diagnosis_description": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "A textual description of the primary diagnosis associated with the request. This provides additional clinical context beyond the code."
              },
              "requesting_provider_signature": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The name or signature of the provider submitting the prior authorization request. This may be a handwritten or electronic signature, or simply the provider's printed name."
              },
              "billing_provider_taxonomy_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The taxonomy code representing the specialty or classification of the billing provider. This code helps identify the provider's area of practice."
              },
              "secondary_diagnosis_description": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "A textual description of the secondary diagnosis, if provided."
              }
            },
            "additionalProperties": false
          },
          "baseProcessor": "extraction_performance",
          "advancedOptions": {
            "reviewAgent": {
              "enabled": true
            },
            "advancedMultimodalEnabled": true
          }
        }
      }
    }
  ]
}
# Prior Authorization (PA) Request Form (RF) Processing — Extend AI Skill

## What this pipeline does

This pipeline extracts structured healthcare authorization data from ForwardHealth Prior Authorization Request Forms. It parses the document into markdown, then extracts 23 required fields including member demographics, provider credentials, diagnosis codes, service line details (CPT codes, quantities, charges), and authorization metadata. Output is production-ready JSON with full typing, suitable for payer review systems, eligibility verification, and claims pre-processing.

## When to use this

- **Automated PA intake**: Eliminate manual data entry when providers submit PA/RF forms; extract directly into your authorization management system.
- **Mental health service pre-authorization**: Psychotherapy, counseling, and psychiatric services require detailed service-line extraction that this pipeline handles at scale.
- **Multi-provider claims networks**: Route extracted data to appropriate payers or networks based on billing provider taxonomy and member ID.
- **Compliance and audit trails**: Capture provider signatures, dates, and diagnosis justification in structured form for regulatory review.
- **Real-time eligibility checks**: Feed member ID, DOB, and primary diagnosis into downstream eligibility systems before manual review.

## Processor pipeline

### Step 1: Parse (agentic OCR + markdown output)
**Processor**: `parse_performance` with agentic text extraction  
**Purpose**: Convert the PDF into clean markdown with full text recovery, handling provider handwriting, checkboxes, and complex table layouts common in healthcare forms.  
**Key config**:
- `blockOptions.text.agentic.enabled: true` — Uses Claude to understand context and recover smudged or handwritten text (critical for signatures and provider notes).
- `chunkingStrategy.type: "document"` — Keeps the entire form as one logical unit rather than splitting across pages, preserving service-line table structure.

**Why**: PA/RF forms often mix typed fields with handwritten provider signatures and clinical notes. Agentic OCR recovers intent when pixels are unclear. Document-level chunking prevents service lines from being split mid-table.

### Step 2: Extract (structured fields via Zod schema + review agent)
**Processor**: `extraction_performance` with `reviewAgent: true` and `advancedMultimodalEnabled: true`  
**Purpose**: Pull 23 fields into JSON, with nested array for service lines (up to N rows). Currency amounts are typed; dates are ISO-8601.  
**Key config**:
- `baseProcessor: "extraction_performance"` — Balances accuracy and latency; handles complex multi-step schemas with nested objects and arrays.
- `reviewAgent: true` — Enables internal validation pass; checks that extracted codes (CPT, ICD-10, NPI, taxonomy) are valid formats before returning.
- `advancedMultimodalEnabled: true` — Allows extractor to cross-reference visual layout (e.g., checkbox state) with text for gender, process type, and service details.

**Why**: PA forms are high-stakes documents (authorization decisions worth thousands). The review agent catches common extraction errors (malformed NPI, wrong currency code, missing modifiers). Multimodal processing ensures checkboxes and radio buttons are correctly interpreted even if OCR text is ambiguous.

## TypeScript implementation



## CLI equivalent

```bash
# Step 1: Parse PA/RF form to markdown
extend parse pa_form.pdf

# Step 2: Extract structured fields using the schema
extend extract pa_form.pdf \
  --schema pa_rf_schema.json \
  --base-processor extraction_performance \
  --review-agent \
  --advanced-multimodal

# Or run the full workflow in one command
extend run workflow_pa_rf --file pa_form.pdf
```

**pa_rf_schema.json** (save this file for CLI use):
```json
{
  "type": "object",
  "properties": {
    "date_signed": {
      "type": ["string", "null"],
      "extend:type": "date",
      "description": "The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request."
    },
    "member_name": {
      "type": ["string", "null"],
      "description": "The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service."
    },
    "process_type": {
      "type": ["string", "null"],
      "description": "The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar."
    },
    "member_gender": {
      "type": ["string", "null"],
      "description": "The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text."
    },
    "service_lines": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "charge": {
            "type": ["number", "null"],
            "description": "The monetary charge associated with this service line, representing the requested reimbursement for this specific service."
          },
          "modifiers": {
            "type": ["string", "null"],
            "description": "Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes."
          },
          "service_code": {
            "type": ["string", "null"],
            "description": "The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested."
          },
          "place_of_service": {
            "type": ["string", "null"],
            "description": "The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code."
          },
          "quantity_requested": {
            "type": ["number", "null"],
            "description": "The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar."
          },
          "service_description": {
            "type": ["string", "null"],
            "description": "A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details."
          },
          "rendering_provider_number": {
            "type": ["string", "null"],
            "description": "The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar."
          },
          "rendering_provider_taxonomy_code": {
            "type": ["string", "null"],
            "description": "The taxonomy code for the provider rendering this service line, indicating their specialty or
import { ExtendClient, extendDate, extendCurrency } from "extend-ai";
import { z } from "zod";
import fs from "fs";

const client = new ExtendClient({ token: process.env.EXTEND_API_KEY });

// Define the Zod schema matching the PA/RF extraction requirements
const paRequestFormSchema = z.object({
  // Header & administrative
  date_signed: extendDate().describe("The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request."),
  authorization_number: z.string().nullable().describe("The unique identifier assigned to this prior authorization request. This number is used to track and reference the authorization throughout the review and claims process. May be labeled as 'PA Number', 'Authorization #', or similar, and can include letters, numbers, or special characters."),
  process_type: z.string().nullable().describe("The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar."),
  
  // Member demographics
  member_name: z.string().nullable().describe("The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service."),
  member_identification_number: z.string().nullable().describe("The unique identification number assigned to the member or patient for whom the prior authorization is being requested. May be labeled as 'Member ID', 'Recipient Number', or similar."),
  member_date_of_birth: extendDate().describe("The date of birth of the member or patient. Used to verify identity and eligibility. May appear in various date formats."),
  member_gender: z.string().nullable().describe("The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text."),
  member_address: z.string().nullable().describe("The complete address of the member or patient, including street, city, state, and ZIP code."),
  
  // Billing provider
  billing_provider_name: z.string().nullable().describe("The full name of the provider or organization submitting the billing for this authorization request. This is the entity responsible for providing the service and requesting payment."),
  billing_provider_number: z.string().nullable().describe("The unique identification number assigned to the billing provider by the payer or regulatory body. May be labeled as 'Provider Number', 'Billing Provider ID', or similar."),
  billing_provider_address: z.string().nullable().describe("The complete address of the billing provider, including street, city, state, and ZIP code. This identifies the location of the provider submitting the request."),
  billing_provider_taxonomy_code: z.string().nullable().describe("The taxonomy code representing the specialty or classification of the billing provider. This code helps identify the provider's area of practice."),
  requesting_provider_signature: z.string().nullable().describe("The name or signature of the provider submitting the prior authorization request. This may be a handwritten or electronic signature, or simply the provider's printed name."),
  
  // Prescribing/ordering provider
  prescribing_provider_name: z.string().nullable().describe("The full name of the provider who is prescribing, referring, or ordering the service for which prior authorization is requested. May be labeled as 'Prescribing Provider', 'Referring Provider', or 'Ordering Provider'."),
  prescribing_provider_npi: z.string().nullable().describe("The National Provider Identifier (NPI) for the prescribing, referring, or ordering provider. This is a unique 10-digit identification number for healthcare providers in the United States."),
  
  // Diagnosis
  primary_diagnosis_code: z.string().nullable().describe("The primary diagnosis code (such as ICD-10) that justifies the need for the requested service. This is the main clinical reason for the authorization request."),
  primary_diagnosis_description: z.string().nullable().describe("A textual description of the primary diagnosis associated with the request. This provides additional clinical context beyond the code."),
  secondary_diagnosis_code: z.string().nullable().describe("An additional diagnosis code (such as ICD-10) relevant to the request. This may support the medical necessity of the service."),
  secondary_diagnosis_description: z.string().nullable().describe("A textual description of the secondary diagnosis, if provided."),
  
  // Treatment dates
  first_date_of_treatment: extendDate().describe("The first date on which the requested service or treatment is expected to be provided. May be labeled as 'First Date of Treatment' or similar."),
  requested_pa_start_date: extendDate().describe("The requested start date for the prior authorization period. This is when the provider wishes the authorization to begin."),
  
  // Service lines
  service_lines: z.array(
    z.object({
      service_code: z.string().nullable().describe("The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested."),
      service_description: z.string().nullable().describe("A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details."),
      modifiers: z.string().nullable().describe("Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes."),
      place_of_service: z.string().nullable().describe("The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code."),
      quantity_requested: z.number().nullable().describe("The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar."),
      charge: z.number().nullable().describe("The monetary charge associated with this service line, representing the requested reimbursement for this specific service."),
      rendering_provider_number: z.string().nullable().describe("The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar."),
      rendering_provider_taxonomy_code: z.string().nullable().describe("The taxonomy code for the provider rendering this service line, indicating their specialty or classification."),
    })
  ).describe("The individual services, procedures, or items being requested for prior authorization. Each entry represents a distinct service line with associated codes, descriptions, and charges. These may be presented in a table or list format and can vary in number and structure."),
  
  // Total charges
  total_charges: extendCurrency().describe("The total amount of charges associated with all requested services on this prior authorization form. This is the sum of all line item charges and represents the total financial request."),
});

// Main extraction function
export async function processPriorAuthorizationPARequestFormRF(filePath: string) {
  console.log(`Processing PA/RF form: ${filePath}`);
  
  // Convert local file to base64 data URL
  const fileBuffer = fs.readFileSync(filePath);
  const base64Data = fileBuffer.toString("base64");
  const dataUrl = `data:application/pdf;base64,${base64Data}`;
  
  try {
    // Step 1: Parse the document to markdown
    console.log("Step 1: Parsing document to markdown...");
    const parseRun = await client.parseRuns.createAndPoll({
      file: { url: dataUrl },
      config: {
        blockOptions: {
          text: {
            agentic: { enabled: true },
          },
        },
        chunkingStrategy: { type: "document" },
      },
    });
    
    if (parseRun.status !== "PROCESSED") {
      throw new Error(`Parse failed with status: ${parseRun.status}`);
    }
    
    const parsedMarkdown = parseRun.output.chunks
      .map((chunk) => chunk.content)
      .join("\n\n");
    console.log(`✓ Parse complete. Markdown length: ${parsedMarkdown.length} chars`);
    
    // Step 2: Extract structured fields
    console.log("Step 2: Extracting PA/RF fields...");
    const extractRun = await client.extractRuns.createAndPoll({
      file: { url: dataUrl },
      config: {
        schema: paRequestFormSchema,
        baseProcessor: "extraction_performance",
        advancedOptions: {
          reviewAgent: { enabled: true },
          advancedMultimodalEnabled: true,
        },
      },
    });
    
    if (extractRun.status !== "PROCESSED") {
      throw new Error(`Extraction failed with status: ${extractRun.status}`);
    }
    
    const extractedData = extractRun.output.value;
    
    // Validate and log results
    console.log("\n✓ Extraction complete. Extracted fields:");
    console.log(JSON.stringify(extractedData, null, 2));
    
    return {
      status: "success",
      parsed_markdown: parsedMarkdown,
      extracted_fields: extractedData,
      member_name: extractedData.member_name,
      member_id: extractedData.member_identification_number,
      authorization_number: extractedData.authorization_number,
      primary_diagnosis: extractedData.primary_diagnosis_code,
      service_count: extractedData.service_lines.length,
      total_charges: extractedData.total_charges,
    };
  } catch (error) {
    console.error("Error processing PA/RF form:", error);
    throw error;
  }
}

// Example usage (for testing)
if (require.main === module) {
  const testFilePath = process.argv[2] || "sample_pa_form.pdf";
  processPriorAuthorizationPARequestFormRF(testFilePath)
    .then((result) => {
      console.log("\nFinal result:", JSON.stringify(result, null, 2));
    })
    .catch((err) => {
      console.error("Fatal error:", err);
      process.exit(1);
    });
}
import os
import json
from extend_ai import Extend

# Initialize the Extend client
client = Extend(token=os.environ["EXTEND_API_KEY"])

# Define the extraction schema as a plain dict matching the JSON structure
pa_request_form_schema = {
    "type": "object",
    "properties": {
        "form_number": {
            "type": ["string", "null"],
            "description": "Form identifier (e.g., F-11018)"
        },
        "process_type": {
            "type": ["string", "null"],
            "description": "Prior Authorization process type code"
        },
        "billing_provider": {
            "type": ["object", "null"],
            "properties": {
                "name": {
                    "type": ["string", "null"],
                    "description": "Billing provider name"
                },
                "number": {
                    "type": ["string", "null"],
                    "description": "Billing provider identification number"
                },
                "taxonomy_code": {
                    "type": ["string", "null"],
                    "description": "Billing provider taxonomy code"
                },
                "phone": {
                    "type": ["string", "null"],
                    "description": "Billing provider telephone number"
                },
                "address": {
                    "type": ["string", "null"],
                    "description": "Billing provider street address, city, state, ZIP"
                }
            }
        },
        "prescribing_provider": {
            "type": ["object", "null"],
            "properties": {
                "name": {
                    "type": ["string", "null"],
                    "description": "Prescribing, referring, or ordering provider name"
                },
                "npi": {
                    "type": ["string", "null"],
                    "description": "National Provider Identifier"
                }
            }
        },
        "member": {
            "type": ["object", "null"],
            "properties": {
                "id": {
                    "type": ["string", "null"],
                    "description": "Member identification number"
                },
                "name": {
                    "type": ["string", "null"],
                    "description": "Member name (last, first, middle initial)"
                },
                "dob": {
                    "type": ["string", "null"],
                    "description": "Member date of birth (MM/DD/CCYY)"
                },
                "gender": {
                    "type": ["string", "null"],
                    "description": "Member gender (Male/Female)"
                },
                "address": {
                    "type": ["string", "null"],
                    "description": "Member address (street, city, state, ZIP)"
                }
            }
        },
        "primary_diagnosis": {
            "type": ["object", "null"],
            "properties": {
                "code": {
                    "type": ["string", "null"],
                    "description": "Primary diagnosis code (ICD-10)"
                },
                "description": {
                    "type": ["string", "null"],
                    "description": "Primary diagnosis description"
                }
            }
        },
        "secondary_diagnosis": {
            "type": ["object", "null"],
            "properties": {
                "code": {
                    "type": ["string", "null"],
                    "description": "Secondary diagnosis code (ICD-10)"
                },
                "description": {
                    "type": ["string", "null"],
                    "description": "Secondary diagnosis description"
                }
            }
        },
        "service_dates": {
            "type": ["object", "null"],
            "properties": {
                "start_of_illness": {
                    "type": ["string", "null"],
                    "description": "Start date of illness (MM/DD/CCYY)"
                },
                "first_treatment_date": {
                    "type": ["string", "null"],
                    "description": "First date of treatment (MM/DD/CCYY)"
                },
                "pa_start_date": {
                    "type": ["string", "null"],
                    "description": "Requested PA start date (MM/DD/CCYY)"
                }
            }
        },
        "rendering_provider": {
            "type": ["object", "null"],
            "properties": {
                "number": {
                    "type": ["string", "null"],
                    "description": "Rendering provider number"
                },
                "taxonomy_code": {
                    "type": ["string", "null"],
                    "description": "Rendering provider taxonomy code"
                }
            }
        },
        "program_types": {
            "type": ["array", "null"],
            "items": {
                "type": "string"
            },
            "description": "Applicable program types (HealthCheck, WCDP, etc.)"
        }
    }
}


def process_prior_authorization_pa_request_form_rf(file_path: str) -> dict:
    """
    Process a Prior Authorization (PA) Request Form (RF) document.
    
    Args:
        file_path: Path to the PA/RF form file (PDF or image)
        
    Returns:
        Dictionary containing parsed markdown and extracted fields
    """
    print(f"Processing PA/RF form: {file_path}")
    
    try:
        # Step 1: Upload the file
        print("Step 1: Uploading file...")
        with open(file_path, "rb") as f:
            file_response = client.files.upload(file=f)
        file_id = file_response.id
        print(f"✓ File uploaded with ID: {file_id}")
        
        # Step 2: Parse the document to markdown
        print("Step 2: Parsing document to markdown...")
        parse_run = client.parse_runs.create_and_poll(
            file={"id": file_id},
            config={
                "block_options": {
                    "text": {
                        "agentic": {"enabled": True}
                    }
                },
                "chunking_strategy": {"type": "document"}
            }
        )
        
        if parse_run.status != "PROCESSED":
            raise Exception(f"Parse failed with status: {parse_run.status}")
        
        parsed_markdown = "\n\n".join(
            chunk.content for chunk in parse_run.output.chunks
        )
        print(f"✓ Parse complete. Markdown length: {len(parsed_markdown)} chars")
        
        # Step 3: Extract structured fields
        print("Step 3: Extracting PA/RF fields...")
        extract_run = client.extract_runs.create_and_poll(
            file={"id": file_id},
            config={
                "schema": pa_request_form_schema,
                "base_processor": "extraction_performance",
                "advanced_options": {
                    "review_agent": {"enabled": True},
                    "advanced_multimodal_enabled": True
                }
            }
        )
        
        if extract_run.status != "PROCESSED":
            raise Exception(f"Extraction failed with status: {extract_run.status}")
        
        extracted_data = extract_run.output.value
        
        # Validate and log results
        print("\n✓ Extraction complete. Extracted fields:")
        print(json.dumps(extracted_data, indent=2))
        
        # Build summary result
        member_info = extracted_data.get("member") or {}
        primary_diag = extracted_data.get("primary_diagnosis") or {}
        
        return {
            "status": "success",
            "parsed_markdown": parsed_markdown,
            "extracted_fields": extracted_data,
            "member_name": member_info.get("name"),
            "member_id": member_info.get("id"),
            "authorization_number": extracted_data.get("form_number"),
            "primary_diagnosis": primary_diag.get("code"),
            "process_type": extracted_data.get("process_type")
        }
        
    except Exception as error:
        print(f"Error processing PA/RF form: {error}")
        raise


if __name__ == "__main__":
    import sys
    
    test_file_path = sys.argv[1] if len(sys.argv) > 1 else "sample_pa_form.pdf"
    
    try:
        result = process_prior_authorization_pa_request_form_rf(test_file_path)
        print("\nFinal result:")
        print(json.dumps(result, indent=2))
    except Exception as err:
        print(f"Fatal error: {err}")
        sys.exit(1)
// This code uses Extend's REST API directly because Extend has no official Java SDK yet.
// It calls https://api.extend.ai endpoints with Bearer token authentication.

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class PriorAuthorizationProcessor {
  private static final String API_BASE_URL = "https://api.extend.ai";
  private static final String API_KEY = System.getenv("EXTEND_API_KEY");
  private static final HttpClient httpClient = HttpClient.newHttpClient();

  // Simple JSON builder (no external library)
  private static String toJson(Object obj) {
    if (obj == null) return "null";
    if (obj instanceof String) return "\"" + escapeJson((String) obj) + "\"";
    if (obj instanceof Number) return obj.toString();
    if (obj instanceof Boolean) return obj.toString();
    if (obj instanceof Map) {
      Map<?, ?> map = (Map<?, ?>) obj;
      StringBuilder sb = new StringBuilder("{");
      boolean first = true;
      for (Map.Entry<?, ?> entry : map.entrySet()) {
        if (!first) sb.append(",");
        sb.append("\"").append(entry.getKey()).append("\":");
        sb.append(toJson(entry.getValue()));
        first = false;
      }
      sb.append("}");
      return sb.toString();
    }
    return "\"" + escapeJson(obj.toString()) + "\"";
  }

  private static String escapeJson(String s) {
    return s.replace("\\", "\\\\")
        .replace("\"", "\\\"")
        .replace("\n", "\\n")
        .replace("\r", "\\r")
        .replace("\t", "\\t");
  }

  // Parse document to markdown
  private static String parseDocument(String dataUrl) throws IOException, InterruptedException {
    Map<String, Object> config = new HashMap<>();
    Map<String, Object> blockOptions = new HashMap<>();
    Map<String, Object> textOptions = new HashMap<>();
    Map<String, Object> agenticOptions = new HashMap<>();
    agenticOptions.put("enabled", true);
    textOptions.put("agentic", agenticOptions);
    blockOptions.put("text", textOptions);
    config.put("blockOptions", blockOptions);
    Map<String, Object> chunkingStrategy = new HashMap<>();
    chunkingStrategy.put("type", "document");
    config.put("chunkingStrategy", chunkingStrategy);

    Map<String, Object> fileObj = new HashMap<>();
    fileObj.put("url", dataUrl);

    Map<String, Object> requestBody = new HashMap<>();
    requestBody.put("file", fileObj);
    requestBody.put("config", config);

    String jsonBody = toJson(requestBody);

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(API_BASE_URL + "/v1/parseRuns/createAndPoll"))
        .header("Authorization", "Bearer " + API_KEY)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
        .build();

    HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() != 200) {
      throw new IOException("Parse request failed with status " + response.statusCode() + ": " + response.body());
    }

    // Simple JSON parsing (extract chunks array and concatenate content)
    String responseBody = response.body();
    int chunksIndex = responseBody.indexOf("\"chunks\"");
    if (chunksIndex == -1) {
      throw new IOException("No chunks found in parse response");
    }

    StringBuilder markdown = new StringBuilder();
    int contentStart = responseBody.indexOf("\"content\"", chunksIndex);
    while (contentStart != -1) {
      int valueStart = responseBody.indexOf("\"", contentStart + 10);
      int valueEnd = responseBody.indexOf("\"", valueStart + 1);
      if (valueStart != -1 && valueEnd != -1) {
        String content = responseBody.substring(valueStart + 1, valueEnd);
        content = content.replace("\\n", "\n").replace("\\\"", "\"").replace("\\\\", "\\");
        markdown.append(content).append("\n\n");
      }
      contentStart = responseBody.indexOf("\"content\"", valueEnd);
    }

    return markdown.toString();
  }

  // Extract structured fields
  private static Map<String, Object> extractFields(String dataUrl) throws IOException, InterruptedException {
    Map<String, Object> schema = buildSchema();

    Map<String, Object> advancedOptions = new HashMap<>();
    Map<String, Object> reviewAgent = new HashMap<>();
    reviewAgent.put("enabled", true);
    advancedOptions.put("reviewAgent", reviewAgent);
    advancedOptions.put("advancedMultimodalEnabled", true);

    Map<String, Object> config = new HashMap<>();
    config.put("schema", schema);
    config.put("baseProcessor", "extraction_performance");
    config.put("advancedOptions", advancedOptions);

    Map<String, Object> fileObj = new HashMap<>();
    fileObj.put("url", dataUrl);

    Map<String, Object> requestBody = new HashMap<>();
    requestBody.put("file", fileObj);
    requestBody.put("config", config);

    String jsonBody = toJson(requestBody);

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(API_BASE_URL + "/v1/extractRuns/createAndPoll"))
        .header("Authorization", "Bearer " + API_KEY)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
        .build();

    HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() != 200) {
      throw new IOException("Extract request failed with status " + response.statusCode() + ": " + response.body());
    }

    // Return parsed output (simplified extraction of value object)
    Map<String, Object> result = new HashMap<>();
    String responseBody = response.body();
    int valueIndex = responseBody.indexOf("\"value\"");
    if (valueIndex != -1) {
      result.put("raw_response", responseBody);
    }
    return result;
  }

  private static Map<String, Object> buildSchema() {
    Map<String, Object> schema = new HashMap<>();
    schema.put("type", "object");

    Map<String, Object> properties = new HashMap<>();

    // Member object
    Map<String, Object> memberProps = new HashMap<>();
    memberProps.put("id", Map.of("type", "string", "description", "Member identification number"));
    memberProps.put("name", Map.of("type", "string", "description", "Member name (last, first, middle initial)"));
    memberProps.put("dob", Map.of("type", "string", "description", "Member date of birth (MM/DD/CCYY)"));
    memberProps.put("gender", Map.of("type", "string", "description", "Member gender (Male/Female)"));
    memberProps.put("address", Map.of("type", "string", "description", "Member address (street, city, state, ZIP)"));
    Map<String, Object> memberObj = new HashMap<>();
    memberObj.put("type", "object");
    memberObj.put("properties", memberProps);
    properties.put("member", memberObj);

    // Billing provider object
    Map<String, Object> billingProps = new HashMap<>();
    billingProps.put("name", Map.of("type", "string", "description", "Billing provider name"));
    billingProps.put("number", Map.of("type", "string", "description", "Billing provider identification number"));
    billingProps.put("taxonomy_code", Map.of("type", "string", "description", "Billing provider taxonomy code"));
    billingProps.put("phone", Map.of("type", "string", "description", "Billing provider telephone number"));
    billingProps.put("address", Map.of("type", "string", "description", "Billing provider street address, city, state, ZIP"));
    Map<String, Object> billingObj = new HashMap<>();
    billingObj.put("type", "object");
    billingObj.put("properties", billingProps);
    properties.put("billing_provider", billingObj);

    // Prescribing provider object
    Map<String, Object> prescribingProps = new HashMap<>();
    prescribingProps.put("name", Map.of("type", "string", "description", "Prescribing, referring, or ordering provider name"));
    prescribingProps.put("npi", Map.of("type", "string", "description", "National Provider Identifier"));
    Map<String, Object> prescribingObj = new HashMap<>();
    prescribingObj.put("type", "object");
    prescribingObj.put("properties", prescribingProps);
    properties.put("prescribing_provider", prescribingObj);

    // Primary diagnosis object
    Map<String, Object> diagnosisProps = new HashMap<>();
    diagnosisProps.put("code", Map.of("type", "string", "description", "Primary diagnosis code (ICD-10)"));
    diagnosisProps.put("description", Map.of("type", "string", "description", "Primary diagnosis description"));
    Map<String, Object> diagnosisObj = new HashMap<>();
    diagnosisObj.put("type", "object");
    diagnosisObj.put("properties", diagnosisProps);
    properties.put("primary_diagnosis", diagnosisObj);

    // Secondary diagnosis object
    Map<String, Object> secondaryDiagnosisProps = new HashMap<>();
    secondaryDiagnosisProps.put("code", Map.of("type", "string", "description", "Secondary diagnosis code (ICD-10)"));
    secondaryDiagnosisProps.put("description", Map.of("type", "string", "description", "Secondary diagnosis description"));
    Map<String, Object> secondaryDiagnosisObj = new HashMap<>();
    secondaryDiagnosisObj.put("type", "object");
    secondaryDiagnosisObj.put("properties", secondaryDiagnosisProps);
    properties.put("secondary_diagnosis", secondaryDiagnosisObj);

    // Service dates object
    Map<String, Object> serviceDatesProps = new HashMap<>();
    serviceDatesProps.put("start_of_illness", Map.of("type", "string", "description", "Start date of illness (MM/DD/CCYY)"));
    serviceDatesProps.put("first_treatment_date", Map.of("type", "string", "description", "First date of treatment (MM/DD/CCYY)"));
    serviceDatesProps.put("pa_start_date", Map.of("type", "string", "description", "Requested PA start date (MM/DD/CCYY)"));
    Map<String, Object> serviceDatesObj = new HashMap<>();
    serviceDatesObj.put("type", "object");
    serviceDatesObj.put("properties", serviceDatesProps);
    properties.put("service_dates", serviceDatesObj);

    // Rendering provider object
    Map<String, Object> renderingProps = new HashMap<>();
    renderingProps.put("number", Map.of("type", "string", "description", "Rendering provider number"));
    renderingProps.put("taxonomy_code", Map.of("type", "string", "description", "Rendering provider taxonomy code"));
    Map<String, Object> renderingObj = new HashMap<>();
    renderingObj.put("type", "object");
    renderingObj.put("properties", renderingProps);
    properties.put("rendering_provider", renderingObj);

    // Top-level fields
    properties.put("form_number", Map.of("type", "string", "description", "Form identifier (e.g., F-11018)"));
    properties.put("process_type", Map.of("type", "string", "description", "Prior Authorization process type code"));
    properties.put("program_types", Map.of("type", "array", "items", Map.of("type", "string"), "description", "Applicable program types (HealthCheck, WCDP, etc.)"));

    schema.put("properties", properties);
    return schema;
  }

  public static Map<String, Object> processPriorAuthorizationPARequestFormRF(String filePath) throws IOException, InterruptedException {
    System.out.println("Processing PA/RF form: " + filePath);

    // Convert local file to base64 data URL
    byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
    String base64Data = Base64.getEncoder().encodeToString(fileBytes);
    String dataUrl = "data:application/pdf;base64," + base64Data;

    try {
      // Step 1: Parse the document to markdown
      System.out.println("Step 1: Parsing document to markdown...");
      String parsedMarkdown = parseDocument(dataUrl);
      System.out.println("✓ Parse complete. Markdown length: " + parsedMarkdown.length() + " chars");

      // Step 2: Extract structured fields
      System.out.println("Step 2: Extracting PA/RF fields...");
      Map<String, Object> extractedData = extractFields(dataUrl);
      System.out.println("✓ Extraction complete. Extracted fields:");
      System.out.println(toJson(extractedData));

      Map<String, Object> result = new HashMap<>();
      result.put("status", "success");
      result.put("parsed_markdown", parsedMarkdown);
      result.put("extracted_fields", extractedData);
      return result;
    } catch (Exception error) {
      System.err.println("Error processing PA/RF form: " + error.getMessage());
      throw error;
    }
  }

  public static void main(String[] args) throws IOException, InterruptedException {
    String testFilePath = args.length > 0 ? args[0] : "sample_pa_form.pdf";
    try {
      Map<String, Object> result = processPriorAuthorizationPARequestFormRF(testFilePath);
      System.out.println("\nFinal result: " + toJson(result));
    } catch (Exception err) {
      System.err.println("Fatal error: " + err.getMessage());
      err.printStackTrace();
      System.exit(1);
    }
  }
}
// This code uses the Extend REST API directly because Extend has no official Go SDK yet.
// It calls https://api.extend.ai endpoints with standard net/http and encoding/json.

package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

const extendAPIBase = "https://api.extend.ai"

// Schema types matching the PA/RF extraction requirements
type ServiceLine struct {
	ServiceCode              *string  `json:"service_code"`
	ServiceDescription       *string  `json:"service_description"`
	Modifiers                *string  `json:"modifiers"`
	PlaceOfService           *string  `json:"place_of_service"`
	QuantityRequested        *float64 `json:"quantity_requested"`
	Charge                   *float64 `json:"charge"`
	RenderingProviderNumber  *string  `json:"rendering_provider_number"`
	RenderingProviderTaxCode *string  `json:"rendering_provider_taxonomy_code"`
}

type PARequestFormData struct {
	DateSigned                    *string        `json:"date_signed"`
	AuthorizationNumber           *string        `json:"authorization_number"`
	ProcessType                   *string        `json:"process_type"`
	MemberName                    *string        `json:"member_name"`
	MemberIdentificationNumber    *string        `json:"member_identification_number"`
	MemberDateOfBirth             *string        `json:"member_date_of_birth"`
	MemberGender                  *string        `json:"member_gender"`
	MemberAddress                 *string        `json:"member_address"`
	BillingProviderName           *string        `json:"billing_provider_name"`
	BillingProviderNumber         *string        `json:"billing_provider_number"`
	BillingProviderAddress        *string        `json:"billing_provider_address"`
	BillingProviderTaxonomyCode   *string        `json:"billing_provider_taxonomy_code"`
	RequestingProviderSignature   *string        `json:"requesting_provider_signature"`
	PresribingProviderName        *string        `json:"prescribing_provider_name"`
	PresribingProviderNPI         *string        `json:"prescribing_provider_npi"`
	PrimaryDiagnosisCode          *string        `json:"primary_diagnosis_code"`
	PrimaryDiagnosisDescription   *string        `json:"primary_diagnosis_description"`
	SecondaryDiagnosisCode        *string        `json:"secondary_diagnosis_code"`
	SecondaryDiagnosisDescription *string        `json:"secondary_diagnosis_description"`
	FirstDateOfTreatment          *string        `json:"first_date_of_treatment"`
	RequestedPAStartDate          *string        `json:"requested_pa_start_date"`
	ServiceLines                  []ServiceLine  `json:"service_lines"`
	TotalCharges                  *float64       `json:"total_charges"`
}

type ParseRunRequest struct {
	File struct {
		URL string `json:"url"`
	} `json:"file"`
	Config struct {
		BlockOptions struct {
			Text struct {
				Agentic struct {
					Enabled bool `json:"enabled"`
				} `json:"agentic"`
			} `json:"text"`
		} `json:"blockOptions"`
		ChunkingStrategy struct {
			Type string `json:"type"`
		} `json:"chunkingStrategy"`
	} `json:"config"`
}

type ParseRunResponse struct {
	Status string `json:"status"`
	Output struct {
		Chunks []struct {
			Content string `json:"content"`
		} `json:"chunks"`
	} `json:"output"`
	ID string `json:"id"`
}

type ExtractRunRequest struct {
	File struct {
		URL string `json:"url"`
	} `json:"file"`
	Config struct {
		Schema map[string]interface{} `json:"schema"`
		BaseProcessor string `json:"baseProcessor"`
		AdvancedOptions struct {
			ReviewAgent struct {
				Enabled bool `json:"enabled"`
			} `json:"reviewAgent"`
			AdvancedMultimodalEnabled bool `json:"advancedMultimodalEnabled"`
		} `json:"advancedOptions"`
	} `json:"config"`
}

type ExtractRunResponse struct {
	Status string `json:"status"`
	Output struct {
		Value PARequestFormData `json:"value"`
	} `json:"output"`
	ID string `json:"id"`
}

type ProcessResult struct {
	Status           string           `json:"status"`
	ParsedMarkdown   string           `json:"parsed_markdown"`
	ExtractedFields  PARequestFormData `json:"extracted_fields"`
	MemberName       *string          `json:"member_name"`
	MemberID         *string          `json:"member_id"`
	AuthNumber       *string          `json:"authorization_number"`
	PrimaryDiagnosis *string          `json:"primary_diagnosis"`
	ServiceCount     int              `json:"service_count"`
	TotalCharges     *float64         `json:"total_charges"`
}

func processPriorAuthorizationPARequestFormRF(filePath string, apiKey string) (*ProcessResult, error) {
	fmt.Printf("Processing PA/RF form: %s\n", filePath)

	// Read file and convert to base64 data URL
	fileBuffer, err := os.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file: %w", err)
	}
	base64Data := base64.StdEncoding.EncodeToString(fileBuffer)
	dataURL := fmt.Sprintf("data:application/pdf;base64,%s", base64Data)

	// Step 1: Parse the document to markdown
	fmt.Println("Step 1: Parsing document to markdown...")
	parseRun, err := createAndPollParseRun(dataURL, apiKey)
	if err != nil {
		return nil, fmt.Errorf("parse failed: %w", err)
	}

	if parseRun.Status != "PROCESSED" {
		return nil, fmt.Errorf("parse failed with status: %s", parseRun.Status)
	}

	var parsedMarkdown string
	for _, chunk := range parseRun.Output.Chunks {
		parsedMarkdown += chunk.Content + "\n\n"
	}
	fmt.Printf("✓ Parse complete. Markdown length: %d chars\n", len(parsedMarkdown))

	// Step 2: Extract structured fields
	fmt.Println("Step 2: Extracting PA/RF fields...")
	extractRun, err := createAndPollExtractRun(dataURL, apiKey)
	if err != nil {
		return nil, fmt.Errorf("extraction failed: %w", err)
	}

	if extractRun.Status != "PROCESSED" {
		return nil, fmt.Errorf("extraction failed with status: %s", extractRun.Status)
	}

	extractedData := extractRun.Output.Value

	// Validate and log results
	fmt.Println("\n✓ Extraction complete. Extracted fields:")
	jsonBytes, _ := json.MarshalIndent(extractedData, "", "  ")
	fmt.Println(string(jsonBytes))

	serviceCount := len(extractedData.ServiceLines)

	result := &ProcessResult{
		Status:           "success",
		ParsedMarkdown:   parsedMarkdown,
		ExtractedFields:  extractedData,
		MemberName:       extractedData.MemberName,
		MemberID:         extractedData.MemberIdentificationNumber,
		AuthNumber:       extractedData.AuthorizationNumber,
		PrimaryDiagnosis: extractedData.PrimaryDiagnosisCode,
		ServiceCount:     serviceCount,
		TotalCharges:     extractedData.TotalCharges,
	}

	return result, nil
}

func createAndPollParseRun(dataURL string, apiKey string) (*ParseRunResponse, error) {
	req := ParseRunRequest{}
	req.File.URL = dataURL
	req.Config.BlockOptions.Text.Agentic.Enabled = true
	req.Config.ChunkingStrategy.Type = "document"

	reqBody, _ := json.Marshal(req)

	httpReq, _ := http.NewRequest("POST", extendAPIBase+"/v1/parse-runs", bytes.NewBuffer(reqBody))
	httpReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
	httpReq.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 300 * time.Second}
	resp, err := client.Do(httpReq)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	var parseResp ParseRunResponse
	json.Unmarshal(body, &parseResp)

	// Poll until PROCESSED
	for parseResp.Status != "PROCESSED" && parseResp.Status != "FAILED" {
		time.Sleep(2 * time.Second)
		pollReq, _ := http.NewRequest("GET", extendAPIBase+"/v1/parse-runs/"+parseResp.ID, nil)
		pollReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
		pollResp, _ := client.Do(pollReq)
		pollBody, _ := io.ReadAll(pollResp.Body)
		pollResp.Body.Close()
		json.Unmarshal(pollBody, &parseResp)
	}

	return &parseResp, nil
}

func createAndPollExtractRun(dataURL string, apiKey string) (*ExtractRunResponse, error) {
	req := ExtractRunRequest{}
	req.File.URL = dataURL
	req.Config.BaseProcessor = "extraction_performance"
	req.Config.AdvancedOptions.ReviewAgent.Enabled = true
	req.Config.AdvancedOptions.AdvancedMultimodalEnabled = true

	// Build schema map
	req.Config.Schema = map[string]interface{}{
		"type": "object",
		"properties": map[string]interface{}{
			"date_signed": map[string]interface{}{
				"type":        "string",
				"description": "The date on which the requesting provider signed the prior authorization form.",
			},
			"authorization_number": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The unique identifier assigned to this prior authorization request.",
			},
			"process_type": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The process or request type code associated with this prior authorization form.",
			},
			"member_name": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The full name of the member or patient.",
			},
			"member_identification_number": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The unique identification number assigned to the member or patient.",
			},
			"member_date_of_birth": map[string]interface{}{
				"type":        "string",
				"description": "The date of birth of the member or patient.",
			},
			"member_gender": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The gender of the member or patient.",
			},
			"member_address": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The complete address of the member or patient.",
			},
			"billing_provider_name": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The full name of the provider or organization submitting the billing.",
			},
			"billing_provider_number": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The unique identification number assigned to the billing provider.",
			},
			"billing_provider_address": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The complete address of the billing provider.",
			},
			"billing_provider_taxonomy_code": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The taxonomy code representing the specialty of the billing provider.",
			},
			"requesting_provider_signature": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The name or signature of the provider submitting the request.",
			},
			"prescribing_provider_name": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The full name of the prescribing, referring, or ordering provider.",
			},
			"prescribing_provider_npi": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The National Provider Identifier (NPI) for the prescribing provider.",
			},
			"primary_diagnosis_code": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "The primary diagnosis code (such as ICD-10).",
			},
			"primary_diagnosis_description": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "A textual description of the primary diagnosis.",
			},
			"secondary_diagnosis_code": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "An additional diagnosis code (such as ICD-10).",
			},
			"secondary_diagnosis_description": map[string]interface{}{
				"type":        ["string", "null"],
				"description": "A textual description of the secondary diagnosis.",
			},
			"first_date_of_treatment": map[string]interface{}{
				"type":        "string",
				"description": "The first date on which the requested service is expected to be provided.",
			},
			"requested_pa_start_date": map[string]interface{}{
				"type":        "string",
				"description": "The requested start date for the prior authorization period.",
			},
			"service_lines": map[string]interface{}{
				"type": "array",
				"items": map[string]interface{}{
					"type": "object",
					"properties": map[string]interface{}{
						"service_code": map[string]interface{}{
							"type":        ["string", "null"],
							"description": "The procedure or service code (such as CPT or HCPCS).",
						},
						"service_description": map[string]interface{}{
							"type":        ["string", "null"],
							"description": "A textual description of the service.",
						},
						"modifiers": map[string]interface{}{
							"type":        ["string", "null"],
							"description": "Any modifiers associated with the service code.",
						},
						"place_of_service": map[string]interface{}{
							"type":        ["string", "null"],
							"description": "The place of service code.",
						},
						"quantity_requested": map[string]interface{}{
							"type":        ["number", "null"],
							"description": "The number of units or sessions requested.",
						},
						"charge": map[string]interface{}{
							"type":        ["number", "null"],
							"description": "The monetary charge for this service line.",
						},
						"rendering_provider_number": map[string]interface{}{
							"type":        ["string", "null"],
							"description": "The rendering provider number.",
						},
						"rendering_provider_taxonomy_code": map[string]interface{}{
							"type":        ["string", "null"],
							"description": "The taxonomy code for the rendering provider.",
						},
					},
				},
				"description": "The individual services, procedures, or items being requested.",
			},
			"total_charges": map[string]interface{}{
				"type":        ["number", "null"],
				"description": "The total amount of charges for all requested services.",
			},
		},
	}

	reqBody, _ := json.Marshal(req)

	httpReq, _ := http.NewRequest("POST", extendAPIBase+"/v1/extract-runs", bytes.NewBuffer(reqBody))
	httpReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
	httpReq.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 300 * time.Second}
	resp, err := client.Do(httpReq)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	var extractResp ExtractRunResponse
	json.Unmarshal(body, &extractResp)

	// Poll until PROCESSED
	for extractResp.Status != "PROCESSED" && extractResp.Status != "FAILED" {
		time.Sleep(2 * time.Second)
		pollReq, _ := http.NewRequest("GET", extendAPIBase+"/v1/extract-runs/"+extractResp.ID, nil)
		pollReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
		pollResp, _ := client.Do(pollReq)
		pollBody, _ := io.ReadAll(pollResp.Body)
		pollResp.Body.Close()
		json.Unmarshal(pollBody, &extractResp)
	}

	return &extractResp, nil
}

func main() {
	filePath := flag.String("file", "sample_pa_form.pdf", "Path to PA form PDF")
	flag.Parse()

	apiKey := os.Getenv("EXTEND_API_KEY")
	if apiKey == "" {
		fmt.Fprintf(os.Stderr, "Error: EXTEND_API_KEY environment variable not set\n")
		os.Exit(1)
	}

	result, err := processPriorAuthorizationPARequestFormRF(*filePath, apiKey)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("\nFinal result:")
	jsonBytes, _ := json.MarshalIndent(result, "", "  ")
	fmt.Println(string(jsonBytes))
}
// Deploy the "Prior Authorization (PA) Request Form (RF)" pipeline to YOUR Extend account.
//
// The workflow below is fully self-contained — every EXTRACT/CLASSIFY/SPLIT
// step carries its extractor/classifier/splitter config INLINE, so this is a
// single API call. No processors to create or wire up beforehand.
// Idempotent: the created workflow id is cached in .extend/prior-authorization-request-form.json,
// so re-running updates the existing workflow instead of duplicating it.
//
// Usage:
//   export EXTEND_API_KEY=sk_...   (from https://dashboard.extend.ai → API Keys)
//   npx tsx provision.ts
//
// Generated by doc1 (template: prior-authorization-request-form).

import fs from "node:fs";
import path from "node:path";

const API = "https://api.extend.ai";
const VERSION = "2026-02-09";
const API_KEY = process.env.EXTEND_API_KEY;
if (!API_KEY) { console.error("Set EXTEND_API_KEY first."); process.exit(1); }

const STATE_DIR = path.join(process.cwd(), ".extend");
const STATE_FILE = path.join(STATE_DIR, "prior-authorization-request-form.json");

type State = { workflowId?: string };
const state: State = fs.existsSync(STATE_FILE)
  ? JSON.parse(fs.readFileSync(STATE_FILE, "utf8"))
  : {};
function saveState() {
  fs.mkdirSync(STATE_DIR, { recursive: true });
  fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
}

async function api(method: string, pathName: string, body?: unknown) {
  const res = await fetch(API + pathName, {
    method,
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "x-extend-api-version": VERSION,
      ...(body ? { "Content-Type": "application/json" } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(`${method} ${pathName} failed (${res.status}): ${JSON.stringify(data).slice(0, 300)}`);
  return data;
}

// ── Workflow definition — extractor/classifier/splitter configs inline ──────
const WORKFLOW = {
  "name": "Prior Authorization (PA) Request Form (RF) Processing Pipeline",
  "steps": [
    {
      "name": "startTrigger1",
      "type": "TRIGGER",
      "next": [
        {
          "step": "parse1"
        }
      ]
    },
    {
      "name": "parse1",
      "type": "PARSE",
      "config": {
        "parseConfig": {
          "blockOptions": {
            "text": {
              "agentic": {
                "enabled": true
              }
            }
          },
          "chunkingStrategy": {
            "type": "document"
          }
        }
      },
      "next": [
        {
          "step": "extraction2"
        }
      ]
    },
    {
      "name": "extraction2",
      "type": "EXTRACT",
      "config": {
        "extractorConfig": {
          "schema": {
            "type": "object",
            "required": [
              "date_signed",
              "member_name",
              "process_type",
              "member_gender",
              "service_lines",
              "total_charges",
              "member_address",
              "authorization_number",
              "member_date_of_birth",
              "billing_provider_name",
              "primary_diagnosis_code",
              "billing_provider_number",
              "first_date_of_treatment",
              "requested_pa_start_date",
              "billing_provider_address",
              "prescribing_provider_npi",
              "secondary_diagnosis_code",
              "prescribing_provider_name",
              "member_identification_number",
              "primary_diagnosis_description",
              "requesting_provider_signature",
              "billing_provider_taxonomy_code",
              "secondary_diagnosis_description"
            ],
            "properties": {
              "date_signed": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request.",
                "extend:type": "date"
              },
              "member_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service."
              },
              "process_type": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar."
              },
              "member_gender": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text."
              },
              "service_lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "charge",
                    "modifiers",
                    "service_code",
                    "place_of_service",
                    "quantity_requested",
                    "service_description",
                    "rendering_provider_number",
                    "rendering_provider_taxonomy_code"
                  ],
                  "properties": {
                    "charge": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "The monetary charge associated with this service line, representing the requested reimbursement for this specific service."
                    },
                    "modifiers": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes."
                    },
                    "service_code": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested."
                    },
                    "place_of_service": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code."
                    },
                    "quantity_requested": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar."
                    },
                    "service_description": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details."
                    },
                    "rendering_provider_number": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar."
                    },
                    "rendering_provider_taxonomy_code": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The taxonomy code for the provider rendering this service line, indicating their specialty or classification."
                    }
                  },
                  "additionalProperties": false
                },
                "description": "The individual services, procedures, or items being requested for prior authorization. Each entry represents a distinct service line with associated codes, descriptions, and charges. These may be presented in a table or list format and can vary in number and structure."
              },
              "total_charges": {
                "type": "object",
                "required": [
                  "amount",
                  "iso_4217_currency_code"
                ],
                "properties": {
                  "amount": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "iso_4217_currency_code": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "description": "The total amount of charges associated with all requested services on this prior authorization form. This is the sum of all line item charges and represents the total financial request.",
                "extend:type": "currency",
                "additionalProperties": false
              },
              "member_address": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The complete address of the member or patient, including street, city, state, and ZIP code."
              },
              "authorization_number": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The unique identifier assigned to this prior authorization request. This number is used to track and reference the authorization throughout the review and claims process. May be labeled as 'PA Number', 'Authorization #', or similar, and can include letters, numbers, or special characters."
              },
              "member_date_of_birth": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The date of birth of the member or patient. Used to verify identity and eligibility. May appear in various date formats.",
                "extend:type": "date"
              },
              "billing_provider_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The full name of the provider or organization submitting the billing for this authorization request. This is the entity responsible for providing the service and requesting payment."
              },
              "primary_diagnosis_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The primary diagnosis code (such as ICD-10) that justifies the need for the requested service. This is the main clinical reason for the authorization request."
              },
              "billing_provider_number": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The unique identification number assigned to the billing provider by the payer or regulatory body. May be labeled as 'Provider Number', 'Billing Provider ID', or similar."
              },
              "first_date_of_treatment": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The first date on which the requested service or treatment is expected to be provided. May be labeled as 'First Date of Treatment' or similar.",
                "extend:type": "date"
              },
              "requested_pa_start_date": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The requested start date for the prior authorization period. This is when the provider wishes the authorization to begin.",
                "extend:type": "date"
              },
              "billing_provider_address": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The complete address of the billing provider, including street, city, state, and ZIP code. This identifies the location of the provider submitting the request."
              },
              "prescribing_provider_npi": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The National Provider Identifier (NPI) for the prescribing, referring, or ordering provider. This is a unique 10-digit identification number for healthcare providers in the United States."
              },
              "secondary_diagnosis_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "An additional diagnosis code (such as ICD-10) relevant to the request. This may support the medical necessity of the service."
              },
              "prescribing_provider_name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The full name of the provider who is prescribing, referring, or ordering the service for which prior authorization is requested. May be labeled as 'Prescribing Provider', 'Referring Provider', or 'Ordering Provider'."
              },
              "member_identification_number": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The unique identification number assigned to the member or patient for whom the prior authorization is being requested. May be labeled as 'Member ID', 'Recipient Number', or similar."
              },
              "primary_diagnosis_description": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "A textual description of the primary diagnosis associated with the request. This provides additional clinical context beyond the code."
              },
              "requesting_provider_signature": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The name or signature of the provider submitting the prior authorization request. This may be a handwritten or electronic signature, or simply the provider's printed name."
              },
              "billing_provider_taxonomy_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The taxonomy code representing the specialty or classification of the billing provider. This code helps identify the provider's area of practice."
              },
              "secondary_diagnosis_description": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "A textual description of the secondary diagnosis, if provided."
              }
            },
            "additionalProperties": false
          },
          "baseProcessor": "extraction_performance",
          "advancedOptions": {
            "reviewAgent": {
              "enabled": true
            },
            "advancedMultimodalEnabled": true
          }
        }
      }
    }
  ]
};

async function main() {
  console.log(`Deploying "${WORKFLOW.name}"…`);

  if (state.workflowId) {
    console.log(`✓ workflow already provisioned (${state.workflowId}) — updating steps`);
    await api("POST", `/workflows/${state.workflowId}`, { steps: WORKFLOW.steps });
  } else {
    // Reuse an existing workflow with the same name if one exists (e.g. a
    // previous run's state file was lost) instead of creating a duplicate.
    try {
      const list = await api("GET", `/workflows?name=${encodeURIComponent(WORKFLOW.name)}`);
      const items = (list.data ?? list.items ?? []) as Array<{ name?: string; id?: string }>;
      const existing = items.find((x) => x.name === WORKFLOW.name);
      if (existing?.id) {
        state.workflowId = existing.id; saveState();
        console.log(`✓ workflow "${WORKFLOW.name}" found in your account (${existing.id}) — updating steps`);
        await api("POST", `/workflows/${existing.id}`, { steps: WORKFLOW.steps });
      }
    } catch { /* lookup is best-effort; fall through to create */ }

    if (!state.workflowId) {
      const created = await api("POST", "/workflows", WORKFLOW);
      const wfId = created.id ?? created.workflow?.id;
      if (!wfId) throw new Error("Could not read created workflow id from response");
      state.workflowId = wfId; saveState();
      console.log(`+ created workflow (${wfId})`);
    }
  }

  // Deploy the current draft as a new version so the workflow is runnable —
  // best-effort: some accounts/plans may not require this explicit step.
  await api("POST", `/workflows/${state.workflowId}/versions`, {}).catch(() => {});

  console.log("\nDone. Run documents through it with:");
  console.log(`  POST ${API}/workflow_runs  { workflow: { id: "${state.workflowId}" }, file: { url: "https://…" } }`);
  console.log("Or open the workflow in the Extend dashboard to review and deploy it.");
}

main().catch((e) => { console.error(e.message ?? e); process.exit(1); });
import os
import json
import sys
from pathlib import Path
from extend_ai import Extend

API_KEY = os.environ.get("EXTEND_API_KEY")
if not API_KEY:
    print("Set EXTEND_API_KEY first.", file=sys.stderr)
    sys.exit(1)

client = Extend(token=API_KEY)

STATE_DIR = Path.cwd() / ".extend"
STATE_FILE = STATE_DIR / "prior-authorization-request-form.json"


def load_state() -> dict:
    if STATE_FILE.exists():
        with open(STATE_FILE, "r") as f:
            return json.load(f)
    return {}


def save_state(state: dict) -> None:
    STATE_DIR.mkdir(parents=True, exist_ok=True)
    with open(STATE_FILE, "w") as f:
        json.dump(state, f, indent=2)


WORKFLOW = {
    "name": "Prior Authorization (PA) Request Form (RF) Processing Pipeline",
    "steps": [
        {
            "name": "startTrigger1",
            "type": "TRIGGER",
            "next": [{"step": "parse1"}],
        },
        {
            "name": "parse1",
            "type": "PARSE",
            "config": {
                "parseConfig": {
                    "blockOptions": {"text": {"agentic": {"enabled": True}}},
                    "chunkingStrategy": {"type": "document"},
                }
            },
            "next": [{"step": "extraction2"}],
        },
        {
            "name": "extraction2",
            "type": "EXTRACT",
            "config": {
                "extractorConfig": {
                    "schema": {
                        "type": "object",
                        "properties": {
                            "date_signed": {
                                "type": ["string", "null"],
                                "extend:type": "date",
                                "description": "The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request.",
                            },
                            "member_name": {
                                "type": ["string", "null"],
                                "description": "The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service.",
                            },
                            "process_type": {
                                "type": ["string", "null"],
                                "description": "The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar.",
                            },
                            "member_gender": {
                                "type": ["string", "null"],
                                "description": "The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text.",
                            },
                            "service_lines": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "charge": {
                                            "type": ["number", "null"],
                                            "description": "The monetary charge associated with this service line, representing the requested reimbursement for this specific service.",
                                        },
                                        "modifiers": {
                                            "type": ["string", "null"],
                                            "description": "Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes.",
                                        },
                                        "service_code": {
                                            "type": ["string", "null"],
                                            "description": "The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested.",
                                        },
                                        "place_of_service": {
                                            "type": ["string", "null"],
                                            "description": "The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code.",
                                        },
                                        "quantity_requested": {
                                            "type": ["number", "null"],
                                            "description": "The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar.",
                                        },
                                        "service_description": {
                                            "type": ["string", "null"],
                                            "description": "A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details.",
                                        },
                                        "rendering_provider_number": {
                                            "type": ["string", "null"],
                                            "description": "The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar.",
                                        },
                                        "rendering_provider_taxonomy_code": {
                                            "type": ["string", "null"],
                                            "description": "The taxonomy code for the provider rendering this service line, indicating their specialty or classification.",
                                        },
                                    },
                                    "additionalProperties": False,
                                    "required": [
                                        "charge",
                                        "modifiers",
                                        "service_code",
                                        "place_of_service",
                                        "quantity_requested",
                                        "service_description",
                                        "rendering_provider_number",
                                        "rendering_provider_taxonomy_code",
                                    ],
                                },
                                "description": "The individual services, procedures, or items being requested for prior authorization. Each entry represents a distinct service line with associated codes, descriptions, and charges. These may be presented in a table or list format and can vary in number and structure.",
                            },
                            "total_charges": {
                                "type": "object",
                                "properties": {
                                    "amount": {"type": ["number", "null"]},
                                    "iso_4217_currency_code": {"type": ["string", "null"]},
                                },
                                "additionalProperties": False,
                                "required": ["amount", "iso_4217_currency_code"],
                                "extend:type": "currency",
                                "description": "The total amount of charges associated with all requested services on this prior authorization form. This is the sum of all line item charges and represents the total financial request.",
                            },
                            "member_address": {
                                "type": ["string", "null"],
                                "description": "The complete address of the member or patient, including street, city, state, and ZIP code.",
                            },
                            "authorization_number": {
                                "type": ["string", "null"],
                                "description": "The unique identifier assigned to this prior authorization request. This number is used to track and reference the authorization throughout the review and claims process. May be labeled as 'PA Number', 'Authorization #', or similar, and can include letters, numbers, or special characters.",
                            },
                            "member_date_of_birth": {
                                "type": ["string", "null"],
                                "extend:type": "date",
                                "description": "The date of birth of the member or patient. Used to verify identity and eligibility. May appear in various date formats.",
                            },
                            "billing_provider_name": {
                                "type": ["string", "null"],
                                "description": "The full name of the provider or organization submitting the billing for this authorization request. This is the entity responsible for providing the service and requesting payment.",
                            },
                            "primary_diagnosis_code": {
                                "type": ["string", "null"],
                                "description": "The primary diagnosis code (such as ICD-10) that justifies the need for the requested service. This is the main clinical reason for the authorization request.",
                            },
                            "billing_provider_number": {
                                "type": ["string", "null"],
                                "description": "The unique identification number assigned to the billing provider by the payer or regulatory body. May be labeled as 'Provider Number', 'Billing Provider ID', or similar.",
                            },
                            "first_date_of_treatment": {
                                "type": ["string", "null"],
                                "extend:type": "date",
                                "description": "The first date on which the requested service or treatment is expected to be provided. May be labeled as 'First Date of Treatment' or similar.",
                            },
                            "requested_pa_start_date": {
                                "type": ["string", "null"],
                                "extend:type": "date",
                                "description": "The requested start date for the prior authorization period. This is when the provider wishes the authorization to begin.",
                            },
                            "billing_provider_address": {
                                "type": ["string", "null"],
                                "description": "The complete address of the billing provider, including street, city, state, and ZIP code. This identifies the location of the provider submitting the request.",
                            },
                            "prescribing_provider_npi": {
                                "type": ["string", "null"],
                                "description": "The National Provider Identifier (NPI) for the prescribing, referring, or ordering provider. This is a unique 10-digit identification number for healthcare providers in the United States.",
                            },
                            "secondary_diagnosis_code": {
                                "type": ["string", "null"],
                                "description": "An additional diagnosis code (such as ICD-10) relevant to the request. This may support the medical necessity of the service.",
                            },
                            "prescribing_provider_name": {
                                "type": ["string", "null"],
                                "description": "The full name of the provider who is prescribing, referring, or ordering the service for which prior authorization is requested. May be labeled as 'Prescribing Provider', 'Referring Provider', or 'Ordering Provider'.",
                            },
                            "member_identification_number": {
                                "type": ["string", "null"],
                                "description": "The unique identification number assigned to the member or patient for whom the prior authorization is being requested. May be labeled as 'Member ID', 'Recipient Number', or similar.",
                            },
                            "primary_diagnosis_description": {
                                "type": ["string", "null"],
                                "description": "A textual description of the primary diagnosis associated with the request. This provides additional clinical context beyond the code.",
                            },
                            "requesting_provider_signature": {
                                "type": ["string", "null"],
                                "description": "The name or signature of the provider submitting the prior authorization request. This may be a handwritten or electronic signature, or simply the provider's printed name.",
                            },
                            "billing_provider_taxonomy_code": {
                                "type": ["string", "null"],
                                "description": "The taxonomy code representing the specialty or classification of the billing provider. This code helps identify the provider's area of practice.",
                            },
                            "secondary_diagnosis_description": {
                                "type": ["string", "null"],
                                "description": "A textual description of the secondary diagnosis, if provided.",
                            },
                        },
                        "required": [
                            "date_signed",
                            "member_name",
                            "process_type",
                            "member_gender",
                            "service_lines",
                            "total_charges",
                            "member_address",
                            "authorization_number",
                            "member_date_of_birth",
                            "billing_provider_name",
                            "primary_diagnosis_code",
                            "billing_provider_number",
                            "first_date_of_treatment",
                            "requested_pa_start_date",
                            "billing_provider_address",
                            "prescribing_provider_npi",
                            "secondary_diagnosis_code",
                            "prescribing_provider_name",
                            "member_identification_number",
                            "primary_diagnosis_description",
                            "requesting_provider_signature",
                            "billing_provider_taxonomy_code",
                            "secondary_diagnosis_description",
                        ],
                        "additionalProperties": False,
                    },
                    "baseProcessor": "extraction_performance",
                    "advancedOptions": {
                        "reviewAgent": {"enabled": True},
                        "advancedMultimodalEnabled": True,
                    },
                }
            },
        },
    ],
}


def main() -> None:
    state = load_state()
    print(f'Deploying "{WORKFLOW["name"]}…"')

    if state.get("workflowId"):
        workflow_id = state["workflowId"]
        print(f"✓ workflow already provisioned ({workflow_id}) — updating steps")
        client.workflows.update(id=workflow_id, steps=WORKFLOW["steps"])
    else:
        existing_id = None
        try:
            workflows = client.workflows.list(name=WORKFLOW["name"])
            items = workflows.data if hasattr(workflows, "data") else (workflows.items if hasattr(workflows, "items") else [])
            for item in items:
                if item.name == WORKFLOW["name"]:
                    existing_id = item.id
                    break
        except Exception:
            pass

        if existing_id:
            state["workflowId"] = existing_id
            save_state(state)
            print(f'✓ workflow "{WORKFLOW["name"]}" found in your account ({existing_id}) — updating steps')
            client.workflows.update(id=existing_id, steps=WORKFLOW["steps"])
        else:
            created = client.workflows.create(**WORKFLOW)
            workflow_id = created.id
            if not workflow_id:
                raise RuntimeError("Could not read created workflow id from response")
            state["workflowId"] = workflow_id
            save_state(state)
            print(f"+ created workflow ({workflow_id})")

    try:
        client.workflows.create_version(id=state["workflowId"])
    except Exception:
        pass

    print("\nDone. Run documents through it with:")
    print(f'  POST https://api.extend.ai/workflow_runs  {{ "workflow": {{ "id": "{state["workflowId"]}" }}, "file": {{ "url": "https://…" }} }}')
    print("Or open the workflow in the Extend dashboard to review and deploy it.")


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print(str(e), file=sys.stderr)
        sys.exit(1)
// This code uses Extend's REST API directly because Extend has no official Java SDK yet.
// It deploys the "Prior Authorization (PA) Request Form (RF)" pipeline to your Extend account.

import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ProvisionsPA {
    private static final String API = "https://api.extend.ai";
    private static final String VERSION = "2026-02-09";
    private static final String API_KEY = System.getenv("EXTEND_API_KEY");
    private static final Path STATE_DIR = Paths.get(System.getProperty("user.dir"), ".extend");
    private static final Path STATE_FILE = STATE_DIR.resolve("prior-authorization-request-form.json");
    private static final HttpClient HTTP = HttpClient.newHttpClient();

    static class State {
        String workflowId;
    }

    private static State state = new State();

    public static void main(String[] args) throws Exception {
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("Set EXTEND_API_KEY first.");
            System.exit(1);
        }

        loadState();

        Map<String, Object> workflow = buildWorkflow();
        System.out.println("Deploying \"" + (String) workflow.get("name") + "\"…");

        if (state.workflowId != null && !state.workflowId.isEmpty()) {
            System.out.println("✓ workflow already provisioned (" + state.workflowId + ") — updating steps");
            Map<String, Object> updateBody = new LinkedHashMap<>();
            updateBody.put("steps", workflow.get("steps"));
            api("POST", "/workflows/" + state.workflowId, updateBody);
        } else {
            try {
                String workflowName = (String) workflow.get("name");
                String encoded = URLEncoder.encode(workflowName, StandardCharsets.UTF_8);
                Map<String, Object> list = api("GET", "/workflows?name=" + encoded, null);
                List<?> items = (List<?>) (list.getOrDefault("data", list.getOrDefault("items", List.of())));
                for (Object item : items) {
                    if (item instanceof Map) {
                        Map<?, ?> itemMap = (Map<?, ?>) item;
                        if (workflowName.equals(itemMap.get("name")) && itemMap.get("id") != null) {
                            state.workflowId = (String) itemMap.get("id");
                            saveState();
                            System.out.println("✓ workflow \"" + workflowName + "\" found in your account (" + state.workflowId + ") — updating steps");
                            Map<String, Object> updateBody = new LinkedHashMap<>();
                            updateBody.put("steps", workflow.get("steps"));
                            api("POST", "/workflows/" + state.workflowId, updateBody);
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                // lookup is best-effort; fall through to create
            }

            if (state.workflowId == null || state.workflowId.isEmpty()) {
                Map<String, Object> created = api("POST", "/workflows", workflow);
                String wfId = (String) created.getOrDefault("id", null);
                if (wfId == null) {
                    Map<?, ?> workflowObj = (Map<?, ?>) created.get("workflow");
                    if (workflowObj != null) {
                        wfId = (String) workflowObj.get("id");
                    }
                }
                if (wfId == null) {
                    throw new RuntimeException("Could not read created workflow id from response");
                }
                state.workflowId = wfId;
                saveState();
                System.out.println("+ created workflow (" + wfId + ")");
            }
        }

        try {
            api("POST", "/workflows/" + state.workflowId + "/versions", new LinkedHashMap<>());
        } catch (Exception e) {
            // best-effort: some accounts/plans may not require this explicit step
        }

        System.out.println("\nDone. Run documents through it with:");
        System.out.println("  POST " + API + "/workflow_runs  { workflow: { id: \"" + state.workflowId + "\" }, file: { url: \"https://…\" } }");
        System.out.println("Or open the workflow in the Extend dashboard to review and deploy it.");
    }

    private static void loadState() throws IOException {
        if (Files.exists(STATE_FILE)) {
            String json = Files.readString(STATE_FILE);
            state = parseStateJson(json);
        }
    }

    private static void saveState() throws IOException {
        Files.createDirectories(STATE_DIR);
        String json = toJson(state);
        Files.writeString(STATE_FILE, json);
    }

    private static Map<String, Object> api(String method, String pathName, Map<String, Object> body) throws Exception {
        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(API + pathName))
                .method(method, body != null ? HttpRequest.BodyPublishers.ofString(toJson(body)) : HttpRequest.BodyPublishers.noBody())
                .header("Authorization", "Bearer " + API_KEY)
                .header("x-extend-api-version", VERSION);

        if (body != null) {
            builder.header("Content-Type", "application/json");
        }

        HttpRequest request = builder.build();
        HttpResponse<String> response = HTTP.send(request, HttpResponse.BodyHandlers.ofString());

        Map<String, Object> data = new LinkedHashMap<>();
        try {
            data = parseJson(response.body());
        } catch (Exception e) {
            // ignore parse errors
        }

        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            String errorMsg = toJson(data);
            if (errorMsg.length() > 300) {
                errorMsg = errorMsg.substring(0, 300);
            }
            throw new RuntimeException(method + " " + pathName + " failed (" + response.statusCode() + "): " + errorMsg);
        }

        return data;
    }

    private static Map<String, Object> buildWorkflow() {
        Map<String, Object> workflow = new LinkedHashMap<>();
        workflow.put("name", "Prior Authorization (PA) Request Form (RF) Processing Pipeline");

        List<Map<String, Object>> steps = List.of(
                buildTriggerStep(),
                buildParseStep(),
                buildExtractionStep()
        );
        workflow.put("steps", steps);

        return workflow;
    }

    private static Map<String, Object> buildTriggerStep() {
        Map<String, Object> step = new LinkedHashMap<>();
        step.put("name", "startTrigger1");
        step.put("type", "TRIGGER");
        step.put("next", List.of(Map.of("step", "parse1")));
        return step;
    }

    private static Map<String, Object> buildParseStep() {
        Map<String, Object> step = new LinkedHashMap<>();
        step.put("name", "parse1");
        step.put("type", "PARSE");

        Map<String, Object> config = new LinkedHashMap<>();
        Map<String, Object> parseConfig = new LinkedHashMap<>();
        Map<String, Object> blockOptions = new LinkedHashMap<>();
        Map<String, Object> textOptions = new LinkedHashMap<>();
        Map<String, Object> agenticOptions = new LinkedHashMap<>();
        agenticOptions.put("enabled", true);
        textOptions.put("agentic", agenticOptions);
        blockOptions.put("text", textOptions);
        parseConfig.put("blockOptions", blockOptions);
        parseConfig.put("chunkingStrategy", Map.of("type", "document"));
        config.put("parseConfig", parseConfig);
        step.put("config", config);

        step.put("next", List.of(Map.of("step", "extraction2")));
        return step;
    }

    private static Map<String, Object> buildExtractionStep() {
        Map<String, Object> step = new LinkedHashMap<>();
        step.put("name", "extraction2");
        step.put("type", "EXTRACT");

        Map<String, Object> config = new LinkedHashMap<>();
        Map<String, Object> extractorConfig = new LinkedHashMap<>();
        extractorConfig.put("schema", buildSchema());
        extractorConfig.put("baseProcessor", "extraction_performance");

        Map<String, Object> advancedOptions = new LinkedHashMap<>();
        Map<String, Object> reviewAgent = new LinkedHashMap<>();
        reviewAgent.put("enabled", true);
        advancedOptions.put("reviewAgent", reviewAgent);
        advancedOptions.put("advancedMultimodalEnabled", true);
        extractorConfig.put("advancedOptions", advancedOptions);

        config.put("extractorConfig", extractorConfig);
        step.put("config", config);

        return step;
    }

    private static Map<String, Object> buildSchema() {
        Map<String, Object> schema = new LinkedHashMap<>();
        schema.put("type", "object");

        Map<String, Object> properties = new LinkedHashMap<>();
        properties.put("date_signed", buildDateProperty("The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request."));
        properties.put("member_name", buildStringProperty("The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service."));
        properties.put("process_type", buildStringProperty("The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar."));
        properties.put("member_gender", buildStringProperty("The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text."));
        properties.put("service_lines", buildServiceLinesProperty());
        properties.put("total_charges", buildCurrencyProperty("The total amount of charges associated with all requested services on this prior authorization form. This is the sum of all line item charges and represents the total financial request."));
        properties.put("member_address", buildStringProperty("The complete address of the member or patient, including street, city, state, and ZIP code."));
        properties.put("authorization_number", buildStringProperty("The unique identifier assigned to this prior authorization request. This number is used to track and reference the authorization throughout the review and claims process. May be labeled as 'PA Number', 'Authorization #', or similar, and can include letters, numbers, or special characters."));
        properties.put("member_date_of_birth", buildDateProperty("The date of birth of the member or patient. Used to verify identity and eligibility. May appear in various date formats."));
        properties.put("billing_provider_name", buildStringProperty("The full name of the provider or organization submitting the billing for this authorization request. This is the entity responsible for providing the service and requesting payment."));
        properties.put("primary_diagnosis_code", buildStringProperty("The primary diagnosis code (such as ICD-10) that justifies the need for the requested service. This is the main clinical reason for the authorization request."));
        properties.put("billing_provider_number", buildStringProperty("The unique identification number assigned to the billing provider by the payer or regulatory body. May be labeled as 'Provider Number', 'Billing Provider ID', or similar."));
        properties.put("first_date_of_treatment", buildDateProperty("The first date on which the requested service or treatment is expected to be provided. May be labeled as 'First Date of Treatment' or similar."));
        properties.put("requested_pa_start_date", buildDateProperty("The requested start date for the prior authorization period. This is when the provider wishes the authorization to begin."));
        properties.put("billing_provider_address", buildStringProperty("The complete address of the billing provider, including street, city, state, and ZIP code. This identifies the location of the provider submitting the request."));
        properties.put("prescribing_provider_npi", buildStringProperty("The National Provider Identifier (NPI) for the prescribing, referring, or ordering provider. This is a unique 10-digit identification number for healthcare providers in the United States."));
        properties.put("secondary_diagnosis_code", buildStringProperty("An additional diagnosis code (such as ICD-10) relevant to the request. This may support the medical necessity of the service."));
        properties.put("prescribing_provider_name", buildStringProperty("The full name of the provider who is prescribing, referring, or ordering the service for which prior authorization is requested. May be labeled as 'Prescribing Provider', 'Referring Provider', or 'Ordering Provider'."));
        properties.put("member_identification_number", buildStringProperty("The unique identification number assigned to the member or patient for whom the prior authorization is being requested. May be labeled as 'Member ID', 'Recipient Number', or similar."));
        properties.put("primary_diagnosis_description", buildStringProperty("A textual description of the primary diagnosis associated with the request. This provides additional clinical context beyond the code."));
        properties.put("requesting_provider_signature", buildStringProperty("The name or signature of the provider submitting the prior authorization request. This may be a handwritten or electronic signature, or simply the provider's printed name."));
        properties.put("billing_provider_taxonomy_code", buildStringProperty("The taxonomy code representing the specialty or classification of the billing provider. This code helps identify the provider's area of practice."));
        properties.put("secondary_diagnosis_description", buildStringProperty("A textual description of the secondary diagnosis, if provided."));

        schema.put("properties", properties);

        List<String> required = List.of(
                "date_signed", "member_name", "process_type", "member_gender", "service_lines",
                "total_charges", "member_address", "authorization_number", "member_date_of_birth",
                "billing_provider_name", "primary_diagnosis_code", "billing_provider_number",
                "first_date_of_treatment", "requested_pa_start_date", "billing_provider_address",
                "prescribing_provider_npi", "secondary_diagnosis_code", "prescribing_provider_name",
                "member_identification_number", "primary_diagnosis_description", "requesting_provider_signature",
                "billing_provider_taxonomy_code", "secondary_diagnosis_description"
        );
        schema.put("required", required);
        schema.put("additionalProperties", false);

        return schema;
    }

    private static Map<String, Object> buildStringProperty(String description) {
        Map<String, Object> prop = new LinkedHashMap<>();
        prop.put("type", List.of("string", "null"));
        prop.put("description", description);
        return prop;
    }

    private static Map<String, Object> buildDateProperty(String description) {
        Map<String, Object> prop = new LinkedHashMap<>();
        prop.put("type", List.of("string", "null"));
        prop.put("extend:type", "date");
        prop.put("description", description);
        return prop;
    }

    private static Map<String, Object> buildNumberProperty(String description) {
        Map<String, Object> prop = new LinkedHashMap<>();
        prop.put("type", List.of("number", "null"));
        prop.put("description", description);
        return prop;
    }

    private static Map<String, Object> buildServiceLinesProperty() {
        Map<String, Object> prop = new LinkedHashMap<>();
        prop.put("type", "array");

        Map<String, Object> itemSchema = new LinkedHashMap<>();
        itemSchema.put("type", "object");

        Map<String, Object> itemProperties = new LinkedHashMap<>();
        itemProperties.put("charge", buildNumberProperty("The monetary charge associated with this service line, representing the requested reimbursement for this specific service."));
        itemProperties.put("modifiers", buildStringProperty("Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes."));
        itemProperties.put("service_code", buildStringProperty("The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested."));
        itemProperties.put("place_of_service", buildStringProperty("The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code."));
        itemProperties.put("quantity_requested", buildNumberProperty("The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar."));
        itemProperties.put("service_description", buildStringProperty("A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details."));
        itemProperties.put("rendering_provider_number", buildStringProperty("The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar."));
        itemProperties.put("rendering_provider_taxonomy_code", buildStringProperty("The taxonomy code for the provider rendering this service line, indicating their specialty or classification."));

        itemSchema.put("properties", itemProperties);
        itemSchema.put("additionalProperties", false);
        itemSchema.put("required", List.of("charge", "modifiers", "service_code", "place_of_service", "quantity_requested", "service_description", "rendering_provider_number", "rendering_provider_taxonomy_code"));

        prop.put("items", itemSchema);
        prop.put("description", "The individual services, procedures, or items being requested for prior authorization. Each entry represents a distinct service line with associated codes, descriptions, and charges. These may be presented in a table or list format and can vary in number and structure.");

        return prop;
    }

    private static Map<String, Object> buildCurrencyProperty(String description) {
        Map<String, Object> prop = new LinkedHashMap<>();
        prop.put("type", "object");

        Map<String, Object> currencyProperties = new LinkedHashMap<>();
        currencyProperties.put("amount", buildNumberProperty(""));
        currencyProperties.put("iso_4217_currency_code", buildStringProperty(""));

        prop.put("properties", currencyProperties);
        prop.put("additionalProperties", false);
        prop.put("required", List.of("amount", "iso_4217_currency_code"));
        prop.put("extend:type", "currency");
        prop.put("description", description);

        return prop;
    }

    private static String toJson(Object obj) {
        if (obj == null) return "null";
        if (obj instanceof String) return "\"" + escapeJson((String) obj) + "\"";
        if (obj instanceof Number) return obj.toString();
        if (obj instanceof Boolean) return obj.toString();
        if (obj instanceof List) {
            List<?> list = (List<?>) obj;
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < list.size(); i++) {
                if (i > 0) sb.append(",");
                sb.append(toJson(list.get(i)));
            }
            sb.append("]");
            return sb.toString();
        }
        if (obj instanceof Map) {
            Map<?, ?> map = (Map<?, ?>) obj;
            StringBuilder sb = new StringBuilder("{");
            boolean first = true;
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                if (!first) sb.append(",");
                sb.append("\"").append(escapeJson(entry.getKey().toString())).append("\":");
                sb.append(toJson(entry.getValue()));
                first = false;
            }
            sb.append("}");
            return sb.toString();
        }
        return "null";
    }

    private static String escapeJson(String s) {
        return s.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }

    private static Map<String, Object> parseJson(String json) {
        json = json.trim();
        if (!json.startsWith("{")) return new LinkedHashMap<>();

        Map<String, Object> result = new LinkedHashMap<>();
        int depth = 0;
        StringBuilder key = new StringBuilder();
        StringBuilder value = new StringBuilder();
        boolean inKey = true;
        boolean inString = false;
        boolean escaped = false;

        for (int i = 1; i < json.length() - 1; i++) {
            char c = json.charAt(i);

            if (escaped) {
                if (inKey) key.append(c);
                else value.append(c);
                escaped = false;
                continue;
            }

            if (c == '\\') {
                escaped = true;
                continue;
            }

            if (c == '"') {
                inString = !inString;
                continue;
            }

            if (!inString) {
                if (c == ':' && inKey && depth == 0) {
                    inKey = false;
                    continue;
                }
                if ((c == ',' || c == '}') && depth == 0) {
                    String k = key.toString().trim();
                    String v = value.toString().trim();
                    if (!k.isEmpty() && !v.isEmpty()) {
                        result.put(k, parseJsonValue(v));
                    }
                    key = new StringBuilder();
                    value = new StringBuilder();
                    inKey = true;
                    continue;
                }
                if (c == '{' || c == '[') depth++;
                if (c == '}' || c == ']') depth--;
            }

            if (inKey) key.append(c);
            else value.append(c);
        }

        return result;
    }

    private static Object parseJsonValue(String v) {
        v = v.trim();
        if (v.equals("null")) return null;
        if (v.equals("true")) return true;
        if (v.equals("false")) return false;
        if (v.startsWith("\"") && v.endsWith("\"")) {
            return v.substring(1, v.length() - 1);
        }
        try {
            if (v.contains(".")) return Double.parseDouble(v);
            return Long.parseLong(v);
        } catch (NumberFormatException e) {
            return v;
        }
    }

    private static State parseStateJson(String json) {
        State s = new State();
        Map<String, Object> map = parseJson(json);
        Object wfId = map.get("workflowId");
        if (wfId != null) {
            s.workflowId = wfId.toString();
        }
        return s;
    }

    private static String toJson(State state) {
        Map<String, Object> map = new LinkedHashMap<>();
        if (state.workflowId != null) {
            map.put("workflowId", state.workflowId);
        }
        return toJson((Object) map);
    }
}
// This code uses the Extend REST API directly because Extend has no official Go SDK yet.
// It deploys the "Prior Authorization (PA) Request Form (RF)" pipeline to your Extend account.
//
// Usage:
//   export EXTEND_API_KEY=sk_...   (from https://dashboard.extend.ai → API Keys)
//   go run provision.go
//
// Generated by doc1 (template: prior-authorization-request-form).

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
)

const (
	API     = "https://api.extend.ai"
	VERSION = "2026-02-09"
)

var (
	apiKey  string
	stateDir string
	stateFile string
)

type State struct {
	WorkflowID string `json:"workflowId,omitempty"`
}

type WorkflowStep struct {
	Name   string        `json:"name"`
	Type   string        `json:"type"`
	Config interface{}   `json:"config,omitempty"`
	Next   []interface{} `json:"next,omitempty"`
}

type Workflow struct {
	Name  string         `json:"name"`
	Steps []WorkflowStep `json:"steps"`
}

var state State

func init() {
	apiKey = os.Getenv("EXTEND_API_KEY")
	if apiKey == "" {
		fmt.Fprintf(os.Stderr, "Set EXTEND_API_KEY first.\n")
		os.Exit(1)
	}

	cwd, _ := os.Getwd()
	stateDir = filepath.Join(cwd, ".extend")
	stateFile = filepath.Join(stateDir, "prior-authorization-request-form.json")

	if data, err := os.ReadFile(stateFile); err == nil {
		json.Unmarshal(data, &state)
	}
}

func saveState() error {
	os.MkdirAll(stateDir, 0755)
	data, _ := json.MarshalIndent(state, "", "  ")
	return os.WriteFile(stateFile, data, 0644)
}

func apiCall(method, pathName string, body interface{}) (map[string]interface{}, error) {
	var reqBody io.Reader
	if body != nil {
		data, _ := json.Marshal(body)
		reqBody = bytes.NewReader(data)
	}

	req, _ := http.NewRequest(method, API+pathName, reqBody)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
	req.Header.Set("x-extend-api-version", VERSION)
	if body != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	respData := make(map[string]interface{})
	json.NewDecoder(resp.Body).Decode(&respData)

	if resp.StatusCode >= 400 {
		respBytes, _ := json.Marshal(respData)
		if len(respBytes) > 300 {
			respBytes = respBytes[:300]
		}
		return nil, fmt.Errorf("%s %s failed (%d): %s", method, pathName, resp.StatusCode, string(respBytes))
	}

	return respData, nil
}

func main() {
	workflow := Workflow{
		Name: "Prior Authorization (PA) Request Form (RF) Processing Pipeline",
		Steps: []WorkflowStep{
			{
				Name: "startTrigger1",
				Type: "TRIGGER",
				Next: []interface{}{
					map[string]string{"step": "parse1"},
				},
			},
			{
				Name: "parse1",
				Type: "PARSE",
				Config: map[string]interface{}{
					"parseConfig": map[string]interface{}{
						"blockOptions": map[string]interface{}{
							"text": map[string]interface{}{
								"agentic": map[string]bool{
									"enabled": true,
								},
							},
						},
						"chunkingStrategy": map[string]string{
							"type": "document",
						},
					},
				},
				Next: []interface{}{
					map[string]string{"step": "extraction2"},
				},
			},
			{
				Name: "extraction2",
				Type: "EXTRACT",
				Config: map[string]interface{}{
					"extractorConfig": map[string]interface{}{
						"schema": map[string]interface{}{
							"type": "object",
							"properties": map[string]interface{}{
								"date_signed": map[string]interface{}{
									"type":              []string{"string", "null"},
									"extend:type":       "date",
									"description":       "The date on which the requesting provider signed the prior authorization form. This is the official attestation date for the request.",
								},
								"member_name": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The full name of the member or patient, typically in 'Last, First, Middle Initial' format. This is the individual receiving the requested service.",
								},
								"process_type": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The process or request type code associated with this prior authorization form. This code may indicate the specific workflow or program under which the request is being submitted. Commonly labeled as 'Process Type' or similar.",
								},
								"member_gender": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The gender of the member or patient. May be indicated as 'Male', 'Female', or other designations, and may be represented by checkboxes or text.",
								},
								"service_lines": map[string]interface{}{
									"type": "array",
									"items": map[string]interface{}{
										"type": "object",
										"properties": map[string]interface{}{
											"charge": map[string]interface{}{
												"type":        []string{"number", "null"},
												"description": "The monetary charge associated with this service line, representing the requested reimbursement for this specific service.",
											},
											"modifiers": map[string]interface{}{
												"type":        []string{"string", "null"},
												"description": "Any modifiers associated with the service code for this line item. Modifiers provide additional detail about the service performed and may be listed as one or more codes.",
											},
											"service_code": map[string]interface{}{
												"type":        []string{"string", "null"},
												"description": "The procedure or service code (such as CPT or HCPCS) for this line item. This code identifies the specific service being requested.",
											},
											"place_of_service": map[string]interface{}{
												"type":        []string{"string", "null"},
												"description": "The place of service (POS) code indicating where the service will be provided. Commonly a two-digit code.",
											},
											"quantity_requested": map[string]interface{}{
												"type":        []string{"number", "null"},
												"description": "The number of units or sessions requested for this service line. May be labeled as 'QR', 'Quantity', or similar.",
											},
											"service_description": map[string]interface{}{
												"type":        []string{"string", "null"},
												"description": "A textual description of the service, procedure, or item being requested in this line. May include duration, setting, or other relevant details.",
											},
											"rendering_provider_number": map[string]interface{}{
												"type":        []string{"string", "null"},
												"description": "The unique identification number for the provider rendering this specific service line. May be labeled as 'Rendering Provider Number' or similar.",
											},
											"rendering_provider_taxonomy_code": map[string]interface{}{
												"type":        []string{"string", "null"},
												"description": "The taxonomy code for the provider rendering this service line, indicating their specialty or classification.",
											},
										},
										"additionalProperties": false,
										"required": []string{
											"charge", "modifiers", "service_code", "place_of_service",
											"quantity_requested", "service_description", "rendering_provider_number",
											"rendering_provider_taxonomy_code",
										},
									},
									"description": "The individual services, procedures, or items being requested for prior authorization. Each entry represents a distinct service line with associated codes, descriptions, and charges. These may be presented in a table or list format and can vary in number and structure.",
								},
								"total_charges": map[string]interface{}{
									"type": "object",
									"properties": map[string]interface{}{
										"amount": map[string]interface{}{
											"type": []string{"number", "null"},
										},
										"iso_4217_currency_code": map[string]interface{}{
											"type": []string{"string", "null"},
										},
									},
									"additionalProperties": false,
									"required":             []string{"amount", "iso_4217_currency_code"},
									"extend:type":          "currency",
									"description":          "The total amount of charges associated with all requested services on this prior authorization form. This is the sum of all line item charges and represents the total financial request.",
								},
								"member_address": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The complete address of the member or patient, including street, city, state, and ZIP code.",
								},
								"authorization_number": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The unique identifier assigned to this prior authorization request. This number is used to track and reference the authorization throughout the review and claims process. May be labeled as 'PA Number', 'Authorization #', or similar, and can include letters, numbers, or special characters.",
								},
								"member_date_of_birth": map[string]interface{}{
									"type":        []string{"string", "null"},
									"extend:type": "date",
									"description": "The date of birth of the member or patient. Used to verify identity and eligibility. May appear in various date formats.",
								},
								"billing_provider_name": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The full name of the provider or organization submitting the billing for this authorization request. This is the entity responsible for providing the service and requesting payment.",
								},
								"primary_diagnosis_code": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The primary diagnosis code (such as ICD-10) that justifies the need for the requested service. This is the main clinical reason for the authorization request.",
								},
								"billing_provider_number": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The unique identification number assigned to the billing provider by the payer or regulatory body. May be labeled as 'Provider Number', 'Billing Provider ID', or similar.",
								},
								"first_date_of_treatment": map[string]interface{}{
									"type":        []string{"string", "null"},
									"extend:type": "date",
									"description": "The first date on which the requested service or treatment is expected to be provided. May be labeled as 'First Date of Treatment' or similar.",
								},
								"requested_pa_start_date": map[string]interface{}{
									"type":        []string{"string", "null"},
									"extend:type": "date",
									"description": "The requested start date for the prior authorization period. This is when the provider wishes the authorization to begin.",
								},
								"billing_provider_address": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The complete address of the billing provider, including street, city, state, and ZIP code. This identifies the location of the provider submitting the request.",
								},
								"prescribing_provider_npi": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The National Provider Identifier (NPI) for the prescribing, referring, or ordering provider. This is a unique 10-digit identification number for healthcare providers in the United States.",
								},
								"secondary_diagnosis_code": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "An additional diagnosis code (such as ICD-10) relevant to the request. This may support the medical necessity of the service.",
								},
								"prescribing_provider_name": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The full name of the provider who is prescribing, referring, or ordering the service for which prior authorization is requested. May be labeled as 'Prescribing Provider', 'Referring Provider', or 'Ordering Provider'.",
								},
								"member_identification_number": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The unique identification number assigned to the member or patient for whom the prior authorization is being requested. May be labeled as 'Member ID', 'Recipient Number', or similar.",
								},
								"primary_diagnosis_description": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "A textual description of the primary diagnosis associated with the request. This provides additional clinical context beyond the code.",
								},
								"requesting_provider_signature": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The name or signature of the provider submitting the prior authorization request. This may be a handwritten or electronic signature, or simply the provider's printed name.",
								},
								"billing_provider_taxonomy_code": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "The taxonomy code representing the specialty or classification of the billing provider. This code helps identify the provider's area of practice.",
								},
								"secondary_diagnosis_description": map[string]interface{}{
									"type":        []string{"string", "null"},
									"description": "A textual description of the secondary diagnosis, if provided.",
								},
							},
							"required": []string{
								"date_signed", "member_name", "process_type", "member_gender", "service_lines",
								"total_charges", "member_address", "authorization_number", "member_date_of_birth",
								"billing_provider_name", "primary_diagnosis_code", "billing_provider_number",
								"first_date_of_treatment", "requested_pa_start_date", "billing_provider_address",
								"prescribing_provider_npi", "secondary_diagnosis_code", "prescribing_provider_name",
								"member_identification_number", "primary_diagnosis_description", "requesting_provider_signature",
								"billing_provider_taxonomy_code", "secondary_diagnosis_description",
							},
							"additionalProperties": false,
						},
						"baseProcessor":     "extraction_performance",
						"advancedOptions": map[string]interface{}{
							"reviewAgent": map[string]bool{
								"enabled": true,
							},
							"advancedMultimodalEnabled": true,
						},
					},
				},
			},
		},
	}

	fmt.Printf("Deploying \"%s\"…\n", workflow.Name)

	if state.WorkflowID != "" {
		fmt.Printf("✓ workflow already provisioned (%s) — updating steps\n", state.WorkflowID)
		_, err := apiCall("POST", fmt.Sprintf("/workflows/%s", state.WorkflowID), map[string]interface{}{"steps": workflow.Steps})
		if err != nil {
			fmt.Fprintf(os.Stderr, "%v\n", err)
			os.Exit(1)
		}
	} else {
		// Try to find existing workflow with same name
		query := url.QueryEscape(workflow.Name)
		list, err := apiCall("GET", fmt.Sprintf("/workflows?name=%s", query), nil)
		if err == nil {
			var items []map[string]interface{}
			if data, ok := list["data"].([]interface{}); ok {
				for _, item := range data {
					items = append(items, item.(map[string]interface{}))
				}
			} else if data, ok := list["items"].([]interface{}); ok {
				for _, item := range data {
					items = append(items, item.(map[string]interface{}))
				}
			}

			for _, item := range items {
				if name, ok := item["name"].(string); ok && name == workflow.Name {
					if id, ok := item["id"].(string); ok {
						state.WorkflowID = id
						saveState()
						fmt.Printf("✓ workflow \"%s\" found in your account (%s) — updating steps\n", workflow.Name, id)
						_, err := apiCall("POST", fmt.Sprintf("/workflows/%s", id), map[string]interface{}{"steps": workflow.Steps})
						if err != nil {
							fmt.Fprintf(os.Stderr, "%v\n", err)
							os.Exit(1)
						}
						break
					}
				}
			}
		}

		if state.WorkflowID == "" {
			created, err := apiCall("POST", "/workflows", workflow)
			if err != nil {
				fmt.Fprintf(os.Stderr, "%v\n", err)
				os.Exit(1)
			}

			var wfID string
			if id, ok := created["id"].(string); ok {
				wfID = id
			} else if wf, ok := created["workflow"].(map[string]interface{}); ok {
				if id, ok := wf["id"].(string); ok {
					wfID = id
				}
			}

			if wfID == "" {
				fmt.Fprintf(os.Stderr, "Could not read created workflow id from response\n")
				os.Exit(1)
			}

			state.WorkflowID = wfID
			saveState()
			fmt.Printf("+ created workflow (%s)\n", wfID)
		}
	}

	// Deploy the current draft as a new version
	apiCall("POST", fmt.Sprintf("/workflows/%s/versions", state.WorkflowID), map[string]interface{}{})

	fmt.Println("\nDone. Run documents through it with:")
	fmt.Printf("  POST %s/workflow_runs  { workflow: { id: \"%s\" }, file: { url: \"https://…\" } }\n", API, state.WorkflowID)
	fmt.Println("Or open the workflow in the Extend dashboard to review and deploy it.")
}

Frequently Asked Questions (FAQ)

Use `baseProcessor: "extraction_performance"` (not `extraction_light`) and write specific field descriptions like "Insurance company's unique authorization number, usually 8-12 alphanumeric characters in top-right corner" to anchor the model.
Nuanced question and depends on the use case! For an agent pipeline, you'll likely just stop at Parsing, take the markdown/HTML output and feed that into your pipeline. For Key-Value extraction into JSON, you can jump straight into Extraction because there is always a Parse step beforehand
Confidence on categorical fields like status is often 0.7–0.85 for messy forms; always set a threshold and route low-confidence extractions to human review. Prior auth outcomes have hard business consequences, so treat any result below 0.80 as "needs verification" rather than gospel.
Tags
Prior AuthorizationHealthcare ProviderWisconsin DHSMember InformationDiagnosis Codes
About this template

This template processes Prior Authorization Request Forms (PA/RF) used by healthcare providers to obtain approval for covered services. It captures provider credentials, member demographics, diagnosis codes, and treatment details required for authorization decisions.

Document formats
  • PDF
  • Images & Scans
Requirements
  • Checkboxes & Strikethroughs
  • Long tables
  • Scanned documents
  • Handwriting