API reference

Three extraction endpoints, one 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) currently authenticate with Authorization: Bearer or a cookie session only. API-key auth is not yet enabled on file uploads. File upload also requires a paid plan.

All responses are JSON. Errors return { "error": "..." } with the status codes listed per endpoint.

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

FieldTypeDescription
email_bodystringRequired. The plain-text body of the quote email. Maximum 100 KB.
email_subjectstringOptional. Email subject line: improves document-type and quote-number detection.
email_senderstringOptional. Sender address: used for vendor detection and duplicate matching.

Response: 200 OK

FieldTypeDescription
extraction_idstring (uuid)ID of the saved extraction. Reference it in support requests.
extracted_dataobjectThe extracted fields (see the extracted_data schema below).
confidence_scorenumber0–1 confidence score (same value as extracted_data.confidence_score).
model_usedstringAI model that produced the extraction (e.g. gpt-4o-mini).
tokens_usednumberTokens consumed by the extraction. Absent on cached responses.
cachedbooleanPresent 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

StatusWhen
400Invalid JSON body, email_body missing, or body larger than 100 KB.
401No valid API key, Bearer token, or session.
402Monthly extraction limit reached. Response includes limit, current_count and upgrade_url.
403Valid API key on a Free or Starter plan. API access requires Pro or Team.
429Rate limit exceeded (10/min per user). Retry after the number of seconds in the Retry-After header.
500Extraction or persistence failure; safe to retry.

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

FieldTypeDescription
filefileRequired. 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.

Scanned-document page caps per plan (vision OCR):

PlanMax pages per scanned document
Free5 (file upload itself requires a paid plan)
Starter10
Pro50
Team100

Response: 200 OK

Same fields as POST /api/extract, plus:

FieldTypeDescription
sourcestringExtraction path: pdf_text, pdf_ocr, or pdf_vision.
page_countnumberNumber of pages read from the PDF.
pages_processednumberPresent on pdf_vision results: pages actually processed by vision (equals page_count unless processing stopped early).
partialbooleanPresent 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

StatusWhen
400No file field, file is not application/pdf, or the file fails PDF validation.
401No valid Bearer token or session.
402Free plan (PDF upload requires a paid plan), or monthly extraction limit reached.
413File larger than 10 MB.
422PDF 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).
429Rate limit exceeded (3/min per user). See the Retry-After header.
500Extraction failure; safe to retry.
504OCR 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

FieldTypeDescription
filefileRequired. 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:

FieldTypeDescription
sourcestringAlways excel.
sheet_countnumberNumber of sheets read from the workbook.
row_countnumberNumber of rows read.

Example

curl -X POST https://www.procuremind.io/api/extract/excel \
  -H "Authorization: Bearer <session token>" \
  -F "file=@quotes.xlsx"

Errors

StatusWhen
400No file field, unsupported file type (only .xlsx, .xls, .csv), or the file fails validation.
401No valid Bearer token or session.
402Free plan (file upload requires a paid plan), or monthly extraction limit reached.
413File larger than 10 MB.
422The file could not be read as a spreadsheet.
429Rate limit exceeded (3/min per user). See the Retry-After header.
500Extraction failure; safe to retry.

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

FieldTypeDescription
filefileRequired. 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:

FieldTypeDescription
sourcestringAlways docx.

Example

curl -X POST https://www.procuremind.io/api/extract/docx \
  -H "Authorization: Bearer <session token>" \
  -F "file=@quote.docx"

Errors

StatusWhen
400No file field, file is not a .docx, or the file fails validation.
401No valid Bearer token or session.
402Free plan (file upload requires a paid plan), or monthly extraction limit reached.
413File larger than 10 MB.
422The document could not be read, or contains no readable text.
429Rate limit exceeded (3/min per user). See the Retry-After header.
500Extraction failure; safe to retry.

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

FieldTypeDescription
filefileRequired. 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:

FieldTypeDescription
sourcestringAlways image.

Example

curl -X POST https://www.procuremind.io/api/extract/image \
  -H "Authorization: Bearer <session token>" \
  -F "file=@quote.jpg"

Errors

StatusWhen
400No file field, unsupported extension (only .png, .jpg, .jpeg, .webp), or the file is not a valid image.
401No valid Bearer token or session.
402Free plan (file upload requires a paid plan), or monthly extraction limit reached.
413File larger than 10 MB.
429Rate limit exceeded (3/min per user). See the Retry-After header.
500Extraction failure; safe to retry.

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.

FieldTypeDescription
document_typestringOne of quote, po, bom, rfi. Defaults to quote.
vendor_namestringSupplier name.
vendor_emailstringSupplier email address.
buyer_namestringIssuing organisation (PO, BOM, RFI; blank for quotes).
buyer_emailstringBuyer email (PO, BOM, RFI; blank for quotes).
delivery_addressstringShip-to address (PO only).
quote_numberstringDocument reference: quote number, PO number, BOM ID or RFI reference, depending on document_type.
bom_versionstringBOM revision, e.g. "Rev B" (BOM only).
currencystringDocument currency code.
total_amountstringGrand total, as a string.
subtotalstringPre-tax subtotal.
tax_amountstringTax amount (e.g. GST/VAT).
shipping_amountstringShipping/freight amount.
due_datestringDue or delivery date.
quote_validitystringQuote/RFI response deadline (blank for BOM/PO).
payment_termsstringPayment terms (quote and PO only).
incotermsstringIncoterms (quote and PO only).
itemsLineItem[]Line items (see the LineItem table below).
confidence_scorenumber0–1 confidence score for the extraction.

items[]: the LineItem object

FieldTypeDescription
descriptionstringItem description.
skustringPart number / SKU / product code.
quantitystringQuantity ordered/quoted.
unitstringUnit of measure (each, kg, m, box…).
unit_pricestringPrice per unit.
line_totalstringExtended line total.
currencystringPer-line currency (may differ from document currency).
discountstringDiscount, e.g. "10%" or "50.00".
moqstringMinimum order quantity.
spqstringStandard pack quantity.
lead_timestringLead time, e.g. "4 weeks".
manufacturerstringManufacturer name (BOM/PO extended fields).
manufacturer_pnstringManufacturer part number (MPN).
bom_levelstringHierarchy depth in a BOM, e.g. "1.1".
reference_designatorstringPCB/schematic references, e.g. "R1, R2, C3" (BOM).
notesstringLine-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.

Create an account →