/// API REFERENCE

API reference.

All endpoints are HTTPS. Base URL: https://api.ashdocs.io. Rate limited per API key.

Getting started

Grab an API key from the dashboard. test keys never charge credits — use them in CI. live keys deduct from your plan.

# Every request needs your API key
curl https://api.ashdocs.io/api/v1/me -H "X-API-Key: ash_live_xxxxxxxx"
Auth
Header X-API-Key
Rate limit
Plan-based, headers on every response
Idempotency
Header Idempotency-Key, cached 24h

Conversion tools

POST/api/v1/convert/html-to-pdf1 credits
Render arbitrary HTML into a PDF.
{ "html": "<h1>Hi</h1>", "options": { "format": "A4" } }
POST/api/v1/convert/url-to-pdf2 credits
Fetch a public URL and render it. Private IPs and metadata endpoints are refused (SSRF).
{ "url": "https://example.com", "options": { "wait_for": "networkidle" } }
POST/api/v1/convert/pdf-to-markdown2 credits
Preserves headings, lists, and tables.
multipart file(s) + include_page_markers=false

Structured extraction

POST/api/v1/extract/tables2 credits
Layout-aware — supports ruled and borderless tables. Returns per-cell confidence.
multipart file + output_format=csv|xlsx|json + pages=all|1-3 + merge_tables=false
POST/api/v1/extract/data3 credits
Schema-driven LLM extraction. Returns data + per-field confidence + validation flags.
{ "file_url": "…", "schema": { "invoice_number": {"type":"string"}, "total_amount": {"type":"number"} }, "confidence_threshold": 0.85 }
POST/api/v1/extract/bank-statement3 credits
Parses transactions, categorizes optionally, includes a signed reconciliation check.
multipart file + output_format=csv|xlsx|qbo|ofx + categorize=false
GET/api/v1/extract/{job_id}/provenance
Bounding boxes for every extracted field, in the original PDF's coordinate space.

Batch

POST/api/v1/batchper file
Up to 50 files, concurrent. One credit ledger entry.
multipart tool_key=… + files=@a.pdf + files=@b.pdf + options={}
GET/api/v1/batch/{batch_id}
Retrieve a batch summary and per-file statuses later.

Security & compliance

POST/api/tools/redact-pdf/run2 credits
Native PDF redaction — text is removed, not just covered. Luhn-validated card detection.
multipart file + options={"types":["email","ssn","credit_card","phone"]}

Zero-retention. Set options.retention="zero" per request, or toggle account-wide from /account/retention. Confidence still returned inline; nothing persisted.

Review queue

GET/api/review?only_pending=true
List extraction rows needing human review.
GET/api/review/{result_id}
Get one row with source-PDF signed URL and editable JSON tree.
PATCH/api/review/{result_id}
Save corrections. When approve=true, fires webhook + destination event `review.approved` with corrected data.
{ "extracted_json": { … }, "approve": true }

Pipelines & schedules

GET/api/pipeline-templates
6 canned templates (invoice→QB, bank→Xero, etc.).
POST/api/pipeline-templates/instantiate
Clone a template into a user pipeline.
{ "template_id": "invoice-to-qb" }
POST/api/pipelines/{id}/schedule
Attach a 5-field cron schedule. Runs unattended in background.
{ "cron": "0 3 * * *", "enabled": true, "tz": "UTC" }

Webhooks & destinations

POST/api/webhooks
Signed POST with header X-ASHDOCS-Signature: sha256=… 3 retries with backoff.
{ "url": "https://your.app/hook", "events": ["job.completed","review.approved"] }
POST/api/destinations
Push formatted events to Slack or Discord. No code required.
{ "kind": "slack", "webhook_url": "https://hooks.slack.com/…", "events": ["job.completed"] }
SUPPORTED EVENTS
job.completedjob.failedjob.queuedpipeline.completedpipeline.failedreview.approved

Analytics, status, health

GET/api/analytics/usage?days=30
Per-day + per-tool + live/test breakdown for the current user.
GET/api/jobs/{job_id}/logs
Timing events, credit consumption, confidence & redaction summaries.
GET/api/status
Public. Overall + component + per-tool health, last 1h.
GET/api/health
Public liveness probe.

Zapier connector

Wire ASHDOCS into any of 5,000+ Zapier apps without writing code. The connector uses REST hooks — Zapier subscribes; we deliver events instantly.

GET/api/zapier/manifest
Discovery — Zapier reads this to build the trigger and action dropdowns.
POST/api/zapier/subscribe
Zapier registers a Zap for one event. Returns id used for unsubscribe.
{ "target_url": "https://hooks.zapier.com/…", "event": "review.approved" }
DELETE/api/zapier/subscribe/{id}
Zapier unsubscribes when the Zap is turned off.
GET/api/zapier/samples/{event}
Zapier calls this at setup so the user can map fields to real sample data.
GET/api/zapier/recent/{event}?limit=3
Polling fallback for backfill when a REST hook is missed.

Recipe: Extraction Approved → Google Sheets row. Filter tool_key = pdf-to-data, map extracted_json.* to columns.

Google Drive destination

OAuth-based. Connect once, then add as many gdrive destinations as folders you need.

GET/api/oauth/drive/status
Report whether the operator configured Drive + whether the current user connected their Drive account.
GET/api/oauth/drive/connect
Returns the Google consent URL. Front-end redirects the user there.
GET/api/oauth/drive/callback
Google redirects here after consent. We store refresh + access tokens Fernet-encrypted.
DELETE/api/oauth/drive
Disconnect. Existing gdrive destinations are disabled but not deleted.

Errors

All errors return JSON with detail.code and detail.message.

unauthorized401
Missing or invalid API key.
insufficient_credits402
Plan quota exhausted.
rate_limited429
Slow down — check X-RateLimit-Reset header.
ssrf_blocked400
Requested URL targets a private or metadata IP.
virus_detected400
ClamAV flagged the uploaded file.
low_confidence422
Extraction failed min-confidence threshold (with on_low_confidence='fail').
schema_required400
pdf-to-data called without a schema object.
template_not_found404
Cloning unknown pipeline template.
bad_cron400
Invalid cron expression on POST /pipelines/{id}/schedule.
too_many_files400
Batch got more than 50 files.