> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pdfnoodle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Asynchronous request

> Asynchronous means that the request will return immediately with a requestId (if the request passes validation), but the pdf file will be sent after a few seconds to your custom webhook.

<Success>
  We recommend using asynchronous requests for better performance on your
  application.
</Success>

POST [https://api.pdfnoodle.com/v1/pdf/async](https://api.pdfnoodle.com/v1/pdf/async)

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl --location 'https://api.pdfnoodle.com/v1/pdf/async' \
  --header 'Authorization: Bearer pdfnoodle_api_123456789' \
  --header 'Content-Type: application/json' \
  --data '{
      "templateId": "check",
      "webhook": "https://webhook.url",
      "data": {
          "currentDDate": "01/12/2025",
          "user": {
              "name": "John Doe",
              "email": "john.doe@email.com"
          },
          "details": [{"score": "100", "description": "high score"}]
      }
  }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.pdfnoodle.com/v1/pdf/async", {
    method: "POST",
    headers: {
      Authorization: "Bearer pdfnoodle_api_123456789",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      templateId: "check",
      webhook: "https://webhook.url",
      data: {
        currentDDate: "01/12/2025",
        user: {
          name: "John Doe",
          email: "john.doe@email.com",
        },
        details: [{ score: "100", description: "high score" }],
      },
    }),
  });

  const result = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.pdfnoodle.com/v1/pdf/async',
      headers={
          'Authorization': 'Bearer pdfnoodle_api_123456789',
          'Content-Type': 'application/json'
      },
      json={
          'templateId': 'check',
          'webhook': 'https://webhook.url',
          'data': {
              'currentDDate': '01/12/2025',
              'user': {
                  'name': 'John Doe',
                  'email': 'john.doe@email.com'
              },
              'details': [{'score': '100', 'description': 'high score'}]
          }
      }
  )

  result = response.json()
  ```
</CodeGroup>

## Response

<CodeGroup>
  ```json Immediate Response (200 OK) theme={null}
  {
    "requestId": "pdfnoodle_request_123456789"
  }
  ```

  ```json Webhook Response (SUCCESS) theme={null}
  {
    "requestId": "pdfnoodle_request_123456789",
    "renderStatus": "SUCCESS",
    "signedUrl": "https://pdforge-production.s3.us-east-2.amazonaws.com/...",
    "metadata": {
      "executionTime": "1.805 seconds",
      "fileSize": "4.066 kB"
    }
  }
  ```

  ```json Webhook Response (FAILED) theme={null}
  {
    "requestId": "pdfnoodle_request_123456789",
    "renderStatus": "FAILED",
    "signedUrl": "",
    "metadata": {}
  }
  ```
</CodeGroup>

This endpoint responds with `200 OK` immediately with a `requestId`. After a few seconds, the PDF file will be generated and we will send a POST to your webhook with the response body shown above.

The `renderStatus` could be either `SUCCESS` or `FAILED`.

<Danger>
  If the request `FAILED`, you should contact support to figure out why your PDF
  generation failed.
</Danger>

The response body will contain a `signedUrl` key which is a temporary URL pointing to the generated PDF file on our S3 bucket. If you passed a custom `s3_bucket`, it'll be stored there instead. This URL will expire after the time specified in `signedUrlExpiresIn` (default: 1 hour).

### PDF Render Metadata

We'll also bring some additional metadata from your PDF render with every response:

* **executionTime** - Time in seconds it took to generate your PDF
* **fileSize** - PDF size in kiloBytes

## Parameters

<ParamField body="templateId" type="string" required>
  The id of your PDF template
</ParamField>

<ParamField body="webhook" type="string" required>
  The url of your webhook
</ParamField>

<ParamField body="data" type="object" required>
  The object containing the variables from your PDF template
</ParamField>

<ParamField body="convertToImage" type="boolean" default="false">
  If true, will return a .PNG file instead of a .PDF file
</ParamField>

<ParamField body="metadata" type="object">
  This object containing the metadata for your PDF. [See all the options
  here](/api-reference/options/pdf-metadata).
</ParamField>

<ParamField body="s3_bucket" type="string">
  The id of the active s3 connection you want to store your generated file on.
  (only available in the high plan)
</ParamField>

<ParamField body="s3_key" type="string">
  The path, including subdirectories and the filename without extension, to use
  when saving the render in your S3 bucket. (only available if being stored in
  custom s3\_bucket)
</ParamField>

<ParamField body="signedUrlExpiresIn" type="number" default="3600">
  Number of seconds that the generated signed URL will take to expire (default:
  1 hour)
</ParamField>

<ParamField body="externalId" type="string">
  If you're using our embedded white-label solution, you can pass the UUID of
  your customer to generate the PDF of the customized template
</ParamField>

<ParamField body="hasCover" type="boolean" default="false">
  If true, will hide the footer and the header elements on the first page of the
  generated PDF
</ParamField>

<ParamField body="debug" type="boolean" default="false">
  If true, will enter Debug Mode and show additional properties on the response
  to help you figure out your variables and html rendered content. [Here's
  everything you need to know about Debug
  Mode](/api-reference/options/debug-mode)
</ParamField>

## Checking PDF Status

Instead of waiting for the webhook, you can also check the status of your PDF generation by polling the [Get PDF Status](/api-reference/pdf-status/get) endpoint using the `requestId` returned from this request.
