PDF Workflows

PDF Workflows allow you to automate the process of sending physical mail from PDF files. Instead of manually splitting multi-page PDFs, extracting addresses, and creating individual letter orders, you can define a reusable workflow that does it all in one step.

This is ideal for businesses that receive bulk PDFs (e.g. invoices, statements, notices) and need to extract recipient addresses directly from the pages and send each one as a separate letter. It also supports sending pre-formatted PDFs as letters when you already know the recipient and sender details.

Overview

There are two stages in the process of sending mail with PDF Workflows:

  1. Create a Workflow — Define a reusable set of jobs (e.g. rotate pages, resize, extract addresses and send letters).
  2. Run the Workflow — Upload a PDF to execute the workflow. PostGrid processes the PDF, extracts the necessary information, and creates letter orders automatically.

If you want to review orders before they are sent, you can enable confirmation mode, which pauses the workflow after processing so you can inspect the pending orders and confirm before any mail goes out.


Getting Started

To use PDF Workflows, you will need your PostGrid API key. You can find your API key on your PostGrid dashboard settings page.

All requests are made to the base URL:

https://api.postgrid.com/print-mail/v1/pdf_workflows

Note: PDF Workflows are available in both test and live modes. In test mode, letter orders are created but no actual mail is sent. Use test mode to verify that addresses are being extracted correctly and letters look as expected before switching to live mode.


Step 1: Create a Workflow

A workflow is a reusable definition that describes what to do with a PDF when it is uploaded. You define it once and can run it as many times as you like with different PDFs.

Each workflow contains an ordered list of jobs. Jobs are processed sequentially - the output of one job feeds into the next.

Available Job Types

JobKeyDescription
Landscape to PortraitlandscapeToPortraitRotates any landscape-oriented pages to portrait orientation.
Auto ResizeautoResizeResizes the PDF pages to a target letter size (us_letter or us_legal).
Extract Info & Send LetterextractInfoSendLetterExtracts recipient and sender addresses from defined regions on each page, then creates and sends a letter order for each one.
Send LettersendLetterSends the uploaded PDF as a letter using contact details you provide directly (via defaultParams on the workflow and params on the run), rather than extracting addresses from the PDF.

Important: Workflows must end with a send job (extractInfoSendLetter or sendLetter). You cannot have multiple send jobs in a single workflow, and the send job must always be the last one in the chain.

Job Sequencing Rules

Not every combination of jobs is valid. The table below shows which job types can precede each other:

JobCan follow
landscapeToPortraitautoResize, or be the first job
autoResizelandscapeToPortrait, or be the first job
extractInfoSendLetterlandscapeToPortrait, autoResize, or be the first job
sendLetterlandscapeToPortrait, autoResize, or be the first job

For example, a valid three-job workflow might be: landscapeToPortraitautoResizeextractInfoSendLetter.

Creating the Workflow

To create a workflow, send a POST request to /pdf_workflows.

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "requireConfirmationBeforeSending": false,
    "jobs": [
      {
        "extractInfoSendLetter": {
          "color": true,
          "doubleSided": false,
          "addressPlacement": "insert_blank_page",
          "fromRegion": {
            "left": 3.18,
            "top": 0.98,
            "width": 1.92,
            "height": 0.54
          },
          "fromCountryCode": "CA",
          "toRegion": {
            "left": 0.35,
            "top": 2.1,
            "width": 3.13,
            "height": 0.51
          },
          "toCountryCode": "CA"
        }
      }
    ]
  }'

This creates a workflow with a single job that extracts addresses from defined regions on each page and sends coloured letters with the address printed on a separate blank page.

Workflow Parameters

ParameterTypeRequiredDescription
jobsarrayYesAn ordered list of jobs to run. Minimum 1, maximum 3.
requireConfirmationBeforeSendingbooleanNoIf true (default), the workflow pauses after processing so you can review pending orders before they are sent. Set to false to send automatically.
descriptionstringNoAn internal description for your reference.
metadataobjectNoArbitrary key-value pairs to attach to the workflow.

Extract Info & Send Letter Parameters

The extractInfoSendLetter job is the most common job type. It extracts recipient and sender addresses from specific regions of the PDF and creates letter orders.

ParameterTypeRequiredDescription
toRegionobjectYesThe region on the page where the recipient's address is located.
toCountryCodestringYesThe recipient's country code in ISO 3166-1 Alpha-2 format (e.g., CA, US, GB).
fromRegionobjectNo*The region on the page where the sender's address is located.
fromCountryCodestringNo*The sender's country code in ISO 3166-1 Alpha-2 format.
fromContactstringNo*A PostGrid contact ID to use as the sender instead of extracting from the PDF.
colorbooleanNoPrint in color. Defaults to false.
doubleSidedbooleanNoPrint double-sided. Defaults to false.
addressPlacementstringNoWhere to place the address: top_first_page (default) or insert_blank_page.
mailingClassstringNoThe mailing class for delivery: first_class, standard_class, express, certified, certified_return_receipt, or registered.

