Get started

    Quickstart

    Generate a Word document from a DocDealer template in a single API call, with curl, Python or TypeScript.

    One request creates a document from a template, fills the form, generates every section, and returns a .docx. Use it when you want a finished document and don't need to hold state in between.

    Before you start

    Mint an API key at /admin/api-keys (see Authentication). The plaintext is shown once. Give it at least documents:write.

    Generate in one call

    POST /api/documents/generate is the whole flow. Pass a templateId and it creates the document for you; pass a documentId instead to reuse one you already have.

    curl
    curl -X POST https://thedocdealer.com/api/documents/generate \
      -H "Authorization: Bearer $DOCDEALER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "templateId": "2359ce30-66f2-4f02-be82-d2231a2a5ec3",
        "title": "Poder — Ana Torres",
        "formData": {
          "intro._count": 1,
          "intro.0.fecha": "2026-08-24",
          "intro.0.notario": "Salvador Farres Ripoll"
        },
        "validateForm": true,
        "strict": true
      }'

    The response is { documentId, blob, filename, warnings }, where blob is the DOCX base64-encoded. Ask for "returnHtml": true and you get html instead, with no blob.

    Getting formData right

    This is where integrations usually stumble. Keys are flat and dotted:

    formData shape
    {
      "comparecientes._count": 2,
      "comparecientes.0.nombre": "Ana Torres",
      "comparecientes.1.nombre": "Luis Gil"
    }

    The pattern is objectKey.entryIndex.fieldKey, plus one objectKey._count per repeating object saying how many entries it has. Read the keys from a template's formSchema: GET /api/templates/{templateId} returns objects and fields, and each field's fieldKey (falling back to its id) is what goes in the key.

    An unrecognised key fails the whole request, and the error names the valid patterns — worth reading rather than guessing.

    Full example

    Same flow in three languages — pick one.

    Python (stdlib only)
    import base64, json, os, urllib.request
    
    API = "https://thedocdealer.com"
    KEY = os.environ["DOCDEALER_API_KEY"]
    
    def call(path, payload=None):
        data = json.dumps(payload).encode() if payload is not None else None
        req = urllib.request.Request(
            f"{API}{path}",
            data=data,
            method="POST" if data else "GET",
            headers={
                "Authorization": f"Bearer {KEY}",
                "Accept": "application/json",
                **({"Content-Type": "application/json"} if data else {}),
            },
        )
        with urllib.request.urlopen(req) as r:
            return json.loads(r.read())
    
    # 1. Find a template.
    template = call("/api/templates")["templates"][0]
    
    # 2. Read its form schema to learn the field keys.
    schema = call(f"/api/templates/{template['id']}")["formSchema"]
    
    # 3. Generate. One call creates the document, fills it, and renders the DOCX.
    result = call("/api/documents/generate", {
        "templateId": template["id"],
        "title": "Poder — Ana Torres",
        "formData": {"intro._count": 1, "intro.0.fecha": "2026-08-24"},
        "validateForm": True,
        "strict": True,
    })
    
    with open(result["filename"], "wb") as f:
        f.write(base64.b64decode(result["blob"]))
    print("wrote", result["filename"], "document", result["documentId"])

    Flags worth knowing

    • validateForm — runs form validation alongside generation and returns warnings.form. Off by default.
    • strict — fail the whole request if any phase fails, instead of returning a partial document. Off by default, except for ephemeral runs.
    • ephemeral — run entirely in memory with no document row. Requires templateSource rather than a stored template.
    • generateTitle — defaults to true only when you omit title.

    Next

    Need attachments, OCR, or step-by-step control instead of one shot? See Documents. Want your users editing in your own app? See Embedding.