Lob’s website experience is not optimized for Internet Explorer.
Please choose another browser.


Best Practices for Using Lob’s Print & Mail and Address Verification APIs

Design Guidelines

When you send an API request to Lob, you are sending 3 pieces of information: the to address, the from address, and the content. Below are some best practices to follow when designing content for Lob.



For example, for postcards you'll notice that the file that you are sending is actually 4.25" x 6.25" instead of 4" x 6". This extra space is what we call the bleed area. The bleed area is included to ensure that artwork gets printed to the edge - artwork gets printed with larger dimensions and is subsequently trimmed down. Although, backgrounds and graphics should be extended into the bleed area as shown with the background in the above example. Not having them extend into the bleed area could result in a white or unprinted border around the edge of the postcard.


Keep all text within the safe zone to make sure no important content is cut off.


On the postcard, there is a space marked off as *RED: INK-FREE AREA*. Anything in this area will not be printed to leave room for the postage and address information.


The sizes of our mail pieces and their respective templates can be found in our documentation. The API will return an error if you input a non-HTML file with the incorrect dimensions.



We highly recommend all our customers use HTML to design their postcards. You have a lot of flexibility when using HTML and can add merge variables into your HTML to easily generate dynamic content. See the articles below for more information on using HTML:

When designing content with HTML, use inline styles or an internal stylesheet. Do not use an external stylesheet. If you are linking to images, make sure they are at least 300 dpi. Because the content is only being designed for a single size, we recommend using absolute positioning, as shown below.

