Extract 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.
Auth via X-API-Key header. Body is JSON — this endpoint does not accept file uploads directly.
document_idreq
string (UUID)
ID of the uploaded PDF. Must belong to this account and not be expired.
page_numbers
int[]
1-based page indices to scan. Omit for a full-document scan.
webhook_url
string
URL to POST the completed job payload to. Delivered on developer, pro, and enterprise tiers only.
ℹ
Cost is 1 credit per job, regardless of page count. When 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).
The job is enqueued immediately. Poll GET /v1/jobs/{job_id} until status is complete or failed.
job_id
string (UUID)
Use this to poll for results.
status
string
Always queued on this response.
poll_url
string
Path only — prepend https://api.anchorgrid.ai to build the full URL.
Result shape
When status === "complete" and model === "schedule-extractor", the result field on the job contains:
document_id
string
UUID of the source document.
schedules_found
integer
Count of schedules in the schedules array.
pages_analyzed
integer | null
len(page_numbers) if provided; null for a full-document scan.
model_version
string
e.g. schedule-extractor-v1.0.0
processing_time_ms
integer
Wall time for the extraction task.
ocr_fallback_used
boolean
True if any page fell back to OCR due to low PDF text quality.
rasterized_pages
integer[]
Pages that were rasterized before extraction. Empty when PDF text layer was sufficient.
schedules
array
One object per detected schedule table.
schedules[].schedule_type
string
Classifier label — e.g. "door_schedule", "window_schedule", "finish_schedule".
schedules[].title
string
Title as printed on the sheet.
schedules[].confidence
number
Schedule-level confidence score (0–1).
schedules[].bounding_box
number[4]
Page coordinates of the table: [x1, y1, x2, y2] in PDF units.
schedules[].headers
string[]
Column labels in left-to-right order.
schedules[].rows
object[]
Each row is an object keyed by header label. Empty string for blank cells.
schedules[].metadata.row_count
integer
Number of data rows detected.
schedules[].metadata.col_count
integer
Number of columns detected.
schedules[].metadata.method
string
Extraction strategy used internally (e.g. wide_net_proximity).
schedules[].metadata.pdf_quality_issues
string[]
Any quality flags raised for this schedule. Empty when extraction was clean.
schedules[].metadata.ocr_fallback
boolean
True if this specific schedule used OCR.
ℹ
Rows are returned as objects keyed by header label — no column index arithmetic needed. Use schedules[].headers if you need the original column order.
Credits & rate limits
Cost
1 credit per job
Rate limit
Tier RPM (5 / 60 / 120 / 300)
free
Lifetime credit cap — 402 FREE_TIER_LIMIT_REACHED when exceeded.
developer / pro
Monthly pool — 429 QUOTA_EXCEEDED when exceeded.
enterprise
No quota 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
401
Missing or invalid X-API-Key.
402
Free tier lifetime credit cap reached.
404
document_id not found or expired (DOCUMENT_NOT_FOUND in API code).
422
Validation error — malformed UUID or invalid body.