Skip to main content
Extract structured data from every file in a directory and save one JSON response per file in transform-results. Use the sequential example to test two or three files. For larger directories, use the asynchronous example, which submits up to three files at a time and can resume unfinished jobs after an interruption. Each job tracks one document until processing finishes. The asynchronous example saves each filename, job ID, status, output name, and error so a rerun can continue unfinished work. Set UNSTRUCTURED_API_KEY in your zsh session and install the Python SDK or TypeScript SDK before running an example. The examples use the SDK’s default Transform API endpoint.
The documents list includes every file directly under the input directory. If the directory contains unrelated files, filter that list to the file types you want to process before calling Extract.
These examples call direct Extract with the ACME Financial Highlights schema. It was built from Parse output for the ACME annual report sample. Save the schema beside each script. For other documents, use a schema that matches your files. Define your extraction schema includes an AI prompt for drafting a schema from a CSV or input file.

Process files sequentially

Save this as extract_directory.py. Pass a directory as the first argument. If you omit it, the script reads from Documents:
Run it with:
Each call waits for Extract to finish and writes its response before the script submits the next file.

Process files asynchronously

Use this workflow for larger directories or when you may need to stop and resume. It submits up to three files at a time, saves state before and after submission, polls every 30 seconds, and writes each result once. A rerun reuses saved job IDs and skips completed files.The API does not publish request-rate or concurrent-job limits. See supported files and limits, and follow recovery guidance if a request returns rate_limited or quota_exceeded.Save this as extract_directory_async.py. Pass a directory as the first argument. If you omit it, the script reads from Documents:
wait_seconds=0 returns a job handle immediately. The state file records each handle before polling. If the process stops while polling or the connection fails, rerunning the command uses the saved job IDs instead of submitting completed files again. A job with status failed or cancelled stays in the state file with its error so you can inspect it or rerun with --retry-failed.An interruption during submission can leave a record as submitting without a job ID. A request error can leave it as submission_unknown. The script does not retry either state automatically because the API may already have accepted the document.To recover either state:
  1. Stop all copies of the script. In the selected input directory, open transform-results/.extract-state.json (for example, ./Documents/transform-results/.extract-state.json).
  2. Check your job history for the document and submission time. If you identify the accepted job, add its ID as job_id and change the record’s status to queued. Keep the other fields.
  3. If you confirm that no job was accepted, change the record’s status to ready and remove any job_id. The next run submits the document again.
  4. Save the state file and rerun the command. If you cannot confirm whether a job was accepted, leave the record unchanged and investigate before retrying. Retrying an uncertain submission can create a duplicate job.
Run the asynchronous example with:
To retry only jobs that the API reported as failed or cancelled:
For more ways to define fields, see Define your extraction schema. Direct Extract accepts one document and one schema per request.