Data Alchemy — Software IDP con AI
For developers

IDP Developer API: Document Data Extraction via REST, Webhooks & JSON

Data Alchemy exposes its Intelligent Document Processing (IDP) engine through a REST API and webhooks. With this data extraction API you send invoices, delivery notes (DDT), orders or contracts and get back structured, validated JSON — 99.8% accuracy with Claude and around 12 seconds for a one-page document (average time with Claude Sonnet), ready to post into an ERP such as SAP, Zucchetti or TeamSystem. This page is the developer API documentation for engineers and system integrators: REST endpoints, webhooks, the output data schema and Zucchetti API.

The REST API and webhooks are included in every licence: Basic, Business and Enterprise. On Basic they are how you integrate with your ERP; the AI agent is available from Business.

What it is

An IDP API that turns documents into structured data

The developer API is the programmatic side of Data Alchemy's Intelligent Document Processing platform. Instead of clicking through a web app, your systems submit documents over HTTP and receive validated, structured data in return — so you can embed invoice, DDT and order extraction directly into your own software, automate your accounts-payable pipeline, or feed any ERP or CRM with no manual re-keying.

Authentication

Base URL and authentication

All requests use HTTPS against https://api.data-alchemy.ai/v1 and authenticate with a Bearer API key passed in the Authorization header. Keys are generated from the console and must be kept server-side, never exposed in the browser. Every response is UTF-8 JSON.

Request — submit document (cURL)
curl -X POST https://api.data-alchemy.ai/v1/documents \
  -H "Authorization: Bearer $DATA_ALCHEMY_API_KEY" \
  -H "Content-Type: multipart/form-data" \
  -F "file=@fattura.pdf" \
  -F "document_type=invoice"
Quickstart

Quickstart: from the first call to JSON in 5 minutes

  1. Generate the API key. From the Data Alchemy console create a key for the test or production environment. Keep the key server-side (environment variable or secret manager), never in client code or in the browser.
  2. Send the first document. A multipart POST to /v1/documents with the PDF and the document_type starts the extraction and immediately returns an id and the processing status.
  3. Register a webhook. A POST to /v1/webhooks declares the URL that will receive the document.processed event: no polling, and you get the data the moment processing finishes.
  4. Verify the HMAC signature. Recompute the HMAC SHA-256 over the raw body and compare it with the X-Data-Alchemy-Signature header before reading the payload.
  5. Map the JSON onto your ERP. The output schema is identical for every document type: write the mapping once and reuse it for invoices, delivery notes, orders, contracts and price lists.

A single integration covers the whole accounts-payable cycle: document intake, automatic classification, extraction, validation against your management system's master data and writing into SAP, Zucchetti or TeamSystem.

API reference

REST API reference: submit a document and read the data

The typical flow is asynchronous: you submit a document with a POST, receive an id and a processing status, then retrieve the result with a GET — or, better, let a webhook notify you when it completes. All endpoints are versioned under /v1.

POST/v1/documentsSubmit a document (PDF, XML, image) and start extraction. Returns an id and a status.
GET/v1/documents/{id}Retrieve the status and the extracted, validated data of a submitted document.
GET/v1/documentsList processed documents with filters by status, type and date range.
POST/v1/webhooksRegister an endpoint that will receive document.processed events in real time.
202 response — document processing
{
  "id": "doc_8a7f2c91",
  "status": "processing",
  "document_type": "invoice",
  "created_at": "2026-06-04T09:12:33Z",
  "webhook_url": "https://yourapp.example.com/hooks/data-alchemy"
}
Retrieve the result (cURL)
curl https://api.data-alchemy.ai/v1/documents/doc_8a7f2c91 \
  -H "Authorization: Bearer $DATA_ALCHEMY_API_KEY"

Everything in this section — endpoints, parameters, output schema, webhooks and error codes — is also published as an OpenAPI 3.1 specification: feed it to Postman, to a client generator or to your AI assistant and have the integration scaffolded without copying anything by hand.