Note: You must provide either fromRegion and fromCountryCode together, or fromContact - but not both. Use fromContact when the sender address is not printed on the PDF or is difficult to extract.

Region Object

Regions define a rectangular area on the PDF page (in inches) where an address can be found. PostGrid reads the text within this region and parses it as an address.

FieldTypeDescription
leftnumberDistance in inches from the left edge of the page.
topnumberDistance in inches from the top edge of the page.
widthnumberWidth of the region in inches.
heightnumberHeight of the region in inches.

To determine the correct region coordinates, open your PDF and measure the position of the address block. Most PDF viewers display dimensions in inches or have a measurement tool available.

Send Letter Parameters

The sendLetter job is for cases where you already know the recipient and sender — you provide the contact details directly rather than extracting them from the PDF. The uploaded PDF is used as the letter content as-is.

This job uses two sets of parameters that are merged together at run time:

  1. defaultParams — Defined on the workflow. These are the parameters that stay the same across every run (e.g. the sender address).
  2. params — Provided when creating a run. These are the parameters that change per run (e.g. the recipient address).

The combined parameters must satisfy the requirements for creating a letter (see Sending Letters using the API). At minimum, you need to and from contacts between the two.

ParameterTypeRequiredDescription
defaultParamsobjectYesDefault letter creation parameters. Typically includes the from contact and any print options.

Example defaultParams:

{
  "from": {
    "firstName": "Jane",
    "addressLine1": "145 Mulberry St",
    "city": "New York",
    "provinceOrState": "NY",
    "postalOrZip": "10013"
  }
}

Note: When using sendLetter, the params field on the run is required to supply any remaining letter fields not covered by defaultParams. If the combined defaultParams and params do not contain all required letter fields (such as to), the run creation will return a 400 error.


Step 2: Run the Workflow

Once your workflow is created, you can run it by uploading a PDF. Each run processes the PDF through all the jobs defined in the workflow.

To create a run, send a POST request to /pdf_workflows/<pdf_workflow_id>/runs with the PDF file attached.

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs \
  -H "x-api-key: <your-api-key>" \
  -F "pdf=@/path/to/your/file.pdf"

You can also provide a publicly accessible URL to a PDF instead of uploading the file directly:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "pdf": "https://example.com/your-file.pdf"
  }'

Run Parameters

ParameterTypeRequiredDescription
pdffile or URLYesThe PDF to process. Either upload a file or provide a publicly accessible URL.
paramsobjectNoAdditional parameters to pass to the workflow run. When using a sendLetter job, these are merged with the workflow's defaultParams to form the full letter creation request (e.g. the to contact).
descriptionstringNoAn internal description for your reference.
metadataobjectNoArbitrary key-value pairs to attach to the run.

Workflow Run Statuses

After you create a run, it progresses through the following statuses:

StatusDescription
queuedThe run has been created and is waiting to be processed.
processingThe PDF is being processed (pages rotated, resized, addresses extracted).
waiting_for_confirmationProcessing is complete. Pending orders have been created and are waiting for your confirmation before any mail is sent. Only applies when requireConfirmationBeforeSending is true.
creating_ordersConfirmation received. Letter orders are being created.
completedAll orders have been created. A CSV report is available.
failedSomething went wrong during processing. Check the failure.note field for details.

Step 3: Review and Confirm (Optional)

If your workflow has requireConfirmationBeforeSending set to true (the default), the run will pause at waiting_for_confirmation after processing. This gives you the opportunity to review exactly what PostGrid is about to send before any mail goes out.

List Pending Orders

To see the pending orders for a run:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs/<run_id>/pending_orders \
  -H "x-api-key: <your-api-key>"

Each pending order includes the extracted address information and a link to download the PDF that would be sent. Review these to make sure the addresses were extracted correctly and the letter content looks right.

Confirm the Run

Once you are satisfied, confirm the run to proceed with creating the letter orders:

curl -X POST https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs/<run_id>/confirm \
  -H "x-api-key: <your-api-key>"

After confirmation, the run status changes to creating_orders and then completed once all letters have been created.

Important: You can only confirm a run that is in the waiting_for_confirmation status. Attempting to confirm a run in any other status will return an error.


Tracking and Reports

Once a run reaches the completed status, a CSV report is generated that shows the result for each pending order — whether the letter was successfully created or if there was an error (e.g., an invalid address).

Retrieve a Run

To check the status of a run and access the report:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs/<run_id> \
  -H "x-api-key: <your-api-key>"

