Custom JSON schema extraction

Instead of the whole content of a document you can ask for specific fields. You describe them with a JSON Schema and send it in the schema field together with format=json. DocSlice reads the document, extracts the values and returns an object that follows your schema.

Extract fields with a JSON Schema
SCHEMA='{"type":"object","properties":{"invoice_number":{"type":"string","description":"Invoice number"},"date":{"type":"string","description":"Issue date, YYYY-MM-DD"},"total":{"type":"number","description":"Total amount"}},"required":["invoice_number","total"]}'

curl -s https://api.docslice.app/v1/convert \
  -H "Authorization: Bearer $DOCSLICE_API_KEY" \
  -F "file=@invoice.pdf" \
  -F "format=json" \
  -F "schema=$SCHEMA"
import json
import os
import requests

api_key = os.environ["DOCSLICE_API_KEY"]
schema = {
    "type": "object",
    "properties": {
        "invoice_number": {"type": "string", "description": "Invoice number"},
        "date": {"type": "string", "description": "Issue date, YYYY-MM-DD"},
        "total": {"type": "number", "description": "Total amount"},
    },
    "required": ["invoice_number", "total"],
}

with open("invoice.pdf", "rb") as handle:
    response = requests.post(
        "https://api.docslice.app/v1/convert",
        headers={"Authorization": f"Bearer {api_key}"},
        files={"file": ("invoice.pdf", handle, "application/pdf")},
        data={"format": "json", "schema": json.dumps(schema)},
        timeout=120,
    )

print(json.dumps(response.json(), indent=2))
const fs = require("node:fs");

const schema = {
  type: "object",
  properties: {
    invoice_number: { type: "string", description: "Invoice number" },
    date: { type: "string", description: "Issue date, YYYY-MM-DD" },
    total: { type: "number", description: "Total amount" },
  },
  required: ["invoice_number", "total"],
};

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("invoice.pdf")], { type: "application/pdf" }), "invoice.pdf");
form.append("format", "json");
form.append("schema", JSON.stringify(schema));

fetch("https://api.docslice.app/v1/convert", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.DOCSLICE_API_KEY}` },
  body: form,
})
  .then((response) => response.json())
  .then((data) => console.log(JSON.stringify(data, null, 2)));
<?php
$schema = [
    'type' => 'object',
    'properties' => [
        'invoice_number' => ['type' => 'string', 'description' => 'Invoice number'],
        'date' => ['type' => 'string', 'description' => 'Issue date, YYYY-MM-DD'],
        'total' => ['type' => 'number', 'description' => 'Total amount'],
    ],
    'required' => ['invoice_number', 'total'],
];

$curl = curl_init('https://api.docslice.app/v1/convert');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('DOCSLICE_API_KEY')],
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('invoice.pdf', 'application/pdf', 'invoice.pdf'),
        'format' => 'json',
        'schema' => json_encode($schema),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 120,
]);
echo curl_exec($curl);
curl_close($curl);

Write a good schema

{
  "type": "object",
  "properties": {
    "invoice_number": {"type": "string", "description": "Invoice number"},
    "date": {"type": "string", "description": "Issue date, YYYY-MM-DD"},
    "total": {"type": "number", "description": "Total amount"}
  },
  "required": ["invoice_number", "total"]
}
  • Give every property a type and a short description. The description is what tells the extractor what to look for and in which format.
  • Use required for the fields you cannot do without.
  • Keep names stable and meaningful: they become the keys of your answer.

Rules

A schema must be a JSON object with a non-empty properties object, and each property must itself be an object. Regular-expression keywords are not accepted. A schema that does not follow the rules is refused with 400 and a message that says why, for example Schema must define a non-empty 'properties' object; a value that is not valid JSON is refused with Invalid JSON schema provided.

Reading the answer

  • schema_applied is true when the AI layer extracted the values and they conform to your schema. If it is false, data is not a verified match for your schema: either the AI extractor was unavailable and a simpler matcher answered, or the AI answered with data that does not conform to the schema (a missing required field, a wrong type). In both cases the request still succeeds, so check schema_applied and validate data in your own code before relying on it.
  • input_truncated is true when the document text is longer than the 25,000 characters sent to the extractor: the text beyond that limit was not read. Split very long documents, or extract from the part that matters.
  • Pages are counted as for any conversion.

Tips

  • Ask only for what a reader could find in the document, and check optional fields in your own code before relying on them.
  • Use clear formats in descriptions (YYYY-MM-DD, "amount as a number without currency symbol").
  • For repeated structures, such as invoice lines, describe an array of objects.