Webhooks

Webhooks: what they are and how they work

A webhook is an HTTP request that a service sends automatically to a URL you provide, the moment an event happens. It is the reverse of a normal API call: instead of you asking «is the document ready?», the service tells you as soon as it is. That is why a webhook is often described as a «reverse API» or an HTTP callback — the receiving application exposes a public endpoint and listens, while the service acts as the client.

In Data Alchemy it works like this: register a URL and you receive a POST to your endpoint as soon as a document has been processed, so you never poll. The payload contains the event, the document id, the confidence score and the extracted data following the output schema. Every request is signed with HMAC SHA-256 in the X-Data-Alchemy-Signature header so you can verify authenticity.

Webhook payload — document.processed
POST /hooks/data-alchemy  (X-Data-Alchemy-Signature: sha256=...)

{
  "event": "document.processed",
  "id": "doc_8a7f2c91",
  "status": "completed",
  "confidence": 0.998,
  "data": { /* schema di output — vedi sotto / see below */ }
}

Webhooks vs polling: what's the difference?

With polling, your system repeatedly asks the API («is it ready yet?»), wasting calls until processing completes and adding a delay equal to your polling interval. With a webhook the notification fires the instant the document is ready: no empty calls, no artificial delay and far less load on both sides. Polling still makes a useful safety net — for example to catch up on a document if your endpoint was unreachable for a long stretch.

How to verify a webhook signature

Because your endpoint is public, anyone could POST to it. That is why every Data Alchemy webhook carries an X-Data-Alchemy-Signature header holding the HMAC SHA-256 of the raw request body, computed with your secret. Recompute the signature over the body you received and compare it with the header using a constant-time comparison: if they differ, drop the request. Always verify the signature before reading the payload.

Signature verification — Node.js
import crypto from "node:crypto";

// Il body va letto grezzo: un JSON già parsato e riserializzato
// produrrebbe una firma diversa. / Read the raw body: a parsed and
// re-serialised JSON would produce a different signature.
function isFromDataAlchemy(rawBody, header, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  const received = header.replace("sha256=", "");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(received)
  );
}
Data schema

Output data schema (JSON)

Every document returns typed, validated JSON: header (supplier, number, dates), line items, totals, taxes and the result of validation against your ERP master data. The structure is consistent across document types, so you write the mapping to your ERP only once.

Output schema — invoice
{
  "document_type": "invoice",
  "header": {
    "supplier": {
      "name": "Rossi Forniture S.r.l.",
      "vat_number": "IT01234567890"
    },
    "invoice_number": "2026/00417",
    "issue_date": "2026-05-28",
    "currency": "EUR"
  },
  "line_items": [
    {
      "sku": "ART-0042",
      "description": "Cartone 30x20x15",
      "quantity": 12,
      "unit_price": 8.50,
      "total": 102.00,
      "vat_rate": 22
    }
  ],
  "totals": { "net": 102.00, "vat": 22.44, "gross": 124.44 },
  "validation": { "status": "validated", "erp_match": true }
}
document_type
Document type classified by the AI: invoice, delivery_note, order, contract, price_list.
header
Header data: supplier/customer details, VAT number, document number, dates and currency.
line_items
Array of lines: item code (SKU), description, quantity, unit price, total and VAT rate.
totals
Recomputed and re-checked totals: net amount (net), tax (vat) and document total (gross).
validation
Result of real-time validation against ERP master data, with an erp_match flag and any anomalies.
OCR and data extraction

OCR and data extraction API: how it differs from a classic OCR

If you're shopping for an OCR API to read invoices and documents, this API does that job and then goes one step further. An OCR returns the text it recognised on the image: a string, which someone then has to interpret to work out which number is the taxable amount and which is the VAT number. Here the call is the same — a multipart POST with your PDF — but the response is already typed JSON, with header, line items, totals and the outcome of validation against your ERP master data.