The response includes:

  • status — The current status of the run.
  • uploadedPDF — A URL to download the original PDF that was uploaded.
  • report — A URL to download the CSV report (available once the run is completed).
  • failure — If the run failed, this object contains a note explaining what went wrong.

List All Runs

To see all runs for a specific workflow:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs \
  -H "x-api-key: <your-api-key>"

Managing Workflows

Retrieve a Workflow

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id> \
  -H "x-api-key: <your-api-key>"

List All Workflows

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
  -H "x-api-key: <your-api-key>"

Delete a Workflow

curl -X DELETE https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id> \
  -H "x-api-key: <your-api-key>"

Chaining Multiple Jobs

For PDFs that need pre-processing before addresses can be extracted, you can chain multiple jobs together. Jobs run in order — the output of one job is the input to the next.

Example: Rotate and Send

If your PDF contains a mix of landscape and portrait pages, add a landscapeToPortrait job before the send job to ensure all pages are in the correct orientation:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "requireConfirmationBeforeSending": true,
    "jobs": [
      {
        "landscapeToPortrait": {
          "rotateCounterClockwise": false
        }
      },
      {
        "extractInfoSendLetter": {
          "color": true,
          "doubleSided": false,
          "addressPlacement": "insert_blank_page",
          "toRegion": {
            "left": 0.35,
            "top": 2.1,
            "width": 3.13,
            "height": 0.51
          },
          "toCountryCode": "US",
          "fromContact": "contact_abc123"
        }
      }
    ]
  }'

In this example, we use fromContact instead of fromRegion to specify the sender. This is useful when the sender address is not printed on the PDF or when the same sender is used for all letters.

Example: Resize and Send

If your PDF pages are not standard letter size, add an autoResize job to resize them before sending:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "jobs": [
      {
        "autoResize": {
          "size": "us_letter"
        }
      },
      {
        "extractInfoSendLetter": {
          "color": false,
          "addressPlacement": "top_first_page",
          "toRegion": {
            "left": 0.5,
            "top": 2.0,
            "width": 3.0,
            "height": 0.5
          },
          "toCountryCode": "US",
          "fromRegion": {
            "left": 3.5,
            "top": 0.5,
            "width": 2.0,
            "height": 0.5
          },
          "fromCountryCode": "US"
        }
      }
    ]
  }'

Example: Send a PDF Directly

If you already know the recipient and sender addresses and just want to send a PDF as a letter, use the sendLetter job. Define the sender in the workflow's defaultParams, and pass the recipient when creating each run:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "requireConfirmationBeforeSending": false,
    "jobs": [
      {
        "sendLetter": {
          "defaultParams": {
            "from": {
              "firstName": "Jane",
              "addressLine1": "145 Mulberry St",
              "city": "New York",
              "provinceOrState": "NY",
              "postalOrZip": "10013"
            }
          }
        }
      }
    ]
  }'

Then create a run, providing the recipient via params:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/<pdf_workflow_id>/runs \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "pdf": "https://example.com/invoice.pdf",
    "params": {
      "to": {
        "firstName": "John",
        "addressLine1": "200 University Ave W",
        "city": "Waterloo",
        "provinceOrState": "ON",
        "postalOrZip": "N2L 3G1"
      }
    }
  }'

This approach is useful when you have pre-formatted PDFs that don't contain addresses on the page, or when you want to leverage the workflow's async processing, confirmation, and reporting features for straightforward letter sends.

Example: Full Pipeline

For the most robust setup, combine all three jobs — rotate, resize, then extract and send:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{
    "requireConfirmationBeforeSending": true,
    "jobs": [
      {
        "landscapeToPortrait": {}
      },
      {
        "autoResize": {
          "size": "us_letter"
        }
      },
      {
        "extractInfoSendLetter": {
          "color": true,
          "doubleSided": true,
          "addressPlacement": "insert_blank_page",
          "toRegion": {
            "left": 0.35,
            "top": 2.1,
            "width": 3.13,
            "height": 0.51
          },
          "toCountryCode": "CA",
          "fromRegion": {
            "left": 3.18,
            "top": 0.98,
            "width": 1.92,
            "height": 0.54
          },
          "fromCountryCode": "CA"
        }
      }
    ]
  }'

Quick Reference

ActionMethodEndpoint
Create a workflowPOST/pdf_workflows
Retrieve a workflowGET/pdf_workflows/:id
List workflowsGET/pdf_workflows
Delete a workflowDELETE/pdf_workflows/:id
Create a runPOST/pdf_workflows/:id/runs
Retrieve a runGET/pdf_workflows/:id/runs/:runID
List runsGET/pdf_workflows/:id/runs
List pending ordersGET/pdf_workflows/:id/runs/:runID/pending_orders
Confirm a runPOST/pdf_workflows/:id/runs/:runID/confirm