API reference
Five extraction endpoints, one saved-record response shape. Base URL for all requests is https://www.procuremind.io. New here? Start with the developer overview.
Authentication
POST /api/extract accepts an API key in the X-API-Key header (Pro/Team plans), a Supabase session token as Authorization: Bearer, or a dashboard cookie session.
The file endpoints (/api/extract/pdf, /api/extract/excel, /api/extract/docx, /api/extract/image) accept the same authentication methods. API keys require Pro or Team; file upload also requires a paid-plan entitlement. Paid-plan checkout is currently coming soon.
Extraction handlers return JSON errors with the status codes listed below. Proxy or infrastructure errors may use another format. Check the HTTP status first.
Explicit bearer credentials take precedence over API keys, then cookie sessions. Invalid explicit credentials return 401. These authentication methods apply to the extraction endpoints; other dashboard APIs do not automatically accept API keys.
Success includes the saved extraction ID. A handled save failure returns HTTP 500 with EXTRACTION_SAVE_FAILED and no extracted payload. File retries can consume additional quota; check history after a lost connection before retrying.
POST/api/extractExtract structured data from a quote email's text: the developer-API endpoint.
Request
Content-Type: application/json · Auth: X-API-Key (Pro/Team), Bearer token, or cookie session
| Field | Type | Description |
|---|---|---|
email_body | string | Required. The plain-text body of the quote email. Maximum 100 KB. |
email_subject | string | Optional. Email subject line: improves document-type and quote-number detection. |
email_sender | string | Optional. Sender address: used for vendor detection and duplicate matching. |
Response: 200 OK
| Field | Type | Description |
|---|---|---|
extraction_id | string (uuid) | ID of the saved extraction. Reference it in support requests. |
extracted_data | object | The extracted fields (see the extracted_data schema below). |
confidence_score | number | 0–1 confidence score (same value as extracted_data.confidence_score). |
model_used | string | AI model that produced the extraction (e.g. gpt-4o-mini). |
tokens_used | number | Tokens consumed by the extraction. Absent on cached responses. |
cached | boolean | Present and true when the same subject + sender + body was extracted before. The stored result is returned without consuming quota. |
Example
curl -X POST https://www.procuremind.io/api/extract \
-H "Content-Type: application/json" \
-H "X-API-Key: pm_your_key_here" \
-d '{
"email_subject": "Quote Q-1042 - Acme Fasteners",
"email_sender": "sales@acme-fasteners.com",
"email_body": "Hi, please find our quote: 500x M6 hex bolts @ $0.12 each..."
}'Errors
| Status | When |
|---|---|
400 | Invalid JSON body, email_body missing, or body larger than 100 KB. |
401 | No valid API key, Bearer token, or session. |
402 | Monthly extraction limit reached. Response includes limit, current_count and upgrade_url. |
403 | Valid API key on a Free or Starter plan. API access requires Pro or Team. |
429 | Rate limit exceeded (10/min per user). Retry after the number of seconds in the Retry-After header. |
500 | Extraction or save failure. Explicit retry may consume quota; check history after an uncertain response. |
POST/api/extract/pdfExtract structured data from a PDF quote attachment.
Request
Content-Type: multipart/form-data · Auth: Authorization: Bearer, X-API-Key (Pro/Team) or cookie session · Paid plans only
| Field | Type | Description |
|---|---|---|
file | file | Required. The PDF document, sent as the multipart field named "file". Must be application/pdf, under 10 MB. |
Text-based PDFs are parsed directly; scanned PDFs fall back to OCR, and low-confidence results are retried with vision extraction in batches of 5 pages, merged into a single result. Long text documents are chunked automatically with the same merge. The source field in the response tells you which path produced the result.
Page caps per PDF (text and scanned documents):
| Plan | Max pages per PDF |
|---|---|
| Free | PDF uploads unavailable |
| Starter | 50 |
| Pro | 100 |
| Team | 100 |
Response: 200 OK
Same fields as POST /api/extract, plus:
| Field | Type | Description |
|---|---|---|
source | string | Extraction path: pdf_text, pdf_ocr, or pdf_vision. |
page_count | number | Number of pages read from the PDF. |
pages_processed | number | Present on pdf_vision results: pages actually processed by vision (equals page_count unless processing stopped early). |
partial | boolean | Present and true when the time budget stopped chunked processing early — the result covers pages_processed of page_count pages. |
Example
curl -X POST https://www.procuremind.io/api/extract/pdf \
-H "Authorization: Bearer <session token>" \
-F "file=@quote.pdf;type=application/pdf"Errors
| Status | When |
|---|---|
400 | No file field, file is not application/pdf, or the file fails PDF validation. |
401 | No valid API key, Bearer token or session. |
402 | Free plan (PDF upload requires a paid plan), or monthly extraction limit reached. |
413 | File larger than 10 MB. |
422 | PDF could not be read or contains no readable text — or the document exceeds your plan's page cap for scanned documents (response includes pages, page_cap and upgrade_url). |
429 | Rate limit exceeded (3/min per user). See the Retry-After header. |
500 | Extraction or save failure; retry may consume quota. |
504 | OCR exceeded the processing time limit; try a text-based PDF or fewer pages. |
POST/api/extract/excelExtract structured data from an Excel or CSV quote file.
Request
Content-Type: multipart/form-data · Auth: Authorization: Bearer, X-API-Key (Pro/Team) or cookie session · Paid plans only
| Field | Type | Description |
|---|---|---|
file | file | Required. The spreadsheet, sent as the multipart field named "file". Supported: .xlsx, .xls, .csv, under 10 MB. |
Response: 200 OK
Same fields as POST /api/extract, plus:
| Field | Type | Description |
|---|---|---|
source | string | Always excel. |
sheet_count | number | Number of sheets read from the workbook. |
row_count | number | Number of rows read. |
Example
curl -X POST https://www.procuremind.io/api/extract/excel \
-H "Authorization: Bearer <session token>" \
-F "file=@quotes.xlsx"Errors
| Status | When |
|---|---|
400 | No file field, unsupported file type (only .xlsx, .xls, .csv), or the file fails validation. |
401 | No valid API key, Bearer token or session. |
402 | Free plan (file upload requires a paid plan), or monthly extraction limit reached. |
413 | File larger than 10 MB. |
422 | The file could not be read as a spreadsheet. |
429 | Rate limit exceeded (3/min per user). See the Retry-After header. |
500 | Extraction or save failure; retry may consume quota. |
POST/api/extract/docxExtract structured data from a Word (.docx) quote document.
Request
Content-Type: multipart/form-data · Auth: Authorization: Bearer, X-API-Key (Pro/Team) or cookie session · Paid plans only
| Field | Type | Description |
|---|---|---|
file | file | Required. The Word document, sent as the multipart field named "file". Only .docx, under 10 MB — validated by extension and by content (a .docx is a ZIP container, checked by signature). |
Text is extracted from the document and run through the same pipeline as email extraction — document classification, fields and confidence scoring are identical.
Response: 200 OK
Same fields as POST /api/extract, plus:
| Field | Type | Description |
|---|---|---|
source | string | Always docx. |
Example
curl -X POST https://www.procuremind.io/api/extract/docx \
-H "Authorization: Bearer <session token>" \
-F "file=@quote.docx"Errors
| Status | When |
|---|---|
400 | No file field, file is not a .docx, or the file fails validation. |
401 | No valid API key, Bearer token or session. |
402 | Free plan (file upload requires a paid plan), or monthly extraction limit reached. |
413 | File larger than 10 MB. |
422 | The document could not be read, or contains no readable text. |
429 | Rate limit exceeded (3/min per user). See the Retry-After header. |
500 | Extraction or save failure; retry may consume quota. |
POST/api/extract/imageExtract structured data from a photo or screenshot of a quote.
Request
Content-Type: multipart/form-data · Auth: Authorization: Bearer, X-API-Key (Pro/Team) or cookie session · Paid plans only
| Field | Type | Description |
|---|---|---|
file | file | Required. The image, sent as the multipart field named "file". Supported: .png, .jpg, .jpeg, .webp, under 10 MB. The real format is detected from the file content (magic bytes), not the extension. |
Images go straight to vision extraction — one image is one extraction, counted against the same monthly quota as everything else.
Response: 200 OK
Same fields as POST /api/extract, plus:
| Field | Type | Description |
|---|---|---|
source | string | Always image. |
Example
curl -X POST https://www.procuremind.io/api/extract/image \
-H "Authorization: Bearer <session token>" \
-F "file=@quote.jpg"Errors
| Status | When |
|---|---|
400 | No file field, unsupported extension (only .png, .jpg, .jpeg, .webp), or the file is not a valid image. |
401 | No valid API key, Bearer token or session. |
402 | Free plan (file upload requires a paid plan), or monthly extraction limit reached. |
413 | File larger than 10 MB. |
429 | Rate limit exceeded (3/min per user). See the Retry-After header. |
500 | Extraction or save failure; retry may consume quota. |
The extracted_data object
All three endpoints return the same schema. Fields that don't apply to a document type come back as empty strings.
| Field | Type | Description |
|---|---|---|
document_type | string | One of quote, po, bom, rfi. Defaults to quote. |
vendor_name | string | Supplier name. |
vendor_email | string | Supplier email address. |
buyer_name | string | Issuing organisation (PO, BOM, RFI; blank for quotes). |
buyer_email | string | Buyer email (PO, BOM, RFI; blank for quotes). |
delivery_address | string | Ship-to address (PO only). |
quote_number | string | Document reference: quote number, PO number, BOM ID or RFI reference, depending on document_type. |
bom_version | string | BOM revision, e.g. "Rev B" (BOM only). |
currency | string | Document currency code. |
total_amount | string | Grand total, as a string. |
subtotal | string | Pre-tax subtotal. |
tax_amount | string | Tax amount (e.g. GST/VAT). |
shipping_amount | string | Shipping/freight amount. |
due_date | string | Due or delivery date. |
quote_validity | string | Quote/RFI response deadline (blank for BOM/PO). |
payment_terms | string | Payment terms (quote and PO only). |
incoterms | string | Incoterms (quote and PO only). |
items | LineItem[] | Line items (see the LineItem table below). |
confidence_score | number | Overall model estimate from 0–1; not field-level confidence, measured accuracy or approval. |
items[]: the LineItem object
| Field | Type | Description |
|---|---|---|
description | string | Item description. |
sku | string | Part number / SKU / product code. |
quantity | string | Quantity ordered/quoted. |
unit | string | Unit of measure (each, kg, m, box…). |
unit_price | string | Price per unit. |
line_total | string | Extended line total. |
currency | string | Per-line currency (may differ from document currency). |
discount | string | Discount, e.g. "10%" or "50.00". |
moq | string | Minimum order quantity. |
spq | string | Standard pack quantity. |
lead_time | string | Lead time, e.g. "4 weeks". |
manufacturer | string | Manufacturer name (BOM/PO extended fields). |
manufacturer_pn | string | Manufacturer part number (MPN). |
bom_level | string | Hierarchy depth in a BOM, e.g. "1.1". |
reference_designator | string | PCB/schematic references, e.g. "R1, R2, C3" (BOM). |
notes | string | Line-level notes or RFI question-response text. |
Webhooks
Pro and Team accounts can register webhook endpoints in the dashboard under Settings → Webhooks. After every successful extraction, ProcureMind POSTs a signed extraction.completed event to each active endpoint.
Each endpoint gets a signing secret (whsec_…) shown once at creation. Verify deliveries by recomputing HMAC-SHA256(secret, "{timestamp}.{raw body}") and comparing it to the v1 value in the X-ProcureMind.io-Signature header. Delivery times out after 10 seconds and is fire-and-forget. Webhook failures never affect the extraction response.
POST https://your-server.example/hooks/procuremind
Content-Type: application/json
X-ProcureMind.io-Event: extraction.completed
X-ProcureMind.io-Signature: t=1756723200,v1=9f86d081...
{
"event": "extraction.completed",
"created_at": "2026-09-01T12:00:00.000Z",
"data": {
"extraction_id": "9f1c2a7e-...",
"document_type": "quote",
"vendor_name": "Acme Fasteners",
"total_amount": "60.00",
"currency": "USD",
"confidence_score": 0.97,
"source": "email",
"sent_to_sheet": false
}
}Questions?
Email support@procuremind.io and include the extraction_id: we can trace the request exactly.