PDF Workflows

Prepare and send your PDF files with a single API call and no additional code or infrastructure.

NOTE: This feature is currently in beta and the schema of the requests/responses discussed here is subject to change.

Let's say you have some PDF documents you want to mail out but they're not formatted correctly for submission to PostGrid. For example, you have a software that generates print-ready PDFs but the pages are inconsistently sized/rotated. Rather than writing custom code to modify your PDFs (which is rather difficult to do), you can leverage PostGrid's low-code PDF workflows feature.

PDF workflows consist of a series of "jobs" that will run on your PDF in order to fix it up and mail it out. See this section for all the supported job types. You create a workflow once and subsequently create "runs" under that PDF workflow every time you want to process a PDF file.

Examples

Automatically resize PDF and mail it to specific contact IDs

We start by creating a PDF workflow with the following API call:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows \
    -u "{YOUR API KEY}:" \
    -H "Content-Type: application/json" \
    --data '{
        "requireConfirmationBeforeSending": false,
        "jobs": [
            {
            	"autoResize": {
              	"size": "us_letter"
              }
            },
            {
            	"sendLetter": {
              	"defaultParams": {
                	"from": "contact_veJC78LS8uc3AchB3mbZi7"
                }
              }
            }
          ]
        }'

Note how each value in the jobs array is an object containing exactly one field: the job type (autoResize) and parameters for that job { "size": "us_letter" }. We've sequenced the sendLetter job after the autoResize job so that the resized PDF gets fed into the sendLetter step. We've also specified a default from contact in the sendLetter job. We can override this (and provide the to contact) when we create the PDF workflow run later. Any parameters that you provide to a regular letter creation API call can be provided under defaultParams.

Also note the requireConfirmationBeforeSending. By default, PDF workflows will hold orders until you have a chance to review and confirm them with a separate endpoint. In this case, we just want it to send them out automatically, so we set that to false.

Here's the response we get:

{
  "id": "pdf_workflow_i5KAPmuxcrsWBnWb3NVkaX",
  "object": "pdf_workflow",
  "live": false,
  "jobs": [
    {
      "autoResize": {
        "size": "us_letter"
      }
    },
    {
      "sendLetter": {
        "defaultParams": {
          "from": "contact_veJC78LS8uc3AchB3mbZi7"
        }
      }
    }
  ],
  "requireConfirmationBeforeSending": false,
  "createdAt": "2024-02-27T01:03:37.763Z",
  "updatedAt": "2024-02-27T01:03:37.763Z"
}

Now that we've created the workflow, we can run it on a specific PDF file. To do this, we make another API call:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/pdf_workflow_i5KAPmuxcrsWBnWb3NVkaX/runs \
    -u "{YOUR API KEY}:" \
    -F "pdf=@{PATH TO PDF FILE}" \
    -F "params[to]=contact_veJC78LS8uc3AchB3mbZi7"

In this case, I've specified only the to contact via params, but I could also provide any of the other parameters that a regular letter creation API call takes. See here for all the options.

Here's what that API call returns:

{
  "id": "pdf_workflow_run_hJBqVKjF8UTEk2ZhvG45ds",
  "object": "pdf_workflow_run",
  "live": false,
  "params": {
    "to": "contact_veJC78LS8uc3AchB3mbZi7"
  },
  "status": "queued",
  "uploadedPDF": "https://pg-prod-bucket-1.s3.amazonaws.com/test/pdf_wYzSGfPCC1cQZUVgEHjAFt?AWSAccessKeyId=AKIA5GFUILSULWTWCR64&Expires=1708997481&Signature=sCUbPl7t%2Bxq1YbB%2FuYcAKhgzy7Y%3D",
  "workflow": "pdf_workflow_i5KAPmuxcrsWBnWb3NVkaX",
  "createdAt": "2024-02-27T01:16:21.348Z",
  "updatedAt": "2024-02-27T01:16:21.348Z"
}

We've successfully kicked off this workflow run. Had we not provided all the fields required to create a letter at this point e.g. we omitted the to contact, we'd get a validation_error same as any other order creation API call.

Note how the status field on the workflow run is queued. Since PDF workflows potentially involve many long running operations, all PDF workflows operate asynchronously. Once this job is picked up, the status will be changed to processing, and eventually completed. We can poll the status of a given workflow run with the following endpoint:

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/pdf_workflow_i5KAPmuxcrsWBnWb3NVkaX/runs/pdf_workflow_run_hJBqVKjF8UTEk2ZhvG45ds \
    -u "{YOUR API KEY}:"

