> For the complete documentation index, see [llms.txt](https://docs.uptiq.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.uptiq.ai/document-ai/cookbooks/generate-a-document.md).

# Generate a document

**Goal.** Turn structured data — borrower details, terms, schedules — into a finished, styled document your business can send.

This runs the pipeline in the opposite direction to extraction. You supply sections of data; the platform returns a rendered file and a download URL.

### Generated endpoint reference

Use [Generate a document asynchronously](/document-ai/developer-documentation/generation-1/generate-document-async.md) or [generate a document synchronously](/document-ai/developer-documentation/generation-1/synchronous-document-generation.md) for request schemas. [Get generation details](/document-ai/developer-documentation/generation-1/get-document-generation-details.md) documents the retrieval endpoint.

### Before you start

* An API key, exported as `$DOCAI_API_KEY`.
* Your content, organised into sections.

### Step 1 — Structure the content

`data` is the one required property: an array of at least one section. Each section pairs a `sectionKey` with its `sectionData`.

```json
{
  "data": [
    {
      "sectionKey": "borrower",
      "sectionData": {
        "name": "Northwind Trading Co.",
        "entityType": "Corporation",
        "address": "44 Harbour Road, Portland, OR"
      }
    },
    {
      "sectionKey": "terms",
      "sectionData": {
        "principal": 250000,
        "ratePct": 7.25,
        "termMonths": 60
      }
    }
  ],
  "format": "docx"
}
```

`sectionKey` must be unique within the array. Order the array the way you want the document to read.

{% hint style="warning" %}
`format` currently supports **`docx` only**, and that is what it defaults to. Asking for `"PDF"` is not a supported request — if you need PDF, convert after generation.
{% endhint %}

### Step 2 — Style it

`style` is optional and controls presentation:

```json
{
  "style": {
    "lenderName": "Example Bank",
    "fontFamily": "Calibri",
    "fontSize": 11,
    "primaryColor": "#1a4d80",
    "secondaryColor": "6c757d",
    "headerFooter": true,
    "pageNumbers": true,
    "tableOfContents": true
  }
}
```

`fontSize` accepts 8–72. Colours take hex with or without the leading `#`.

Keep a single style object in your configuration rather than repeating it per call — it is the part most likely to change when branding does.

### Step 3 — Generate

Asynchronous, returning `201`:

```bash
curl -X POST "https://api-docai-uat.uptiq.ai/generate" \
  -H "X-Api-Key: $DOCAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @generate.json
```

```json
{
  "success": true,
  "generationId": "fb728716-0300-49bb-ae17-f7b480d37544",
  "requestId": "36a8be90-5d19-4133-b102-9a755f60ec21",
  "status": "Pending",
  "message": "Document generation job created successfully"
}
```

Note the field is `generationId`, not `_id` — generation names its identifier differently from extraction and classification.

{% hint style="info" %}
Generation is the only capability whose request takes its own **`webhookUrl`** (HTTPS required). You can direct an individual job to an endpoint without touching account settings — extraction and classification cannot do this.
{% endhint %}

### Step 4 — Collect the document

{% hint style="danger" %}
**`GET /generate/{_id}` does not currently work.** Every call returns `500` with `"Invalid generation ID format"` — including when passed the exact `generationId` the API itself just issued. Tested against the returned UUID, a stripped form, a prefixed form and a nil UUID: all `500`. There is no ID format that succeeds.

Until it is fixed, **do not build on the async retrieval path.** Use one of the two routes below instead.
{% endhint %}

**Route A — `POST /generate/sync`.** The simplest working option: it returns the finished file directly on the same connection.

```bash
curl -X POST "https://api-docai-uat.uptiq.ai/generate/sync" \
  -H "X-Api-Key: $DOCAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @generate.json \
  -o loan-agreement.docx
```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Disposition: attachment; filename="document.docx"
Content-Length: 10193
```

{% hint style="warning" %}
This response is the **binary document itself**, not JSON. There is no envelope, no `status` field, and nothing to parse — write the body straight to a file. A client that calls `.json()` on it will throw.
{% endhint %}

**Route B — the webhook.** Set `webhookUrl` on the async request and take the download URL from the completion payload, which is covered in step 5.

Generation is fast enough that the synchronous route is reasonable for most cases — unlike extraction, where a \~90-second hold makes it impractical.

### Step 5 — Or let the webhook bring it

If you set `webhookUrl`, the completion payload arrives with the download URL already in it:

```json
{
  "_id": "60d5ec18…",
  "status": "Processed",
  "format": "PDF",
  "downloadUrl": "https://signed-url…",
  "storageInfo": { },
  "error": null,
  "eventId": "evt_jkl012"
}
```

Verify the signature before acting on it — see [Webhook payloads](/document-ai/developer-documentation/getting-started/webhook-payloads.md).

### When it goes wrong

| Symptom                                          | Cause                                            | Fix                                          |
| ------------------------------------------------ | ------------------------------------------------ | -------------------------------------------- |
| `400` on submit                                  | `data` missing or empty                          | At least one section is required             |
| `400` mentioning sections                        | Duplicate `sectionKey`                           | Keys must be unique within `data`            |
| `500 "Invalid generation ID format"` on retrieve | The endpoint is broken for all IDs — not your ID | Use `/generate/sync` or a webhook            |
| JSON parse error on `/generate/sync`             | The response is a binary DOCX                    | Write the body to a file; do not parse it    |
| Download 403s                                    | The signed webhook URL expired                   | Signed URLs are time-limited; fetch promptly |
| Unexpected file type                             | `format` only supports `docx`                    | Convert downstream                           |
| Webhook never arrives                            | `webhookUrl` was not HTTPS                       | HTTPS is required                            |

### Related pages

* [Generation API](/document-ai/developer-documentation/integration-guides/generation.md) — all three endpoints and the full schema.
* [Document Generation](/document-ai/guides-1/document-generation.md) — the same capability in the UI.
* [Webhook payloads](/document-ai/developer-documentation/getting-started/webhook-payloads.md) — the generation completion payload.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.uptiq.ai/document-ai/cookbooks/generate-a-document.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