In practice: where an OCR leaves you writing the parser and maintaining it for every new supplier, here the parsing is the service. The document goes through text recognition, document-type classification, field extraction with a dedicated LLM and validation — and what reaches your code is the structure described in the output schema above, identical across document types.

No per-supplier templates

A rules-based OCR needs reconfiguring when an invoice layout changes. Extraction here is LLM-based: it reads layouts it has never seen without you adding a line of configuration.

Native PDFs and scans

Text PDFs, scanned PDFs, images and FatturaPA XML all go to the same endpoint: optical recognition only kicks in when it's actually needed.

Fields, not strings

The response exposes header, line_items, totals and validation — not a blob of text you mine with regular expressions.

Validated before it returns

The erp_match flag tells you whether the supplier and the item codes exist in your ERP master data. That's the check an OCR, by definition, cannot perform.

Still deciding which of the two technologies you need? The invoice OCR software vs IDP AI comparison goes into detail. If you'd rather see it on a document of your own, try the extraction free with the Demo.

Errors and limits

Rate limits, retries and error handling

Responses use standard HTTP status codes: 202 for a document accepted and processing, 200 when you retrieve the result, 401 for a missing or invalid API key, 422 for an unreadable document and 429 when you exceed the rate limit. Every error returns JSON with error.code and error.message.

On a 429 or any 5xx error, retry with exponential backoff so you don't pile pressure on a service that is already under load. Undelivered webhooks are retried automatically with increasing backoff, so no document.processed event is lost even if your endpoint stays unreachable for a few minutes.

202Document accepted and processing.
200Result ready: extracted and validated data.
401API key missing, expired or invalid.
422Document unreadable or format unsupported.
429Rate limit exceeded: retry with exponential backoff.
Error response — 429 rate limit
HTTP/1.1 429 Too Many Requests
Retry-After: 30

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Retry after 30s."
  }
}
Integration modes

The API and the other three integration modes

The REST API with webhooks is the mode for developers. If you'd rather not write code, the same processing reaches your systems through the AI agent, the native Salesforce connector or the Mail service.

REST API + webhooks

Licence
  • Basic: included
  • Business: included
  • Enterprise: included
Who it's for
Developers and system integrators building extraction into their own software.
What it does
You send documents over HTTPS and receive structured, validated JSON; a signed webhook tells you when processing has finished.
Channels and formats
  • REST API /v1 with a Bearer API key
  • Input: PDF, images, XML
  • Output: JSON
  • document.processed webhooks signed with HMAC SHA-256

AI agent

Licence
  • Business: separately quoted add-on
  • Enterprise: included
Who it's for
Anyone who wants to connect Data Alchemy to their ERP or CRM.
What it does
Installed at your premises, it connects to Data Alchemy over websocket and APIs: it makes your ERP data available for the checks and posts the extracted data into it, including orders with header and lines.
Channels and formats
  • Destinations configured from a graphical interface: database, CSV/JSON/TXT files, APIs
  • ERP credentials kept in your perimeter
  • Integration in 2–5 working days without custom integrations

Native Salesforce connector

Licence
  • Enterprise: included
Who it's for
Teams that manage sales orders in Salesforce.
What it does
With Order Dispatcher, orders read by the AI land in Salesforce as drafts, already filled in and with the original PDF attached.
Channels and formats
  • Official Salesforce APIs
  • Server-to-server OAuth
  • Draft orders with the PDF attached

Mail service

Licence
  • Business: included
  • Enterprise: included
Who it's for
Teams that receive invoices, delivery notes and orders in business mailboxes.
What it does
Installed at your premises, it manages multiple mailboxes and sends Data Alchemy only the emails that match a model.
Channels and formats
  • Business mailboxes
  • Configured from a graphical interface
  • Emails and credentials kept in your perimeter

