Extract schedules
Schedule extraction · model schedule-extractor
/v1/drawings/schedulesExtract structured schedule tables from an architectural drawing PDF. Accepts a previously uploaded document_id, enqueues extraction, and returns a job you poll for results. Each schedule is returned with headers, rows, and schedule-level confidence.
- Returns
- A job to check202 Accepted
- Usage
- Document indexingper page scanned
- Results in
- A list of schedulesresult.schedules
- Auth
- API keyX-API-Key header
Example


How it runs
- Send a
document_id - Get a
job_id - Check your results or receive a webhook
Request
document_id. Upload your PDF first.Body is JSON — this endpoint does not accept file uploads directly.
| Field | Description |
|---|---|
document_idstring · UUIDRequired | ID of the uploaded PDF. Must belong to this account and not be expired. |
page_numbersarray of integersOptional | 1-based page indices to scan. Omit for a full-document scan. |
webhook_urlstring · URLOptional | URL to POST the completed job payload to. Delivered on developer, pro, and enterprise tiers only. |
| Header | Description |
|---|---|
X-API-KeyRequired | Your API key. A missing or invalid key returns 401. |
Content-TypeRequired | application/json |
page_numbers is omitted, pages_analyzed in the completed result is null; when provided, it reflects len(page_numbers) (not a substituted total page count).Responses
The job is enqueued immediately. Poll GET /v1/jobs/{job_id} until status is complete or failed.
| Field | Description |
|---|---|
job_idstring · UUID | Use this to poll for results. |
statusstring | Always queued on this response. |
poll_urlstring | Path only — prepend https://api.anchorgrid.ai to build the full URL. |
When status is complete and model is schedule-extractor, the result field on the job contains:
| Field | Description |
|---|---|
document_idstring | UUID of the source document. |
schedules_foundinteger | Count of schedules in the schedules array. |
pages_analyzedinteger | null | len(page_numbers) if provided; null for a full-document scan. |
model_versionstring | e.g. schedule-extractor-v1.0.0 |
processing_time_msinteger | Wall time for the extraction task. |
ocr_fallback_usedboolean | True if any page fell back to OCR due to low PDF text quality. |
rasterized_pagesinteger[] | Pages that were rasterized before extraction. Empty when PDF text layer was sufficient. |
schedulesarray | One object per detected schedule table. |
schedules[].schedule_typestring | Classifier label — e.g. "door_schedule", "window_schedule", "finish_schedule". |
schedules[].titlestring | Title as printed on the sheet. |
schedules[].confidencenumber | Schedule-level confidence score (0–1). |
schedules[].bounding_boxnumber[4] | Page coordinates of the table: [x1, y1, x2, y2] in PDF units. |
schedules[].headersstring[] | Column labels in left-to-right order. |
schedules[].rowsobject[] | Each row is an object keyed by header label. Empty string for blank cells. |
schedules[].metadata.row_countinteger | Number of data rows detected. |
schedules[].metadata.col_countinteger | Number of columns detected. |
schedules[].metadata.methodstring | Extraction strategy used internally (e.g. wide_net_proximity). |
schedules[].metadata.pdf_quality_issuesstring[] | Any quality flags raised for this schedule. Empty when extraction was clean. |
schedules[].metadata.ocr_fallbackboolean | True if this specific schedule used OCR. |
schedules[].metadata.item_bboxesobject | Each piece of text in the schedule region (e.g. a door number) mapped to the boxes where it appears, as [x1, y1, x2, y2] in PDF points. Empty for scanned schedules. |
schedules[].headers if you need the original column order.Usage & rate limits
Each job counts as one document-indexing page (See pricing). Rate limit: tier RPM (5 / 60 / 120 / 300).
| Plan | When the allowance is used up |
|---|---|
trial | Trial allowance — 402 FREE_TIER_LIMIT_REACHED when used up, 402 TRIAL_ENDED once the trial is over. |
developer | Monthly allowance, then overage up to your overage limit — 402 OVERAGE_LIMIT_REACHED at the limit (429 QUOTA_EXCEEDED when the allowance is used up without overage billing). |
enterprise | No allowance check. |
Rate-limit 429s include retry_after_seconds in the body. Quota 429s and rate-limit 429s return the same status code — check the error body to distinguish them.
Errors
| Status | What it means |
|---|---|
| 401 | Missing or invalid X-API-Key. |
| 402 | Trial allowance used up. |
| 404 | document_id not found or expired (DOCUMENT_NOT_FOUND in API code). |
| 422 | Validation error — malformed UUID or invalid body. |
| 429 | Rate limit or monthly quota exceeded. |