You can also list all PDF workflow runs with the following endpoint

curl https://api.postgrid.com/print-mail/v1/pdf_workflows/pdf_workflow_i5KAPmuxcrsWBnWb3NVkaX/runs \
    -u "{YOUR API KEY}:"

Now that our run is done processing (which should be done in less than a minute for small PDFs and a few operations in the PDF workflow), we get the following response:

{
  "id": "pdf_workflow_run_hJBqVKjF8UTEk2ZhvG45ds",
  "object": "pdf_workflow_run",
  "live": false,
  "params": {
    "to": "contact_veJC78LS8uc3AchB3mbZi7"
  },
  "report": "https://pg-prod-bucket-1.s3.amazonaws.com/pdf_workflow_runs/pdf_workflow_run_hJBqVKjF8UTEk2ZhvG45ds/report.csv?AWSAccessKeyId=AKIA5GFUILSULWTWCR64&Expires=1708998232&Signature=wZHFq7ePkvzWeVLsgWvvXs1KF5A%3D",
  "status": "completed",
  "uploadedPDF": "https://pg-prod-bucket-1.s3.amazonaws.com/test/pdf_wYzSGfPCC1cQZUVgEHjAFt?AWSAccessKeyId=AKIA5GFUILSULWTWCR64&Expires=1708998232&Signature=0HO3K9aVfQbp0KfSLksOMXtOOmM%3D",
  "workflow": "pdf_workflow_i5KAPmuxcrsWBnWb3NVkaX",
  "createdAt": "2024-02-27T01:16:21.348Z",
  "updatedAt": "2024-02-27T01:16:27.078Z"
}

We can download the report linked here to get a CSV file of which orders were created from this run. If the resulting PDF had some issues that prevented its order from being created, that would also be surfaced in this report.

In the event that your workflow run failed to process the input PDF, its status field would be failed, and there would be a failure subobject on the workflow run with a note explaining what caused the processing failure.

In this case, since the workflow succeeded, we can figure out which letter was created by either looking at the report or simply calling the GET /letters endpoint and searching for { "pdfWorkflowRun": "pdf_workflow_run_hJBqVKjF8UTEk2ZhvG45ds" }. This this for more information on how you can use structured search in the PostGrid API.

Job Types

Landscape to Portrait

The landscapeToPortrait simply rotates landscape pages such that they become portrait. For example:

{
  "landscapeToPortrait": {
    "rotateCounterClockwise": false
  }
}

This specifies that the job should rotate clockwise (since rotateCounterClockwise is false).

Auto Resize

The autoResize job resizes the pages of the input PDF to a given (logical) size. For example:

{
  "autoResize": {
    "size": "us_letter"
  }
}

This will resize all pages of the PDF file to be us_letter sized (8.5x11 inches). You can alternatively specify us_legal and a4. In the future, this will also support all common PostGrid postcard sizes.

Send Letter

This job effectively forwards the parameters you provide and the PDF (generated after running the jobs in your workflow) to the "Send a Letter PDF" endpoint. You can specify the default parameters to this endpoint in the job definition itself. For example:

{
  "sendLetter": {
    "defaultParams": {
      "from": "contact_veJC78LS8uc3AchB3mbZi7",
      "metadata": {
        "campaign_id": "ABC"
      }
    }
  }
}

Note how I specify both a from contact and some metadata in the default params of the sendLetter job.

Extract Info Send Letter

This job extracts contact information directly from your PDF file and sends a letter to the contact it finds. You must specify the regions where it should look for the contact information. For example:

{
  "extractInfoSendLetter": {
    "color": true,
    "addressPlacement": "insert_blank_page",
    "fromRegion": {
      "left": 0.43,
      "top": 1.47,
      "width": 2.61,
      "height": 0.89
    },
    "fromCountryCode": "US",
    "toRegion": {
      "left": 0.42,
      "top": 2.46,
      "width": 2.67,
      "height": 1.03
    },
    "toCountryCode": "US"
  }
}

Note how I also specify color and addressPlacement here. I can also specify mailingClass. Support for all letter parameters is planned.

In case I don't want the sender address to be picked up from the PDF file, I can omit fromRegion and fromCountryCode and supply a fromContact property with an ID value.

Note that this does not perform OCR and expects that the contact information is surfaced in the PDF as text and not an image.