body {
  width: 6.25in;
  height: 4.25in;
  margin: 0;
  padding: 0;
  background-image: url(https://s3-us-west-2.amazonaws.com/public.lob.com/assets/beach.jpg);
  background-size: 6.25in 4.25in;
  background-repeat: no-repeat;

#safe-area {
  position: absolute;
  width: 5.875in;
  height: 3.875in;
  left: 0.1875in;
  top: 0.1875in;
  background-color: rgba(255,255,255,0.5);

PDF Guidelines

Lob processes and prints various types of PDFs, however the below PDF formatting guidelines will help ensure successful and accurate printing. 

  • Transparencies should be flattened. If transparencies are not flattened, overlapping colors may change and objects may disappear completely
  • Fonts must be outlined (preferred) or embedded. Fonts that have not been outlined or embedded might change or render incorrectly, specific letters may be substituted with incorrect glyphs
  • File size should be under 5MB. Lower file size allows for easier processing at the print level. Large files have a higher potential to fail
  • Color should be CMYK Color Space (SWOP v2 or GRACoL 2006 preferred). By submitting CMYK you will avoid potential conversion errors when Lob changes RGB to CMYK
  • Image resolution should be 300 ppi. If resolution is below 300 ppi, you may see pixelation and incorrect color saturation of your images, if ppi greatly exceeds 300 the file size will be too large and have the potential to fail
  • NO Printers Marks. Do not submit printer marks including, but not limited to Crop Marks, Bleed Marks, Slug Lines, Registration Marks, Color Bars, Page Information, etc


When using PNGs or JPEGs with Lob, we require a minimum of 300 dpi. The dpi is calculated as (width of image in pixels) / (width of product in inches) and (length of image in pixels) / (length of product in inches). For example: 1275px x 1875px image used to create a 4.25" x 6.25" postcard has a dpi of 300.


This is a raster image format that can have a transparent background. It is generally a higher quality than other image formats.


This is a raster image format that is often used for photographs. It does not allow for a transparent background.


If you upload an image or send us HTML in your API request, Lob will render and host the content. If you are sending at high volumes, we recommend you host the content yourself on a performant file hosting provider such as Amazon S3 and send us a URL to the content in your API request. By removing the file upload from the API request, you'll be able to reduce your API request time.


To see how your HTML is rendered, create a Test API request either through the API or on the Dashboard. You'll be able to see a PDF proof of exactly what the design looks like. We highly recommend sending yourself a printed piece to verify the mail piece is how you like it.

Example Pieces

Checkout out our Template Gallery for pre-designed templates to help you get started!



Lob's HTML renderer is based off of Webkit. For this reason, using the Safari browser will show previews more accurately. For the best results, we recommend submitting test API requests and reviewing the rendered PDF.


We highly recommend using Adobe Illustrator or Adobe Photoshop to design your content. They'll give you the most flexibility and export options.


We recommend using a developer to convert the PDF to HTML. We'd estimate 15 minutes to 2 hours of development time for the average file. Some applications like Adobe Illustrator come with HTML export options, but the automated tools for doing this today aren't great.

What Should I Test as I Integrate Lob?


Before you go live, verify that your mail pieces are rendering correctly. Lob's dashboard will show proofs of the mail piece you create. The proofs are also available in the API response.


  • Verify your PDF is PDF/A compliant
  • Embed all images and fonts


  • Lob's HTML render is based on Webkit, but is highly modified to be used with Lob. Test rendering by using your test API key and checking the dashboard for proofs, instead of designing using the browser.


  • Verify that your images are at least 300 DPI. This will prevent blurry prints.


As you integrate Lob, you may find it useful to view logs of your requests. If you send a request with your test or live API key, both the request and response will be logged here for you to debug with.

HTML Templates

Easily create, view, edit, and manage your postcard, self-mailer, letter, and check HTML templates by saving them within Lob's system.

NOTE: In Live mode, you can only have as many non-deleted templates as allotted in your current Print & Mail Edition. There is no limit in Test mode.


Templates can be created from your Dashboard. Any parameter that accepts HTML in postcard, self-mailer, letter, or check creation can also accept a template. When creating a template, you need to pass two pieces of information:

  • An optional description
  • The HTML for your template

While it is optional, we highly recommend adding a description so you can easily identify your template within Lob. As for the HTML design, you can start off with a pre-designed template from our gallery or follow these basic guidelines to get started. Templates are compatible with merge variables, which we encourage using for creating dynamic, custom content. For more detailed guidelines and best practices around creating HTML designs, please see our documentation.

Both the description and your HTML can be edited easily afterwards, so don't worry about getting things perfect.

Like all Lob resources, you can create templates in both your Test and your Live Environment. Templates created in the Test Environment will only be usable by postcards, self-mailers, letters, and checks created in the Test Environment, while templates created in the Live Environment will only be usable by postcards, self-mailers, letters, and checks created in the Live Environment. Be sure to work closely with your developer to make sure you are working in the correct environment.


Once you've created a template, you'll be able to view it on your Dashboard. You can do a couple things on this page:

  • Find the template's ID
  • Preview the template
  • Make edits to the template
  • Delete the template
  • View old versions of the template


At the top right-hand corner the page is the template ID, which is completely unique to this particular template. The template ID is how you will refer to this template when ultimately creating a postcard, self-mailer, letter, or check.


On this page, you can view the raw HTML for your template, as well as preview the design by clicking the "Preview" button.

When you preview a template, you'll first need to choose a product to preview it as. We will also auto-populate any merge variables we find in your template, which are dictated by {{double_curly_braces}}. After you've filled out these fields, you'll be able to preview your template as a PDF, which will open in a new tab (you may need to unblock pop-ups in the browser of your choice).

On the 2020-02-11 and later API versions, the JSON editor is required if you need to use loops, conditionals, or objects (read more details later in this article). We will not auto-populate any merge variables we find in your template when using the JSON editor.

Keep in mind that you won't be able to see any specific proofing elements such as address information, barcodes, or cropping that happen when actually creating a mailing. Ultimately, the best way to test your template will be to send it as a test postcard, self-mailer, letter, or check.


You can edit a template's description as well as its HTML from the Dashboard as well. When you edit a template's HTML, a new published version of that template will be created. Those changes will go into effect immediately. Any postcard, self-mailer, letter, or check integrations referencing that template ID will reflect the updated changes as soon as they are submitted.


If a template is no longer of use to you, you can delete it from Lob. Once you delete a template, it will no longer be usable in any postcard, self-mailer, letter, or check requests, so make sure that the template is not being actively used in any integrations!


At the top of the page will always be the published version, which is the version that will be used when that template is referenced in a postcard, self-mailer, letter, or check request. Historical versions of the template can be viewed for your reference, along with a unique ID and browser preview for each. This can be helpful for reconciling edits made in the past.


To test out and use your HTML template, you'll need to create a postcard, self-mailer, letter, or check. For parameter details, please see the respective documentation for each endpoint: Postcards, Self-Mailers, Letters, Checks).

For this example, we'll create a postcard. Don't forget to add in any merge variables you'd like to interpolate in. Remember that the published version of the template is the version which will be used for the request.

curl https://api.lob.com/v1/postcards \
  -u test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc: \
  -d "description=Demo Postcard job" \
  -d "to=adr_78c304d54912c502" \
  -d "from=adr_61a0865c8c573139" \
  --data-urlencode "front=tmpl_d2ef51761865901" \
  --data-urlencode "back=tmpl_7c9c41753dfea20" \
  -d "merge_variables[name]=Harry" \
  -d "merge_variables[code]=5dks92"

After sending this request, you'll be able to see your final postcard design:

For any postcards, self-mailers, letters, or checks that use templates, the template IDs and version IDs used will be retrievable from the API (see the respective documentation for each endpoint: Postcards, Self-Mailers, Letters, Checks), as well as viewable on the Dashboard:

Using HTML and Merge Variables

Merge variables make it easy to personalize your postcards, self-mailers, letters, and checks with whatever custom information you'd like. Common use cases for merge variables are:

  • Customer information (name, phone number, etc)
  • Date
  • Invoice line items
  • Custom images


Merge variables only work if you use HTML to generate your mail piece. To make use of a merge variable, insert {{tag_name}} (with double curly braces) into the HTML you pass. You can define whatever variables make sense for the design you are creating.

<html style="padding: 1in; font-size: {{fontsize}}; color: {{color}}">
  <p>Hi {{name}}, how are you?</p>
  <img src="{{img}}" style="width: 1in">

If the HTML above were used with the information below:

name fontsize color img
Harry 20px red https://s3-us-west-2.amazonaws.com/public.lob.com/assets/beach.jpg
Ami 30px green https://s3-us-west-2.amazonaws.com/public.lob.com/assets/jungle.jpg

Then the final two postcards would be rendered like so:

Use this feature to your advantage to create completely custom postcards, self-mailers, letters, and checks for your recipients, without having to generate PDFs on your side.


NOTE: This is only available on the 2020-02-11 and later API versions.

You have the ability to access merge variables at any depth within your JSON. For instance you can have an object created with a bunch of user information:

  "user": {
    "name": "Ami",
    "location": "San Francisco"

To access these within your template you can do the following:

Name is: {{user.name}}
Location is: {{user.location}}

This renders the following template:

Name is: Ami
Location is: San Francisco

You can also create a "section" which will change the context of the variables you are accessing. For instance:

  Name is: {{name}}
  Location is: {{location}}

This renders the same HTML as above, since you changed the context to the "user" temporarily. This is done by the {{#user}} and {{/user}} syntax. Everything inside that "section" tries to access a property on the "user" object.


NOTE: This is only available on the 2020-02-11 and later API versions.

Conditionals allow you to conditionally render any sort of content to the user. A simple use case could be you want to send an extra message to any user who has bought over 1,000 products. To do that would require the following:

Merge variables:

  "bought_a_lot": true


Thank you for being a loyal customer!

This renders:

Thank you for being a loyal customer!

If you want to render some content if a condition does not pass, simply do: {{^condition}}{{/condition}}. For example:

Merge variables:

  "bought_a_lot": false


Buy more products!
Buy more products!


NOTE: This is only available on the 2020-02-11 and later API versions.

Loops allow you to display content multiple times for multiple objects. The following is how you would use it:

Merge variables:

  "users": [{"name": "Nathan"}, {"name": "Ami"}]


  List of top users:

This renders:

  List of top users:


Depending on how much control you'd like over your HTML integration, we offer 2 different account settings that affect how we treat merge variables. This account setting affects the POST /v1/postcards, POST /v1/self_mailers, POST /v1/letters, and POST /v1/checks endpoints in both test and live mode:

  • Strict: Lob will send a 422 error if you define a merge variable in your HTML that is not passed in the merge_variables field of that request. Pass ' ' or null to have a particular defined variable not render.
  • Relaxed: Lob will not send an error if you define a merge variable in your HTML that is not included in the merge_variables field of that request. Instead, we will simply render nothing in the HTML in place of that merge variable.

Regardless of your strictness setting, if you pass merge variables keys that are not defined in your HTML, no error will be thrown. Your HTML will simply be rendered as normal without substituting the extra variable(s).

NOTE: On the 2020-02-11 and later API versions which support JSON in merge variables, merge variable strictness will still apply to the nested object keys, i.e. if a nested merge variable is undefined on the strict setting, then Lob will send an error.


With Lob's HTML feature, you can easily make use of any font to make your postcards, self-mailers, letters, and checks as on brand as possible. By default, we only support 1 font family, Deja Vu, within our renderer. To access any other fonts, you must follow one of the steps below.


Using Google Web Fonts is a simple way to import and use a wide variety of fonts within your Lob HTML without having to download or upload any assets.

After you've gone to their platform and found a font you'd like to use, all you have to do is include a link to the font in the <head></head> tag of your HTML:

  <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

Then, you simply reference the font like so in your <style></style> tag (or inline if you prefer):

body {
  font-family: 'Roboto';


Outside of Google Fonts, you are free to use any custom font you desire. Simply upload your font files to a performant file hosting platform (such as Amazon S3) and use CSS's @font-face declaration to load them into your design.

For example, in the <style></style> tag of your HTML, add the rule like so:

@font-face {
  font-family: 'My Font Name';
  font-style: normal;
  src: url('https://link-to-your-font/my_font_name.ttf') format('truetype');

And then reference the font in your <style></style> tag (or inline if you prefer):

body {
  font-family: 'My Font Name';


When creating HTML letters within Lob, you may find it necessary to create page breaks in order to split up your content by page. This is easy to do using CSS's page-break-after property.

For example, create a page class in your HTML and apply these styles:

.page {
  page-break-after: always;
  position: relative;
  width: 8.5in;
  height: 11in;

And then, divide the pages of content in your HTML by this page class:

<div class="page">
  Page 1
<div class="page">
  Page 2

Using Metadata

Metadata makes it easier to associate structured data with Lob objects. With metadata you can easily attach key-value pairs to postcards, self-mailers, letters, checks, and other objects. This data could include a campaign name, a customer segment, or an internal id.

Check out our documentation for implementation details.


Metadata objects can include up to 20 key-value pairs of custom data. Each metadata key must be less than 40 characters long and values must be less than 500 characters. Neither can contain the characters " and \. Metadata does not support nested objects.

This data can be searched through and viewed in our dashboard as shown below.


Using the filter button in the dashboard, you can filter metadata.

Metadata Filter Input on Dashboard


Metadata Filter Applied

Verification of Mailing Addresses

Whenever you send a mailing through Lob, you reap the benefits of accurate address cleansing and verification powered by our CASS-Certified Address Verification API. Verifying addresses is a necessary part of sending mail at scale to optimize the efficiency and accuracy of your mail delivery.


Upon creation, all US addresses will be automatically standardized, cleansed, and verified through our US Address Verification API before being returned back to you. All international addresses will simply be standardized by being transformed to all uppercase to conform with USPS standards.


Depending on what business logic you'd like to take based on your verification result, you can toggle your US Address Strictness Settings in your Dashboard. There are 3 possible Strictness Levels:

  • Strict: Only US addresses that Lob and the USPS deem deliverable can be successfully used as the to address for postcard, self-mailer, letter, or check resources. This maps to a deliverability value of deliverable (see documentation for more information). Postcard, self-mailer, letter, and check requests sent with non-deliverable addresses will return a 422 (Unprocessable Entity) error. If addresses have never been run through verification (i.e. were created in the past), they will also err when used as the to address.
  • Normal: Postcards, self-mailers, letters, and checks will be created for addresses that Lob and the USPS deem deliverable, as well as addresses for which secondary information is extraneous or missing. This maps to the deliverability values of deliverable, deliverable_unnecessary_unit, deliverable_incorrect_unit, and deliverable_missing_unit (see documentation for more information). Otherwise, you will receive a 422 (Unprocessable Entity) error. If addresses have never been run through verification (i.e. were created in the past), they will also err when used as the to address.
  • Relaxed: All postcard, self-mailer, letter, and check resources will be successfully created and mail delivery will be attempted, regardless of address validity. You will not receive a 422 (Unprocessable Entity) for Address Strictness reasons.

Ultimately, this allows you completely control the destiny of your final pieces. Only want to send to addresses that are guaranteed to be deliverable? Pick "Strict" mode. Confident that your addresses are right and want us to mail them out anyway? Use "Relaxed" mode. We want to give you the power to decide when Lob should be sending mail or when we should be rejecting based on deliverability. Ultimately, this reduces the amount of undeliverable mail you send and saves you money.


National Change of Address (NCOA) is a service offered by the USPS, which allows individuals or businesses who have recently moved to have any mail forwarded from their previous address to their new address.

As a CASS-certified Address Verification Provider, Lob also offers NCOA functionality to our Print & Mail customers. With the Lob NCOA feature enabled, Postcards, Self-Mailers, Letters, Checks and Addresses can automatically be corrected to reflect an individual's or business' new address in the case that they have moved (only if they have registered for NCOA with the USPS).

Due to privacy concerns and USPS constraints, for customers with NCOA enabled, our API responses for a limited set of endpoints differ slightly in the case when an address has been changed through NCOA (see more below).

NOTE: This feature is exclusive to certain customers. Upgrade to the appropriate Print & Mail Edition to gain access.


In order to have the Lob NCOA feature enabled, our customers must sign a Processing Acknowledgement Form (PAF), which is required by the USPS. NCOA cannot be enabled if a PAF has not been signed.

Please reach out to your Account Manager or your Customer Success Manager to see if you are eligible to sign a PAF.


With Lob NCOA enabled, there are no changes to API requests sent to Lob. This is true whether you are using our client-facing libraries, or making raw HTTP(S) requests to our API. If you have Lob NCOA enabled, all live API requests to the following endpoints will be run through NCOA after first being cleansed and verified through CASS. However, there are some changes to API responses for the following endpoints:

  • POST /v1/addresses
  • POST /v1/checks
  • POST /v1/letters
  • POST /v1/self_mailers
  • POST /v1/postcards


Though there are no changes to API requests, there are significant changes to our API responses, but only in the event that an address has been changed through NCOA. If an address has not been changed through NCOA, the response would be identical to our standard API responses, except with the addition of a recipient_moved field, which is false for unchanged addresses.

Due to the USPS constraints mentioned above, if an address has been changed through NCOA, we are required to suppress the following response fields for that address:

  • address_line1
  • address_line2
  • The +4 portion of the ZIP+4 (5-digit ZIP code will still be present).

In addition, if an address has been changed through NCOA, the address will have a recipient_moved: true flag. For more details about the response format, see the NCOA information in our docs.

In addition to our API responses, the suppressed fields will (almost) always be suppressed in other places within the Lob platform as well. This includes:

  • In the PDF proofs and thumbnails generated for Print & Mail requests
  • In Exports for Postcards, Self-Mailers, Letters, Checks and Addresses resources
  • API Logs & Event Logs
  • Webhooks
  • Dashboard Search

There are two locations where these fields are not suppressed:

  • In the physical mail piece that will be sent to your customer.
  • In an NCOA export from the Lob Dashboard (discussed in more detail below).

The NCOA export is the only way in which you will be able to access the suppressed response data for addresses that have been changed through NCOA.


In order to allow our customers to access NCOA'd data, the USPS has given us the following constraint:

Customers must send at least 100 addresses through NCOA within one week in order to gain access to NCOA'd data.

This means that in order to access this data, you must send at least 100 live API requests in a one week timespan to any of the following endpoints:

  • POST /v1/addresses
  • POST /v1/checks
  • POST /v1/letters
  • POST /v1/self_mailers
  • POST /v1/postcards

Additionally, the USPS has defined a "week" to be the following time ranges:

  • 1st-7th of the month (inclusive)
  • 8th-14th of the month (inclusive)
  • 15th-21st of the month (inclusive)
  • 22nd-28th of the month (inclusive)
  • 29th-30th or 31st of the month (inclusive, when a month has more than 28 days)

Once you have sent at least 100 live API requests in a one week timespan, you can access suppressed data through an NCOA export, which can be accessed in the Lob Dashboard Settings, under the "Reporting" tab.

Once in the "Reporting" Tab, you can select any week from the previous month or the current month, and generate an export for that week. Additionally, you have the option of only exporting addresses that have been changed during the NCOA process. This option is selected by default, as this tends to be the more useful option.

Once you have clicked the "Export" button, an email should arrive in your inbox with the exported data. Depending on how many requests you've sent and how many addresses have been changed through NCOA, this can take anywhere from a few seconds to a few hours.

The export is a CSV, which has the following fields:

  • id - The Address ID (not the mailpiece ID) for the address that has been changed.
  • name - The name passed with the API request.
  • company - The company passed with the API request.
  • phone - The phone passed with the API request.
  • email - The email passed with the API request.
  • address_line1 - The full, unsuppressed address_line1, which represents the new address for the recipient.
  • address_line2 - The full, unsuppressed address_line2, part of the new address for the recipient.
  • address_city - The city of the recipient's new address.
  • address_state - The state of the recipient's new address.
  • address_zip - The ZIP code (including the +4) of the recipient's new address.
  • address_country - The country of the recipient's new address. Always UNITED STATES.
  • metadata - The metadata associated with this address.
  • date_created - The timestamp this address was created.

One important thing to note, is that the export only includes an address ID, and not a resource (postcard/self-mailer/letter/check) ID. This means that you must keep track of address ID for inline addresses created in Postcard, Self-Mailer, Letter and Check requests.

Idempotent Requests

Idempotent Requests are requests that can be called many times without producing different outcomes. GET and DELETE requests are idempotent by definition, meaning the same backend work will occur no matter how many times the same request is issued. POST requests, however, are not idempotent. Sending a successful POST request once will result in a newly created object. If you send the same POST request 5 times, you will create 5 resources, assuming none of those requests err. If a network error occurs, there is no deterministic way to ensure the exact number of resources created.

For this reason, we have added a feature that will allow you to safely resend the same POST request to /v1/postcards, /v1/self_mailers, /v1/letters, or /v1/checks and ensure that duplicate products are not created. To perform an idempotent POST request, you simply need to provide an additional Idempotency-Key header that uniquely identifies that resource. See our documentation for more specific information.


We suggest using V4 UUID or another appropriately random string, but how you create the unique keys is up to you. For example, if you would like to associate a check with an internal unique ID of the user you are sending the check to, you may use that user id and the transaction date as an idempotency key (as long as you can guarantee the uniqueness of each idempotency key across requests to the same product). This key will expire after 24 hours, meaning if you resend the same request with the same idempotency key after 24 hours, a second resource will be created. Ultimately, it is up to you to make sure that you are appropriately setting the uniqueness of your keys based on your business logic. See resources below for help generating V4 UUIDs in various languages.


In case of failure, we recommend following something akin to an exponential backoff algorithm for retrying your idempotent requests. This ensures that you aren't retrying continuously on a downed server, thereby contributing to the issue at hand.


Below are resources we recommend in various languages for generating V4 UUIDs.


Webhooks are an easy way to get notifications on events happening asynchronously within Lob's architecture. Some common use cases for integrating webhooks are:

  • Sending end users notifications about mail traveling through the postal stream
  • Receiving notifications about erroneous scan events, such as "Re-Routed" or "Returned to Sender"
  • Downloading PDF previews or thumbnails automatically once they are rendered
  • Internal logging and reconciliation

When an event occurs within our architecture and you have a webhook subscribed to that event type in that Environment (Test vs. Live), we will attempt to make a POST request with the entire event object to the URL provided. See here for a full list of all available event types that you can subscribe to.

NOTE: In Live mode, you can only have as many non-deleted webhooks as allotted in your current Print & Mail Edition. There is no limit in Test mode.


To receive webhooks from Lob, you just need to create another endpoint on your web server that will accept a POST request with a content type of application/json. Keep in mind that it will need to be accessible by us so if there's anything that could prevent Lob from accessing it should be disabled for this endpoint. However, we do have recommendations on how to secure your endpoint below.

To confirm delivery of the webhook, Lob expects a 2xx status code returned in a timely manner. We will consider any other status code (or lack of status code) to be erroneous and attempt to retry the delivery. If your webhook endpoint has any additional complex logic to perform, we recommend immediately returning a 2xx to let us know that you don't want to receive this event again, and then performing that logic afterwards. This should aid in preventing unwanted retry attempts caused by unexpected network timeouts.

Any other information sent back to Lob in the response will be captured and stored (regardless of status code) for you to view on your Dashboard, though we won't perform any processing on it. Therefore, we recommend responding with any information that you may find useful for debugging purposes. While you can return anything (including HTML), we've found it most helpful to return a concise JSON object with anything that could be relevant.

Lob will send webhook events as soon as they become available. However, customers should not assume all webhooks will be sent in real-time, and may occasionally experience some delays.

Your webhook endpoints may occasionally receive the same event more than once. We recommend checking the unique event_ID that is included in the webhook events to determine whether it is a duplicate.

NOTE: When subscribing to a webhook event the response will return back the previous tracking events to that subscribed event as well. 
For example when subscribing to the postcard.processed_for_delivery event, you will receive a response with the previous tracking events such aspostcard.in_local_area, postcard.in_transit, postcard.mailed
If you are expecting to send large volumes of mail, subscribing to several webhook events may cause your servers rate limiting issues and therefore the loss of webhook events. To avoid this issue, please do not subscribe to more webhooks events than needed.


Events are created in both your Test and Live Environment, and Webhooks can also be created in both. Please note that Webhooks created in the Test Environment will be triggered off events from your Test API Key, while Webhooks created in the Live Environment will be triggered off events from your Live API Key.

Because tracking events only ever exist in Live, these event types can not be subscribed to in the Test Environment. To debug, you can "fake" the sending of these events to your server by using our Debugger.


When first starting out, we recommend using our Debugger. This tool allows you to trigger a generated event body to your specified URL on command. This should mainly be used to determine JSON structure when integrating. Since the event bodies sent are fake, all IDs and URLs within them are not accessible and do not map to real resources in your account.

Once you've started local development of the web server that will be handling these requests, we recommend using a tool that provides local tunneling, such as ngrok. This allows you to expose your locally running server to the Internet so we can access it without you needing to deploy your application.


When webhook attempts executed by Lob do not succeed (e.g. do not receive a 2xx status code, hit a SSL/TLS error, DNS issue, etc), we will continue to try to deliver the same event according to a schedule with an increasing back off. This policy is meant to give you time to rectify the issue without losing any events.

We will attempt the webhook at the following intervals until we either receive a 2xx status code or all 8 attempts have been executed:

Attempt # Time since last attempt Time since first attempt Example
1 n/a 0 min 2016-01-01T00:00:00Z
2 1 min 1 min 2016-01-01T00:01:00Z
3 5 min 6 min 2016-01-01T00:06:00Z
4 30 min 36 min 2016-01-01T00:36:00Z
5 1 hr 1 hr 36 min 2016-01-01T01:36:00Z
6 6 hr 7 hr 36 min 2016-01-01T07:36:00Z
7 12 hr 19 hr 36 min 2016-01-01T19:36:00Z
8 24 hr 43 hr 36 min 2016-01-02T19:36:00Z

This means that if a webhook attempt continuously fails, Lob will stop attempting webhook requests 43 hr & 36 min (approximately 1.82 days) after the initial creation of the event.


If your webhook endpoint does not consistently respond with a 2xx status code, we will automatically disable the webhook and stop sending events to the endpoint. Webhooks are automatically disabled when there are 5,000 failures after the third retry of each event in the span of 24 hours. You will receive an email notification when the webhook has been disabled.

Disabled webhooks can be re-enabled in the dashboard by editing the webhook.


It's important to note that for every API request you send to Lob, you may get multiple requests back to your server, depending on what event types you have subscribed to. For best results, please make sure your servers will be able to handle the load you expect to get back.


We understand that security is an important concern when granting external access. You need to make sure that Lob is able to access your endpoint, but you don't want anybody being able to access it or your data, so there are certain features that you can enable on your end to ensure this is possible.


We enforce HTTPS for all webhook URLs. Securing your endpoint with TLS ensures all data being sent to and from your server is encrypted. Make sure that you're using a fully-chained certificate, or else the request will never make it to your server and the attempt will fail. To make sure they are fully-chained, you should use the Debugger and see if the request successfully goes through.


Lob webhooks include a signature to allow you to verify their authenticity. Verifying this signature within your webhook endpoints allows you to ensure that the webhooks originate from Lob and not from a third party.

Webhooks include Lob-Signature and Lob-Signature-Timestamp headers. Lob-Signature is generated by computing HMAC-SHA256 on a signature input and a secret. The signature input is generated by concatenating Lob-Signature-Timestamp (as a string), the . character, and the webhook request's JSON payload (as a string). The secret is unique for each webhook and can be found in the details page for the respective webhook in the dashboard.

A static, fixed secret is used for webhooks for requests sent out using the webhook debugger. In these cases, the secret used in generating the signature is the string secret.

The addition of the Lob-Signature-Timestamp in the headers and as the input to HMAC-SHA256 allows you to prevent users from performing replay attacks. In a replay attack, an attacker intercepts webhooks and retransmits them. By verifying that the signature is valid and the timestamp is within some tolerance (we recommend 5 minutes), you can ensure that the request is not an older request being duplicated by an attacker.

In order to verify the Lob-Signature and Lob-Signature-Timestamp headers, follow the steps below.

Step 1: Prepare the signature input

Concatenate the Lob-Signature-Timestamp (as a string), the . character, and the request body (as a string).

Step 2: Generate the expected signature

Compute the HMAC with SHA-256 using the webhook secret from the dashboard as the key and the signature input as the message. Convert to a string in base-16, hexidecimal format.

Step 3: Compare Signatures

Compare the expected signature with the Lob-Signature header. If the strings are equal, then the webhook is valid.

Step 4: [Optional] Check the timestamp

If you are concerned about replay-attacks, check that Lob-Signature-Timestamp is not older than your tolerance.


You can also use Basic Authentication to guard your endpoint from public access. This can be used in addition to or instead of webhook signature verification. For the best level of security, we highly recommend verifying webhook signatures, rather than relying solely on HTTP Basic Authentication.

When creating your webhook, insert the username and password to the URL using the following format: https://username:password@example.com/webhooks. This will be converted on our end to the appropriate Authorization header when we make the request.


A common feature that is enabled by default for some frameworks is cross-site request forgery. This is an valuable security measure to ensure that authenticated users aren't performing actions that aren't intended. However, having it enabled on your webhook endpoint could prevent our events from being processed. Instead of disabling it completely, you should just exempt this endpoint from CSRF validation.


We will always send events based on the API Version on your account at the time of event creation. If your account is set to an older API version but a request is sent with a hard coded header, the Event generated will still be based on the API Version on your account at that time. Event objects in the past will not be updated if you upgrade your API Version - only subsequent events will follow the new Version's structure.

Cancellation Windows

By default, all new accounts have a 5 minute cancellation window for postcards, self-mailers, letters, and checks. Within that timeframe, you can cancel mailings, free of charge. This gives you the flexibility to quickly QA your mailings before they finally get sent off for production.


Certain customers can customize their cancellation windows in their Dashboard Settings. Upgrade to the appropriate Print & Mail Edition to automatically gain access to this ability. If you have access to this feature, your cancellation window can be anything from 0 minutes (no cancellation window) to up to 3 days.

Keep in mind that when you edit your cancellation window settings, any changes made will only apply to mailings created after the update was made. If you find yourself constantly changing your cancellation window for different use cases, we recommend using our Scheduled Mailings feature instead.


Within your chosen cancellation window, postcards, self-mailers, letters, and checks are cancelable. This means that they will be completely removed from production and that they will not count towards your monthly usage for billing purposes.

To cancel a mailing, either use the API endpoint or cancel the mailing from your Dashboard. In either case, the mailing will only be cancelable if its send_date has not yet passed.


Even if you have a cancellation window set on your account, using the Scheduled Mailings feature to schedule a mailing will override your cancellation window and the send_date passed will be used instead.

Not only is this useful for scheduling mailings far off in the future, but it is also handy for completely bypassing any cancellation window you might have and sending one mailing or batch off to production immediately.

Scheduling Mailings for a Future Date

Postcards, self-mailers, letters, and checks can be scheduled up to 180 days in the future. Until that time, mailings can also be canceled. You can use this feature to:

  • Create automated drip campaigns (e.g. send a postcard at 15, 30, and 60 days)
  • Schedule recurring sends
  • Plan your mailing schedule ahead of time
NOTE: This feature is exclusive to certain customers. Upgrade to the appropriate Print & Mail Edition to gain access.


Scheduling a mailing for the future just requires one additional parameter: send_date. This specifies a date and time up to 180 days in the future to start processing the mailing. For billing purposes, requests will count towards the month of their send_date, and will not be charged if they are canceled before that time. If your account has a cancellation window set for the resource you are creating, passing a send_date will override that window. For more detailed request information, see our documentation.


If something changes on your side and you no longer wish to send a mailing that had already been scheduled (such as the customer taking a certain action), you can programmatically cancel those requests as long as the mailing's send_date has not passed. Additionally, you can cancel a mailing from your Dashboard.

Mail Analytics Dashboard

As you start sending higher volumes of mail with Lob, you may have a need to analyze the status and deliverability of your mail on a more aggregate basis. Our Mail Analytics Dashboard gives you full visibility into where the mail you've sent in any given time period sits in the mail stream. You can slice and dice your data by certain filters to view a full deliverability report, all directly from your Dashboard.

To access this feature, sign in to your Dashboard and click the "Mail Analytics" tab in the left navigation bar.

NOTE: This feature is exclusive to certain customers. Upgrade to the appropriate Print & Mail Edition to gain access.


Lob is the only intelligent platform that tracks each piece of mail as it moves through the USPS delivery process. All mail that is tracked by Lob is presented and aggregated on this Dashboard. The Mail Speed tab shows the number of business days it took from a mail piece's send_date to the date the mail piece was marked as processed_for_delivery by the USPS.

Mail Speed Histogram

The Mail Speed graph respects all applied filters and shows the average and median mail speed for all the mail pieces that fall within the filter. Pieces that have yet to receive a processed_for_delivery tracking event are not counted in the metrics above the graph. Additionally, the graph is for US mail only.


The Mail Distribution tab shows the number of mail pieces sent to each US state (and Washington D.C., but excludes US territories). A state's color corresponds to how many mail pieces have been sent to that state. Hovering over a state will provide more details like how many mail pieces have received a processed_for_delivery tracking event, as well as average and median mail speeds (calculated the same way as the Mail Speed tab).

Mail Distribution Map

You can also view the data in a table format. The table shows the same data as the map, where each state's data corresponds to a row. Clicking on a column header will sort the values in that column. To search by state name, click on the search icon and input a value to filter the table.

Mail Distribution Table


The Tracking Events tab displays a breakdown of all tracking events applicable to the mail pieces within the filter parameters. The main buckets at the top of the Dashboard represent the different stages in your mail's delivery process:

Tracking Events Statistics Summary

Sent: This is a count of non-deleted mailings that you have sent to Lob in the specified time frame based on the date for which a piece was scheduled (the piece's send_date), not the date the API request was made.

Mailed: This bucket is a count of all pieces that have received a Mailed event, which represents handoff to USPS. NOTE: Access to Mailed Events is exclusive to certain customers. Upgrade to the appropriate Print & Mail Edition to gain access.
In Mailstream: This bucket is an aggregate of two tracking events, In Transit and In Local Area. These are the first two scans that a piece will receive—representing that it's in the mailstream and on the way to its destination.
Processed for Delivery: This bucket is represents pieces that have received a Processed for Delivery scan. This scan means that the piece has been greenlit for delivery at the destination's nearest postal facility and will likely be delivered in 1-2 business days.

Re-Routed: If a piece is re-routed due to recipient change of address, address errors, or USPS relabeling of barcode/ID tag area, it will receive this scan.

Returned to Sender: A piece will receive a Returned to Sender scan if delivery was attempted, but failed due to barcode, ID tag area, or address errors.

Each mail piece will be counted once in each bucket for which it receives a scan. For example, if a letter has these tracking events:

  • "In Transit"
  • "In Local Area"
  • "Processed for Delivery"

Then it will be counted once in the "Sent", "In Mailstream", and "Processed for Delivery" buckets.

NOTE: Certified and Registered letters and Overnight checks are excluded from this dashboard because they are tracked via their own external tracking numbers.


You can also export all tracking events data into a CSV file. This can easily be done by accessing the Filters and Export buttons at the top of any list page.

From the list view, use the filters to select the type of mail items that you would like to export its tracking data. You can specify date range, metadata tags, and several other attributes that differ by form factor. Lob currently supports tracking no more than 250,000 mail items per export. Once your selection is made, click “Apply”.

Next, click the "Export" button at the top of the page, and confirm your filter selections. Click yes to make a granular selection of associated tracking events. Once done, submit your request.

You will receive an email with a link to download a CSV file of your requested tracking events.


On your Mail Analytics Dashboard, you can slice-and-dice your data by various other aspects of your mailings, including: product type, recipient ZIP code, template used, and more. You can use these filters to compare deliverability between your different campaigns, recipients, and more.

Metadata Filtering Example

Be sure to leverage Lob's metadata feature to more deeply tag your Lob mailings with any internal data you may have, such as a customer ID or campaign ID. Then, you can easily filter by that metadata within the Analytics Dashboard to view different deliverability reports based on those factors.

For mail sent to international destinations, we only expect to get either "In Transit" or "In Local Area" scans. For this reason, we've added a top level filter where you can compare US and international mailings, with the last three tracking buckets disabled for international mail.


Under the tracking event statistics on the dashboard, we also provide a graph that provides an even further breakdown of your mail by day, week, or month. Time periods are grouped by the date a piece was sent, not by the date of the API request. As with all other dates within the Lob system, the UTC time zone is used.

Hover over a specific column to view a full tracking breakdown for that time period. Use this breakdown to narrow down your data for even further analysis.

Tracking Events Line Graph


Over time, you can expect to see tracking events for 98-100% of your mailings. The numbers below are benchmarks for when you should start seeing scans. Keep in mind that these timings and percentages may vary based on the volume of mail you've sent, where you're sending to, and the quality of your address set.

For first class mail, you'll start to see mailings reach the "In Mailstream" bucket in 2-3 business days and the "Processed for Delivery" bucket 1 business day afterwards. After about 4 business days total, you should expect almost all of your mailings to be in the "In Mailstream" state. After about 5 business days total, almost all of your mailings should be in the "Processed for Delivery" state.

For standard mail, which is inherently slower, the timing is a bit different. You'll start to see mailings reach the "In Mailstream" bucket in 4-5 business days and the "Processed for Delivery" bucket 2 business days afterwards. After about 10-11 business days total, you should expect almost all of your mailings to be in the "In Mailstream" state. After about 12-13 business days total, almost all of your mailings should be in the "Processed for Delivery" state.

Audit Logs

All actions available through the dashboard's settings are recorded in our Audit Logs system. Admins in Enterprise level accounts have access to the Audit Logs tab in dashboard settings.

Audit Log Information

  • Action
  • Associated user
  • IP Address
  • User Agent
  • Time Stamp

Recorded Actions

  • Changed the account's bank account
  • Changed the account's credit card
  • Changed the SAML configuration
  • Changed the account's company name
  • Changed the account's address
  • Changed the account's deliverability strictness
  • Changed the account's merge variable strictness
  • Changed the account's cancellation window for checks
  • Changed the account's cancellation window for letters
  • Changed the account's cancellation window for self-mailers
  • Changed the account's cancellation window for postcards
  • Redeemed a code
  • Logged in
  • Downgraded the Print & Mail edition
  • Downgraded the address Verification plan
  • Downgraded the support plan
  • Upgraded the Print & Mail edition
  • Upgraded the address verification plan
  • Upgraded the support plan
  • Joined
  • Deleted a team member
  • Invited a user
  • Reset their password
  • Resent a team invite
  • Requested a password reset
  • Changed their password
  • Changed their email address
  • Changed a user's role
  • Changed their name
  • Verified their email address

Inviting Team Members

You can add team members to join your Lob account in your dashboard. All users on an account share the same API keys and payment method.

The maximum number of users you can add to your account is dictated by your current Print & Mail Edition.

Depending on your current Print & Mail Edition, you may have access to create Read & Write and Read Only users. See our FAQ for more details about these roles.

Billing and Invoices


To add a payment method to your account, please visit your dashboard settings. Lob accepts ACH payments and credit cards. If you are sending at high volumes, we recommend you set up ACH payments. If you are spending over $2,000 a month we require you to setup ACH.

In general, a payment method (either credit card or ACH account) must be added to your account to make live API requests. However, a payment method is not required for the first 300 live requests per month to the /v1/us_verifications endpoint. After the first 300 requests, you will begin receiving errors with status code 403.


You can view your invoices, both current and historical, at any time in the plan settings in the dashboard as shown below.


For Enterprise edition customers, Lob is now able to address specialized billing needs by allowing greater flexibility to generate invoices that are more reflective of your usage of Lob’s Print & Mail services. This can simplify charges between different parts of your organization that’s sending mail, and provide data-driven visibility that unlocks new revenue potential based on a “pay for what you use” billing structure. 

Specialized billing needs may be defined by (but not limited to):

  • Separating annual subscriptions from consumption-based usages 
  • Differentiating usage between different cost centers or end-customers

In order to customize your billing structure, a detailed request should be made to your Customer Success Manager (CSM). Once a request is reviewed and approved by our Finance team, our team will be able to provide further instructions to modify your invoice and fulfill your needs. 

Please refer to the API documentation for more information. If you are an Enterprise edition customer that is interested in this feature, please speak to your CSM to enable this feature. 

Test and Live Environment

Every account has a test and a live environment. All API requests are either a test or live request. The two environments are completely separate; data created in the test environment can not access data created in the live environment, and vice versa. You should use the test environment during development to test that your integration is working properly and that your artwork looks as expected. Once you are ready for production, switch to your live API key.

The test and live API keys are located in your dashboard.


All features that are available in live mode are available in the test environment. When you send a request in test mode, a proof and thumbnails will be rendered, but the mail piece will not actually be printed and mailed. PDF proofs and thumbnail images of your mail-pieces are returned in the API response, which are helpful for you to preview the expected print output as well as show previews from your apps. Additionally, a full production-load test can be done in test mode before switching over to production.

To send a real mail piece, you need use your live API key.


Before going live, you will need to verify your email and add a payment method. A payment method is not required for the first 300 live requests per month to the /v1/us_verifications endpoint (after which you will begin receiving errors with status code 403). A verification email is sent when you create your account and can be requested again through the dashboard.

When you send a live request, your mail piece will be queued for printing and mailing immediately. There is no way to undo a live API request, so please use caution when using your live API key.

Upgrading API Versions

When backwards-incompatible changes are made to the API, a new dated version is released. You can view your version and upgrade to the latest version in your dashboard settings.

We highly recommend upgrading to the latest API version. Upgrading allows you to keep up to date the with the latest features, bug fixes, and performance improvements.

To test a newer version of the API, you need to specify a version, in the HTTP header as shown in the documentation. The API will return an error if a version older than your current one is passed in.

See the API changelog for a full list of breaking changes.

Setting Up Lob SSO with Okta

These instructions should broadly apply to configuring Lob SSO with other popular IDPs in the market, such as OneLogin and Google IdP.


1. First, create an application in Okta for Lob using the following guide

2. Name the application:

3. Next, add the SAML settings:

  • For Single sign on URL, please input: https://api.lob.com/v1/sessions/saml
  • Click the option below to Use this for Recipient URL and Destination URL
  • For Audience URI (SP Entity ID), please input: https://api.lob.com/v1/sessions/metadata.xml
  • For Name ID format, choose the "EmailAddress" option
  • For Application username, choose the "Email" option
  • The SAML settings should match the screenshot below:


4. Once your new application is created in Okta, then you will need to copy the SAML metadata generated from your IDP and paste that metadata blob into Lob's Dashboard. You can view SAML IDP metadata in Okta by clicking on the Sign On tab in the application and then clicking the Identity Provider metadata link below. This should open a new web page containing the XML you will need.

Note: An IDP metadata blob should look something like this:

5. Next, open Lob's Dashboard and hover to the account settings, located at the top-right corner of the dashboard with your name. This should show a dropdown menu to open the Settings.

6. In the Settings, you will be prompted to the Account tab. Scroll down to Single Sign-on. Here you can paste in the IDP metadata blob from Okta, and then click save.

Note: Only Lob admin users will be able to see the Single Sign-on configuration in Dashboard.


Even if your company has an active SSO integration with Lob, each individual user will still need to accept their company's invite before being able to log in using SSO. Otherwise they will be sent to the normal sign-in screen.

SSO is a hard cutover for your account, so once SSO is configured then ALL users for that account will only be able to sign in through SSO. If there is an issue with the IDP metadata, e.g. an incorrect SSO URL, then all users for that account will possibly be locked out. It is strongly recommended to test SSO by signing into Lob's Dashboard through another session.

If you are locked out of your account because of incorrect IDP metadata, contact support@lob.com to revert your account back to the normal login flow.

Getting Started

To get started with sending postcards, check out our postcards documentation.


Be sure to follow the provided templates for the back of your postcard to leave room for the address and postage area:

Getting Started: Folded Self Mailers

This feature is exclusive to certain customers. Upgrade to the appropriate Print & Mail Edition to gain access, or reach out to our sales team.

To get started with sending self mailers, check out our API documentation.


Lob offers bifold self-mailers, which measure 6x9” when folded in half, and unfolds either horizontally (6x18”) or vertically (12x9”). There are four panels available to customize for each size permutation, and one of the outside panels must have an ink-free zone for the address and postage area, which measures 2.375 x 4”. Additionally, adhesive will be applied within 0.25” of the open edge and will be placed opposite the fold.  

Reference our design templates below on where to place your design elements for each size permutation, and note the expected zone for adhesive placement:


In general, any artwork should be 0.125" away from the final trim line due to movement at press. Bleeds should extend 0.125" past the trim line. No critical design elements or text should be printed outside of the safe zone.

The preferred image submission format is a PDF file (.pdf), and all images should be 300 dpi or higher. Refer to our design guides or documentation for more details on image prepping, or browse our Template Gallery for pre-designed creatives to leverage as inspiration.


Stain-resistant, low tack, clear fugitive glue is used for adhesives on the folded self-mailers.

Glue is positioned within 1/4 inch of the opening edges and placed opposite the final fold. Glue is applied by one of the following methods:

  • Continuous glue line at least 1/8 inch wide (0.125 inches)
  • Three or four glue spots at least 3/8 inch (0.375 inch) in diameter
  • Three or four elongated glue lines


Currently, we are unable to support HIPAA compliance for self-mailers. If you require HIPAA-compliant healthcare mailings that include PHI to be sent, we recommend they be sent as a letter, which is a HIPAA-compliant form factor.

Printing and mailing any sensitive PII will be up to the users’ own discretion and guidance.

Getting Started

To get started with sending letters, check out our letters documentation.


The address_placement parameter specifies the location of the address information that will show through the double-window envelope. Options are top_first_page and insert_blank_page.

By defaults, lob selects top_first_page, meaning lob will print address information at the top of your provided first page.To see how this will impact your letter design, view our letter template.

If you pass insert_blank_page, a blank address page will be inserted at the beginning of your file and you will be charged for the extra page.

If you don't follow these address guidelines, your letter will be printed incorrectly, and it will not mail correctly with USPS.

Using Return Envelopes

If you'd like to include a return envelope with your mail piece, you will need to set return_envelope=true and set a perforated_page for the envelope to be added on. To see how this will impact your letter design, view our perforated letter template.

Return envelopes are blank and come without prepaid postage.


For Enterprise edition customers, Lob offers access to return envelope tracking via webhooks for USPS Courtesy Reply Mail. 

To access this feature, customers should submit an API request for a letter with:

  • return_envelope = true
  • or return_envelope = no_9_single_window, if custom return envelopes are enabled on the account
  • perforated_page, specifying the page that will have tear-off slips with a remittance slip and return address for the reply mail
  • return_address, specifying the return address the return envelope customers should send remittance slips to

This will result in the return address and associated Intelligent Mail Barcode (IMb) tracking code to be placed within the window area of the perforated_page. The letter including the perforated page with a return address and the #9 return envelope will then be sent to the customer in a #10 outer envelope.

Customers who would like to send Courtesy Reply mail without return envelope tracking, can omit the return address field in the API request. This will result in only the return address rendered in the window area of the perforated page.

  • return_envelope = true
  • or return_envelope = no_9_single_window, if custom return envelopes are enabled on the account
  • perforated_page, specifying the page that will have tear-off slips with a remittance slip and return address for the reply mail


Once the returned envelope enters the mailstream and is scanned by the USPS, the customer can start receiving notifications to mail tracking events, which will be surfaced via webhooks.

The following is a list of mail tracking event labels and descriptions available:

  • Created: Return envelope is first created (should be simultaneous with Letter creation)
  • In transit: Return envelope is being processed at the entry/origin facility
  • In local area: Return envelope is being processed at the destination facility
  • Processed for delivery: Return envelope is greenlit for delivery at the end recipient's nearest postal facility. The mailpiece should reach the mailbox within 1 business day of this tracking event.
  • Re-routed: Return envelope is re-routed due to recipient change of address, address errors, or USPS relabeling of barcode/ID tag area
  • Returned to sender: Return envelope is undeliverable and is being returned to sender due to barcode, ID tag area, or address errors.

Return envelope tracking is currently only accessible via Lob webhooks, and the Event Logs node in the Lob dashboard. Tracking events will appear in the Letters Events portion of the original individual mailpiece in the dashboard as soon as they become available, or can be downloaded using the “Export” button that’s located at the top of the Letters section in the dashboard.


Return addresses that are passed into the “return address” field will be used exactly as passed in. We do not run this address through any verification services like NCOA or CASS. This helps ensure that remittance slips are sent to the business address provided. Customers must take extra care to ensure that the address information provided matches their desired delivery address. 

Additionally, we recommend supplying ZIP+4 codes in the return address specified to ensure the fastest, most accurate mailing possible. This can speed up USPS processing and delivery by up to as much as 2 days.

In the future, the tracking feature will be made available for custom return envelopes and Business Reply Mail, as well as the ability to track return envelopes from the Lob dashboard.  

If you are an Enterprise edition customer looking to learn more about return envelope tracking, including specifics on pricing, please reach out to our Sales team or your CSM.

Using Custom Envelopes

This feature is exclusive to certain customers. Upgrade to the appropriate Print & Mail Edition to gain access, or reach out to our sales team.
Additionally, Custom Outer Envelopes are currently only supported for letters; they are not available for checks. To get started with creating letters with custom envelopes, refer to our letters documentation.

Envelopes must be created, ordered, and printed before they can be utilized. Create and manage your custom outer envelopes from within the Lob dashboard.


Custom outer envelopes are 9.5" x 4.125" and can fit up to six tri-folded 8.5" x 11" sheets.

If you'd like to use a custom envelope with your mail piece, you will need to set the custom_envelope parameter in your POST call to https://api.lob.com/v1/letters to the desired custom envelope ID, which can be found in your dashboard. If a letter is created with a specified envelope ID that is not in stock, the letter request will be rejected. If a letter is created with a specified envelope ID and is 7+ sheets, the letter will be sent instead in a blank, flat envelope, and the custom envelope inventory will not be decremented. Additionally, custom envelopes have an expiration date, which ensures the envelope's integrity.


Reference our custom envelope template to see where you can put your design elements. In general, any artwork should be 0.125" away from the trim line due to movement at press. Bleeds should extend 0.125" past the trim line. Custom envelopes will not be printed outside of the safe zone.

The preferred image submission format is a PDF file (.pdf). Other acceptable image formats include Adobe Illustrator (.ai), Indesign (.indd), and Photoshop (.psd) files.

Envelope Artwork Considerations

  • Outline all fonts: differences in kerning, font versions, anti-aliasing, etc., can cause small variations between what you see on your screen and what we output to press
  • Double-check that all images are embedded into your document
  • Ensure all rasterized artwork (images, effects, copy, etc.) is created and saved at or above 300 DPI
  • All images must be at or under 25% ink saturation 
  • Type should be no smaller than 5 pt
  • Thin, small fonts with over 3 colors may fill in slightly or appear “fuzzy”
  • Line weights of 0.5 pt or more assure optimum print results
  • It is preferred that barcodes/QR codes are vector/editable
  • CMYK documents are preferred over RGB


The envelope window is where your recipient address information will be visible. Reference our letter template to ensure that your recipient’s address is visible. No design within the envelope window will be printed.


Postage will be placed in the upper right corner of the envelope. No design will be printed in this space. Refer to our custom envelope template for stamp placement.


USPS prefers that return addresses are placed in the upper left portion of the mailpiece, on the side of the piece bearing postage. USPS does not require that all mail include a return address; however, mail sent without a return address cannot be returned.


Envelopes can be purchased as one-off orders or through auto-reordering. The minimum order quantity for custom envelopes is 10,000 envelopes per artwork design.

Note: Please allow an estimated 15 business days for custom envelopes to be available for use in your dashboard. Envelopes can not be used until the dashboard indicates that they have been made available, and any API requests including your unique envelope ID will fail. Timing and delivery is dependent on order size and complexity, and may be additionally delayed by forces outside of Lob's control.


When the auto-reordering function is turned on, a new order will be submitted whenever the remaining envelope quantity in inventory falls below 20%. A confirmation will show the reorder quantity and price that will be charged.

Given that custom envelopes have additional lead times, we recommend enabling auto-reorder for envelopes that will be continuously utilized to ensure there will be no risk of running out.


Order details will be populated in the order history window once the order is submitted. Expected date provides a rough estimate of when envelopes will be available, while an email confirmation will be sent to you when envelopes are actually ready for use.


Return to the dashboard at any given time to view existing order designs, the number of remaining envelopes, and the number of orders that are still outstanding or fulfilled. Inventory will decrease with each API call made that specifies a custom envelope.

Getting Started

To get started with sending checks, you'll need to setup and verify a bank account to send checks from. Once you have setup your bank account, check out our checks documentation.


Check with your bank to make sure that the check will be accepted. A new check template or different signatory can cause the bank to flag your account. The best way to avoid this happening is to let your bank know that the checks are valid.

Your money is not transferred to Lob. When a check is deposited, it will pull money directly from the specified bank account.

Verifying Your Bank Account

To verify your bank account, Lob will send two micro-deposits ranging from 1 to 100 cents into the specified bank account. You'll be asked to enter them in the dashboard or submit them through the API, before sending out any checks.

This is especially important if you are sending checks on behalf of your customers. You must verify all your customer's bank accounts before sending checks from them. This is mostly easily done through the API.


Our security team reviews newly created accounts. New accounts that trigger our flags will be immediately suspended and required to provide additional verification.

If you have any questions or concerns, please contact us.

Uploading a Signature for Checks

One of the options for associating a signature to a bank account to be printed on checks is the uploading of an image file. Below are the guidelines to adhere to when prepping your image so that the signature can best be extracted and processed.


The image must be in either a JPEG or PNG format (.jpg, .jpeg, .png).


The image must be at least 330px x 105px. The image may be larger but we recommend a width to height ratio of approximately 3:1 for best results.


The signature must be written in black or dark ink on a white or light background. The signature should be centered and should occupy most of the image.


Here are a few of the most common mistakes that we recommend you avoid when preparing a signature image.


Make sure to center your signature and crop your image as needed so that the signature takes up a majority of the space.


Write your signature on a white or light colored background to ensure proper signature processing. Using ruled or patterned paper will likely result in unintended artifacts.


If you are taking a photo of your signature rather than using a scanned image, make sure to prepare your photo so that all artifacts and non-signature objects (e.g. tables, pens, dark shadows, etc...) are cropped out.

Customizing Check Pages

Check pages do not require any artwork in order to be sendable. However, it is a great opportunity to leverage the blank space at the bottom of the check to add any branded artwork or personalization. If you choose to customize this optional section, be sure to follow the provided template and leave room for the actual check itself; otherwise you may render the check useless. You may also add optional attachment pages. See our checks documentation for more details or the Template Gallery for design inspiration.

Bottom of the check page may be customized (optional)


Please use the following as an addendum to the Braze integration documentation for using Lob with Braze.


Add Custom Attributes for user mailing address information:

  • address_line1
  • address_line2
  • address_city
  • address_state
  • address_zip
  • address_country


Update user profiles with mailing addresses.

Import CSV:

API call:

Anything highlighted is a custom variable that will need to be updated for each customer or use case.

curl -X POST \
  https://rest.iad-01.braze.com/users/track \
  -H 'Content-Type: application/json' \
  -d '{
    "api_key": "Braze_API_Key",
    "attributes": [
          "external_id" : "10142019",
          "address_line1" : "185 BERRY ST STE 6100",
          "address_line2" : null,
          "address_city" : "SAN FRANCISCO",
          "address_state" : "CA",
          "address_zip" : "94107-1741",
          "address_country" : "UNITED STATES"


Create Webhook Template:

Example Postcard


WEBHOOK URL: https://api.lob.com/v1/postcards


  "description" : "{{campaign.${name}}}",
    "metadata" : {
        "campaign" : "{{campaign.${name}}}"
    "to" : {
        "name" : "{{${first_name}}} {{${last_name}}}",
        "address_line1" : "{{custom_attribute.${address_line1}}}",
        "address_line2" : "{{custom_attribute.${address_line2}}}",
        "address_city" : "{{custom_attribute.${address_city}}}",
        "address_state" : "{{custom_attribute.${address_state}}}",
        "address_zip" : "{{custom_attribute.${address_zip}}}"
    "from" : "adr_2066448bdef840f1",
    "front" : "tmpl_8b3b1249ede0406",
    "back" : "tmpl_d69077c7be7bd09",
    "merge_variables" : {
        "name" : "{{${first_name}}}"


Be sure to leave the : after the Lob API key you paste in between the apostrophes.


  • Authorization: Basic {{ 'YOUR_LOB_API_KEY:' | base64_encode }}
  • Content-Type: application/json
  • Idempotency-Key: {{${user_id}}}



Test your new Webhook template and check your Lob dashboard to ensure desired results.



  • We have added a feature that will allow you to safely resend the same POST request to /v1/postcards, /v1/self mailers, /v1/letters, or /v1/checks and ensure that duplicate products are not created. To perform an idempotent POST request, you simply need to provide an additional Idempotency-Key header that uniquely identifies that resource (such as the user id in the example above.)
  • This key will expire after 24 hours, meaning if you resend the same request with the same idempotency key after 24 hours, a second resource will be created.
  • https://docs.lob.com/#idempotent-requests
  • https://lob.com/guides#idempotent_request






Integromat is a free online automation tool that connects apps and automates manual workflows by using an easy to use, no-code, visual builder. With Integromat, you can quickly connect to hundreds of your favorite apps, services, and devices with zero programming to automate your custom workflows and save time.


  • Create Scenarios (no-code workflows) that connect Lob with hundreds of popular apps & services 
  • Create your own custom app through the Developer Platform
  • Supports functions - as you know them from Excel
  • Choose whether to retrieve data from the past or after activation, when you run your Scenario
  • Sign up for a free Integromat account to create custom workflows or use prebuilt Scenarios

Using pre-built lob modules

To help you hit the ground running, here are five of our most popular Modules (functionality clusters) to help automate your Print & Mail and Address Verification workflows:

  • Create a Letter: Takes in your API key, to/from address data, creative data (HTML or PDF), and Mail Class
  • Create a Postcard: Takes in your API key, to/from address data, creative data (HTML or PDF), and Mail Class
  • Verify a US Address: Takes in your API key and address data
  • Verify an International Address: Takes in your API key and address data
  • Send a Generic API Request to Lob: Takes in your API request payload


Integromat’s platform allows users to build Scenarios by connecting Modules. By linking together any Modules of your favorite app/service, you can easily create a Scenario that will automate data transfers between apps and subsequent workflows. 

Integration occurs in three easy steps: 1) Sign up for Lob and Integromat, 2) Connect Lob to Integromat, and 3) Create custom workflows or use prebuilt ones.

Connecting Lob to integromat

  • Log in to your Lob and Integromat accounts
  • In the Integromat dashboard, click on "Create a new Scenario" button at the top right corner
  • Search for "Lob" in the app directory and hit "Continue"
  • In the visual Scenario builder, click on the Lob icon and select the action you’d like to take
  • In the resulting menu, click on the “Add” button, name your connection, add your Lob account’s API key (Test key is recommended), and click “Continue”
  • Once that's done, finish creating your Scenario
  • Once you've tested your first Scenario, switch the API key to the Live key and begin sending actual mail!


Watch how you can easily connect addresses stored in Google Sheets to Lob with Integromat to send a simple postcard in three steps:

For more information on how to build custom Scenarios, head over to Integromat’s Help Center.

Using pre-built Lob Scenarios is also easier than building one from scratch:

Here are other pre-built Scenarios with popular apps that you can use:


Feel free to contact Integromat’s support team via their support form for issues on the Integromat side, or email support@lob.com for Lob-specific debugging!



Lob is excited to announce the launch of our direct integration with Salesforce, the world’s #1 CRM. Our powerful integration is built atop the Salesforce Platform and available via the AppExchange, allowing any user to easily send automated direct mail at scale, 100% natively from Salesforce. 


Lob's direct Salesforce integration is accessible via Veezla’s Print & Mail app, which is built and published by Veezla on the AppExchange and powered by Lob. 

  • Plug & play: purchase the Veezla app with a Lob subscription to access Lob functionalities within Salesforce in just a few clicks 
  • Print & Mail: Send mail at scale and record all interactions, access content management libraries, map custom objects, build triggered workflows and automated mass mail campaigns, and leverage ReportBuilder to turn quality direct mail data into actionable insights   
  • Enterprise edition users will be required to purchase Lob premium support if they want support for mail production and delivery
  • Optional implementation services & support plans available from Veezla


This integration runs on Salesforce.com Enterprise edition or higher or on Force.com Platform. 

  • Certain form factors and features will only be accessible to Lob Enterprise edition users, such as folded self-mailers or custom envelopes
  • The integration is not compatible with Salesforce Marketing Cloud, Pardot, or B2C Commerce Cloud at this time 



Contact Veezla’s support team concerning any questions or issues around your app’s technical functionality or workflow automation within Salesforce.

Contact Lob’s support team for any issues around print quality and production, mail fulfillment and delivery, form factors, HTML templating, billing & invoicing, or security.



Zapier automates your tedious workflows by connecting Lob to 1000+ other business tools, including Slack, MailChimp, Gmail, and Trello. In just minutes, setup automated Zaps to correct, standardize, and enrich addresses and send letters or postcards based on Triggers from thousands of other Zapier integrations.


  • Zapier integrates Lob with 1000+ business applications
  • Set up automations called Zaps to take care of repetitive tasks for you
  • No coding required
  • Sign up for a free Zapier account to use popular automated workflows called Zaps


Each Zap has one app as the Trigger, where your information comes from and which causes one or more Actions in other apps, where your data gets sent automatically.


Sign up for a free Zapier account, from there you can jump right in. To help you hit the ground running, choose from one of our popular pre-made Zaps:


Sign up for a free Lob account to send Test API requests for free. Instantly begin sending real mail by simply adding a payment method to your account.


  • Log in to your Lob Account.
  • Log in to your Zapier account.
  • Navigate to "Connected Accounts" from the top menu bar.
  • Now click on "Connect new account" and search for "Lob".
  • Use your Test Lob API Key to connect your Lob account to Zapier. Start with your Test API Key so that you can set up your Zap without sending anything real yet.
  • Once that's done you can start creating an automation! Use a pre-made Zap or create your own with the Zap Editor. Creating a Zap requires no coding knowledge and you'll be walked step-by-step through the setup.
  • Need inspiration? See everything that's possible with Lob and Zapier.
  • Once you've tested your first Zap, all that is needed is switch your Lob API key to the Live to begin sending actual mail!



Feel free to email contact@zapier.com for issues on the Zapier side or support@lob.com for Lob-specific debugging!

AV Elements



Create an account at Lob.com to obtain a Live Public API Key. The key is available in the Lob Settings Panel and uses the format, live_pub_*.


Address Elements works by targeting the input elements of your address form and using their values with Lob's verification and autocomplete functionality. Include the AV Elements script tag immediately before the closing <body>tag.

Code Demo
                        <script src="https://cdn.lob.com/lob-address-elements/2.1.2/lob-address-elements.min.merged.js"

Shopify Users

AV elements works great with e-commerce platforms because they use predictable element names. For example, Shopify users can simply paste the following preconfigured script at the bottom of their Shopify Plus template.

Remember to replace live_pub_xxx with your Lob public key

<script src="https://cdn.lob.com/lob-address-elements/2.1.2/lob-address-elements.min.merged.js"
Screengrab of Shopify demonstration that illustrates where Lob error message will appear by default in Shopify checkout form

NOTE: Many E-commerce platforms have strict content security policies that prevent scripts from loading additional content. Embed the merged build of Address Elements to handle these situations as shown in the example above (lob-address-elements.min.merged.js). This ensures all dependencies are included in the download.

Attribute Reference Cheatsheet

The Address Verification script has many attributes to give you complete control over its appearance and behavior. They generally go by the following pattern:

data-lob-*-id data-lob-*-value
These attributes are used to identify an element on your web page. Their values should be the elements ID and correspond to the components of an address: primary line, secondary line, city, state, and zip.
Example: data-lob-primary-id="address1"
These attributes modify the behavior of autocomplete and verification. Their values are either true, false, or a string from a list of options
Example: data-lob-verify-value="passthrough"

Form Detection Attributes
AV Elements can detect address form inputs automatically. We can improve performance by skipping the form detection process when these attributes are provided. Set them to the IDs for each field to target.

  • data-lob-primary-id
  • data-lob-secondary-id
  • data-lob-city-id
  • data-lob-state-id
  • data-lob-zip-id
  • data-lob-country-id

Form Functionality Attributes
These attributes modify the behavior of AV Elements

Attribute Name Attribute Value(s)
  • strict
  • normal
  • relaxed
  • passthrough
  • false
Controls the strictness level when verifying an address. If the strictness criteria is not met, we block the form submission and prompt the user to correct the address. Set to passthrough to submit the form regardless of the verification result. Set to false to disable verification altogether.
Default: relaxed
Learn more about Lob's strictness setting
data-lob-primary-value Enables or disables address autocompletion.
Default: true
data-lob-secondary-value When set to false, force the suite or unit number to render on the primary address line during address verification.
Default: true

Custom Error Handling
data-lob-*-message-id Identifies the element containing the error message at the input level. Lob will update the text content for this element and toggle its display.

  • data-lob-primary-message-id
  • data-lob-secondary-message-id
  • data-lob-city-message-id
  • data-lob-city-message-id
  • data-lob-zip-message-id
  • data-lob-country-message-id
Example: data-lob-primary-message-id points to the element below the input for Address 1. Any errors related to the primary line will be inserted inside this element.

data-lob-err-*-value Overrides the default error message when a value is missing or specific Lob verification error messages

  • data-lob-err-primary-line-value
  • data-lob-err-city-state-zip-value
  • data-lob-err-zip-value
  • data-lob-err-undeliverable-value
  • data-lob-err-missing-unit-value
  • data-lob-err-unnecessary-unit-value
  • data-lob-err-incorrect-unit-value
  • data-lob-err-confirm-value
  • data-lob-err-default-value

data-lob-anchor-idThis optional attribute will place the general error message before the element with the id provided. An alternative attribute isdata-lob-anchor-classwhich will search for the target element by class name.

Usage with React & Vue

Modern web frameworks like React and Vue boost developer productivity without sacrificing control. Add IDs to the components of your address inputs (they will be included in the compiled HTML at runtime) then include these IDs in the form detection attributes of the AV elements script.

Note: If your component has many layers, you must ensure that the ID is propagated down to the root html components being used.

React Example

React Demo

In this demo we use React out of the box and create an address form. The AV elements script is added in public/index.htmlbefore the closing body tag. This demo also overrides some styles to keep the verification message centered in the form and to undo the styles applied to our primary address by our dependency algolia (for autocompletion).

Vue Example

Vue 3 Demo

Similarly, the AV elements script is also placed in public/index.html before the closing body tag.

A Note About Component Libraries

The AV elements script searches for key form elements like the form tag and <input type="submit" />. When building your form with component libraries such as Material-UI or Ant Design please check for the following:

  1. An ID can be propagate down to the root html elements used by the component.
  2. The components render the appropriate html elements for their behavior - they are materially honest (e.g. not styling links as buttons or using hidden elements to work correctly)

Case #1 may be the more common scenario you'll come across. If this happens, you will need to fallback to writing the component yourself in place of using the library's component.

International Support

International address verification is enabled when there is a country input present and it is set outside the United States. Form detection is relaxed on international forms since different countries may require different sets of address components.

NOTE: Autocomplete is disabled for international addresses.


AV Elements employs multiple strategies to detect your address form. If none of them work, we display an error message to help fix this. Those messages are shown below:

Missing or duplicate form elements

screenshot of missing element error
screenshot of duplicate element error

These errors arise in the form detection process. Either we are unable to find the input for a given address component, or we detected multiple inputs that may correspond to the same address component. There could be various causes for these errors including the input not existing, a label we're not familiar with, or a problem with the component's implementation from a external library.

Solution: Add the attribute(s) mentioned in the error to the AV elements script. The value should be an element id. For example, with the message above we must add the attribute data-lob-state-id.

<script src="https://cdn.lob.com/lob-address-elements/2.1.2/lob-address-elements.min.merged.js"
data-lob-state-id="id_of_state_input" ></script>