The REST API and webhooks are included in every licence. The Basic licence, and therefore the Demo that is its free trial, does not include the AI agent, the Mail service or the Salesforce connector: on Basic, ERP integration goes through the REST API.

FAQ

Frequently asked questions about the developer API

Is there an API to extract structured data from invoices and business documents to integrate into my software?

Yes, this one. Your software sends the document with a multipart POST to https://api.data-alchemy.ai/v1/documents (file plus document_type: invoice, delivery_note, order, contract or price_list) and gets back typed JSON with header, line items, totals and the outcome of validation against the ERP master data, via a webhook signed with HMAC SHA-256 or a GET on /v1/documents/{id}. The full contract is public as OpenAPI 3.1 at /openapi.json, the API is included in every licence and the output schema is the same for every document type. The comparison with Mindee, Klippa, Amazon Textract, Google Document AI, Azure and ABBYY is on the document data extraction API comparison page.

What is the Data Alchemy developer API?

It is the programmatic interface to Data Alchemy's Intelligent Document Processing (IDP) engine. Instead of using the web app, your systems submit documents — invoices, delivery notes (DDT), purchase orders, contracts, price lists — and receive back structured, validated data ready to write into your ERP or CRM.

Which integration methods are available?

There are four modes. The REST API with signed webhooks, for developers. The REST API is included in every licence (Basic, Business, Enterprise). The AI agent, installed at your premises, which connects to Data Alchemy over websocket and APIs and posts the data into your ERP on the destination configured from a graphical interface: a database, CSV, JSON or TXT files, or APIs (a separately quoted add-on on the Business licence, included in Enterprise). The native Salesforce connector with Order Dispatcher, which creates draft orders in the CRM (Enterprise licence). The Mail service, installed at your premises, which captures documents from business mailboxes (from the Business licence).

What format does the extracted data come back in?

Extracted fields are returned as structured JSON — header data, line items, totals, taxes and document references — already validated against your ERP master data, so it can be mapped directly onto your system of record.

How do authentication and webhook security work?

Requests authenticate with a Bearer API key in the Authorization header over HTTPS. Outgoing webhooks are signed with HMAC SHA-256 in the X-Data-Alchemy-Signature header, so you can verify each notification genuinely comes from Data Alchemy before processing it.

How accurate and fast is the extraction?

Data Alchemy pairs each document model with a single AI engine, chosen from Claude (recommended), GPT, Data Alchemy AI (Data Alchemy's proprietary model) or a compatible model through the European providers Scaleway and Regolo.ai; with Claude it reaches 99.8% accuracy (no accuracy figure is published for the other engines) with no templates and no per-layout training; with Claude Sonnet or higher, around 12 seconds for a one-page document and around 18 seconds for two pages (average times).

Which ERPs can I write the data into?

The API is system-agnostic: with the REST API and webhooks you write the JSON into SAP, Zucchetti, TeamSystem or any other ERP, CRM or internal application yourself. If you'd rather not build the integration, the AI agent, installed at your premises, posts the data into your ERP on a database, CSV, JSON or TXT files, or APIs, with your ERP credentials kept in your perimeter (Business licence with the add-on, or Enterprise).

What is a webhook?

A webhook is an HTTP request that a service sends automatically to a URL you provide, the moment an event happens — a kind of «reverse API». Instead of repeatedly asking the API whether a document is ready (polling), you register an endpoint and Data Alchemy sends you a POST with the extracted data the instant processing completes. Every webhook is signed with HMAC SHA-256 in the X-Data-Alchemy-Signature header, so you can verify it genuinely came from Data Alchemy before processing it.

Is the REST API included in the licence?

Yes. The REST API and webhooks are included in every licence: Basic, Business and Enterprise. Request your API key from the contact page and start from the documentation on this page. On the Basic licence the API is how you integrate with your ERP; from Business you can add the AI agent.

Build with the developer API

The REST API is included in every licence. Tell us about your use case: we'll give you your API key and walk you through integration on your real documents — no commitment.

Request your API key