Guides

    Attachments and OCR

    Upload a file, let DocDealer extract structured data from it, and feed that into the form.

    This is the flow that makes DocDealer worth wiring into a backend rather than filling a form by hand: upload an ID, a deed, a land-registry extract, and have its contents become form values.

    Upload

    Multipart, with file, fileName and documentId. Max 50 MB.

    curl
    curl -X POST https://thedocdealer.com/api/attachments \
      -H "Authorization: Bearer $DOCDEALER_API_KEY" \
      -F "file=@dni.pdf" \
      -F "fileName=dni.pdf" \
      -F "documentId=<uuid>"

    PDFs, images (JPEG/PNG/GIF/WebP/TIFF), Office documents, plain text and CSV are accepted. DOCX is converted to PDF server-side. Identical files are de-duplicated by hash, so re-uploading the same document costs nothing and returns the existing attachment.

    Analyse

    Analysis is asynchronous: start it, then poll.

    It targets a specific file_attachment field, and that is not incidental — the field's schema is what tells the model which shape to extract. Analysing "a PDF" in the abstract would give you prose; analysing it as the dni field of the comparecientes object gives you the name, number and expiry the template actually needs.

    curl
    # Start — returns { "id": "<analysisId>", ... }
    curl -X POST https://thedocdealer.com/api/ai/analyze/attachment \
      -H "Authorization: Bearer $DOCDEALER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "documentId": "<uuid>",
        "attachmentIds": ["<attachmentId>"],
        "fieldId": "field_dni",
        "entryIndex": 0
      }'
    
    # Poll — status: 0 pending, 1 success, 2 error
    curl "https://thedocdealer.com/api/documents/<uuid>/attachment-analyses/<analysisId>" \
      -H "Authorization: Bearer $DOCDEALER_API_KEY"

    Requires the attachments:analyze scope, which spends AI credit. For API-key callers, results are auto-accepted regardless of what you pass for autoAccept — there is no human in the loop to review them.

    Reference the result from the form

    Analyses are referenced, not copied:

    formData
    {
      "comparecientes._count": 1,
      "comparecientes.0.dni": { "type": "attachment_analysis", "$ref": "<analysisId>" }
    }

    The reference is what lets a rule branch on something the model extracted — path: "address.postcode" on a condition reads into the analysis result, so document structure can follow the contents of an uploaded file.

    The upload → analyse flow is mandatory

    There is no shortcut for callers who already hold the extracted data. A file_attachment field accepts exactly one value shape — a reference to a real analysis:

    the only accepted shape
    { "type": "attachment_analysis", "$ref": "<analysisId>" }

    Anything else on such a field is rejected with 403 and this message:

    Field "comparecientes.0.dni" is a file attachment — do not set it directly and never
    inline extracted data. Call create_attachment_upload_url, upload the file from disk,
    then analyze_attachments, which fills this field from the real extraction.

    In particular, inlining { "type": "attachment_analysis", "data": { "analysisResult": … } } does not work, even though it looks like it should. The server requires a non-empty $ref to an analysis it created, so provenance always traces back to a real uploaded file and a real extraction.

    So a migration of existing records still has to push the source files through POST /api/attachments and POST /api/ai/analyze/attachment. That costs an analyze_file call per document, which is the expensive call type — budget for it rather than being surprised by it.

    Cost

    analyze_file is one of the two expensive call types — it is a vision call over a whole document. Two things follow:

    • De-duplication is free money. The same file uploaded twice is analysed once.
    • Re-triggering is not cached. Asking for analysis again means you want a fresh result, so it runs again. Do not poll by re-posting.

    Mint a key without attachments:analyze for any integration that only needs to read or attach files. See Authentication.