Help/FAQs
-
Basics:
-
Web:
-
Email:
-
Developers:
-
Additional Features:
-
Company/Contact:
Postful Web Service Developer's Guide
IntroductionOverview
Signup
Pricing
Accounts
Authorization
REST
Lifecycle
Documents
Uploading Attachments
Addressing
Querying
Tagging
Callbacks
Appendix
Introduction
The Postful Web Service is a pay-as-you-go REST API that allows developers to send ground mail. You can use it to mail letters or postcards, both domestically and internationally. Imagine it as a mailbox wired to the web.
Quickstart
How to Mail a Letter
The Postful API makes it easy to mail a document in two requests.
1. Upload the document.
To uploading a document, submit a POST to:
http://www.postful.com/service/upload
Be sure to include the Content-Type and Content-Length headers and the document itself as the body of the request.
POST /upload HTTP/1.0
Content-Type: application/octet-stream
Content-Length: 301456
... file content here ...
If the upload is successful, you will receive a response like the following:
<?xml version="1.0" encoding="UTF-8"?>
<upload>
<id>290797321.waltershandy.2</id>
</upload>
What is critical in this response is the id assigned by the server to your document, in this example 290797321.waltershandy.2. You will use that id to reference the document in the next step.
2. Post a mail request referencing the document.
To complete the posting of the order, submit a second request referencing the document and providing addressee information. Here is an example of the XML:
<mail>
<documents>
<document>
<type>html</type>
<attachment>290797321.waltershandy.2</attachment>
</document>
</documents>
<addressees>
<addressee>
<name>Winnie the Pooh</name>
<address>4568 Main St</address>
<city>Kenosha</city>
<state>WI</state>
<postal-code>53140</postal-code>
</addressee>
</addressees>
</mail>
Notice that the document is referenced within the attachment tag by the name provided in the first request.
Notice also that the request specifies the type of document, in this case html. Please see here for a list of supported document formats.
Please see here for an alternative explanation on embedding documents directly within the XML of the mail request. This method, however, can become unwieldy for larger documents. Note that XML requests are capped at 200k, so larger documents must be uploaded prior to making the request.
How to Mail a Postcard
The Postful API makes it easy to send a postcard, either by uploading a front image and back text or by uploading an image for both front and back.
To send a postcard:
1. Choose a Postcard Template.
To send a postcard, you must first choose a postcard template. Templates control factors such as layout, image resizing strategy, and text placement. You will be specifying the name of this template in the XML request. Here are our most commonly used templates:
Fit Image Front, Text Back
For this template, provide an image for the front of the postcard and text for the left column of the back. The front image will be scaled with a "fit" strategy: until either the height or the width reach the edge of a quarter inch background border. If the image proportions do not match the postcard minus a quarter inch border, more background border will be drawn beneath. This scaling strategy ensures that no part of the image will be cropped.
Here is an example of the required XML.
Filled Image Front, Text Back
For this template, provide an image for the front of the postcard and text for the left column of the back. The front image will be scaled with a "fill" strategy: until both height and width reach the edge of the bleed box. The image will always entirely fill the postcard front with no border, however if the image does not have the proportions of the card itself, either height or width will be cropped.
Here is an example of the required XML.
Image Front and Back
For this template, provide two images, one for the front and another for the back. Postful must reserve space on the back of the postcard for the address, barcode, and indicia. Please design your back images accordingly, and always check previews from your user account when experimenting with a new design.
Here is an example of the required XML.
2. Upload your image(s).
To uploading an image, submit a POST to:
http://www.postful.com/service/upload
Be sure to include the Content-Type and Content-Length headers and the image itself as the body of the request.
POST /upload HTTP/1.0
Content-Type: application/octet-stream
Content-Length: 301456
... file content here ...
If the upload is successful, you will receive a response like the following:
<?xml version="1.0" encoding="UTF-8"?>
<upload>
<id>290797321.waltershandy.2</id>
</upload>
What is critical in this response is the id assigned by the server to your image, in this example 290797321.waltershandy.2. You will use that id to reference the image in the next step.
3. Submit an XML request.
Submit an XML request referencing the uploaded image and provide text and addressee information to:
http://www.postful.com/service/mail
The request must be a POST method, authenticated with your user account credentials.
Here are examples of the XML for our postcard templates:
Fit Image Front, Text Back
<?xml version="1.0" encoding="UTF-8"?>
<mail>
<documents>
<document>
<template>
<source>gallery</source>
<name>Postcard: Image fit front</name>
</template>
<sections>
<section>
<name>Text</name>
<text>Hello, World!</text>
</section>
<section>
<name>Image</name>
<attachment>...attachment id...</attachment>
</section>
</sections>
</document>
</documents>
<addressees>
<addressee>
<name>John Doe</name>
<address>123 Main St</address>
<city>Anytown</city>
<state>AZ</state>
<postal-code>10000</postal-code>
</addressee>
</addressees>
</mail>
Filled Image Front, Text Back
<?xml version="1.0" encoding="UTF-8"?>
<mail>
<documents>
<document>
<template>
<source>gallery</source>
<name>Postcard: Image fill front</name>
</template>
<sections>
<section>
<name>Text</name>
<text>Hello, World!</text>
</section>
<section>
<name>Image</name>
<attachment>...attachment id...</attachment>
</section>
</sections>
</document>
</documents>
<addressees>
<addressee>
<name>John Doe</name>
<address>123 Main St</address>
<city>Anytown</city>
<state>AZ</state>
<postal-code>10000</postal-code>
</addressee>
</addressees>
</mail>
Image Front and Back
<?xml version="1.0" encoding="UTF-8"?>
<mail>
<documents>
<document>
<template>
<source>gallery</source>
<name>Postcard: Image front and back</name>
</template>
<sections>
<section>
<name>Front</name>
<attachment>...front attachment id...</attachment>
</section>
<section>
<name>Back</name>
<attachment>...back attachment id...</attachment>
</section>
</sections>
</document>
</documents>
<addressees>
<addressee>
<name>John Doe</name>
<address>123 Main St</address>
<city>Anytown</city>
<state>AZ</state>
<postal-code>10000</postal-code>
</addressee>
</addressees>
</mail>
Overview
Basics
Each order represents a single letter or poscard to one or more addressees.
A letter might contain multiple documents. For example, a PDF, a Microsoft Word document, and HTML. Each document will be ordered in the letter in the order provided within the XML POST. You can think of each document as an email attachment.
Each order, whether letter or postcard, can also be sent to multiple addressees.
Signup
Signup with a Postful user account. The API uses the same user accounts and credentials as Postful's e-mail to mail service, acting as a second gateway into Postful.
Pricing
The Postful Web Service is a purely pay-as-you-go service. The pricing structure is identical to our email gateway's. Mail is $0.99 for one page, full-color, and $0.25 for each additional page. There is no startup or initialization fee to use the service.
Accounts
Mail is only printed and delivered if there are adequate funds within the user account. Otherwise, orders are suspended until the account is supplied with additional funds.
API users are encouraged to securely store credit card information using the Postful Vault to ensure continuous service without the need for manual intervention. The Postful Vault debits cards in blocks only as additional funds are required.
Authorization
Postful Web Service uses HTTP basic authentication. Credentials must be sent along with each request. Owing to the limitations of HTTP basic, we prefer that service calls be sent over SSL with the HTTPS protocol. However, the service does listen to unencrypted HTTP at port 80.
To authorize your request, add an Authorization header to each web service call. The value of that header must be of the form:
Basic name:password
where name:password is base64 encoded.
So, for example, if the e-mail address of the account is:
pierce_inverarity@yoyodyne.com
and the password
trystero
then base64 encode:
pierce_inverarity@yoyodyne.com:trystero
The entire authorization header would look like:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
REST
The web service exposes a single resource at
http://www.postful.com/service/mail
A GET to that resource retrieves a list of all a user's orders.
A POST to that resource creates a new order. A successful request returns status code 201 Created and the location of a new resource URL. An example URL might look like:
http://www.postful.com/service/mail/1000
At this new resource, a GET will retrieve the order's status and, if available, pricing. A DELETE will cancel the order. We do not support editing an existing mail resource. If there has been a problem, please cancel and resend a new POST.
Please note that a 201 Created status only indicates that the message was received, authenticated, and validated successfully. There may still be problems with the order which make it undeliverable. For example, the submitted PDF might be invalid. Any such notification of status change or processing error will be reflected in GET calls to the created resource.
Lifecycle
An order, once posted, will pass through a sequence of statuses until it is mailed.
These statuses can be obtained either by querying the resource or by registering for a callback.
| Status | Explanation |
|---|---|
| Received | The initial status of all orders. This indicates that the order has been received and validated by the service, that a resource has been created, but preview and pricing information are not yet available. |
| Prepared | The order has been prepared for printing. Pricing and a PDF preview are available. |
| Dispatched | The order has been dispatched for printing and mailing. At this point, the order can no longer be canceled. |
| Printed | The order has been printed. |
| Mailed* | The order has been mailed. On transition to this status, the account is debited by the price of the order. |
| Canceled* | The order has been canceled by the user. This is a final status in the lifecycle of an order. |
| Please Pay | A order will reach this status if there is not adequate funds in the account to pay for this as well as any prior in-traffic orders. If the account owner credits the account, the order will revert to a Prepared status. |
| Expired* | A order will reach this status if it had been marked Please Pay, but the account had not been credited. Orders will be held in Please Pay at least one week before expiration. |
| Error* | There was an error generating the PDF of your document. This could be due to invalid document or image resources provided in the order request. |
* denotes a final status in the lifecycle of an order. An order reaching this states will not, under normal circumstances, transition to another.
Documents
The content of letters mailed through the Postful Web Service are provided by client-uploaded documents.
Presently, the service accepts the following document formats:
| XML Specifier | Name |
|---|---|
| html | HyperText Markup Language |
| Portable Document Format | |
| doc | Microsoft Word |
| txt | Plain Text |
| rtf | Rich Text Format |
| odt | Open Office Document |
To mail a document:
- Upload it and extract the
idprovided in the response body. - Reference that
idin a subsequent mail request.
Here is an example of the XML for referencing a document in a POST request:
<?xml version="1.0" encoding="UTF-8"?>
<mail>
<documents>
<document>
<type>txt</type>
<attachment>... attachment id ...</attachment>
</document>
</documents>
...
</mail>
Notice here that the value of the type element corresponds to the XML Specifier in the table above, in this case txt for a plain text file.
Uploading Attachments
Both letters and postcards will, in most cases, require the attachment of documents. Those attachments might be PDFs in the case of letters or images in the case of postcards.
To uploading an attachment, submit a POST to:
http://www.postful.com/service/upload
Be sure to include the Content-Type and Content-Length headers and the attachment itself as the body of the request.
POST /upload HTTP/1.0
Content-Type: application/octet-stream
Content-Length: 301456
... file content here ...
If the upload is successful, you will receive a response like the following:
<?xml version="1.0" encoding="UTF-8"?>
<upload>
<id>290797321.waltershandy.2</id>
</upload>
What is critical in this response is the id assigned by the server to your image, in this example 290797321.waltershandy.2. You will use that id to reference the attachment in a later request.
The attachment store is a temporary data store. Developers should not assume that these attachments will remain on servers for longer than 60 minutes.
There are benefits of speed and bandwidth for developers in separating resource upload and mail request. Let us say, for example, that a client was about to mail 1,000 postcards. If the postcards were identical in both front image and text content, then a single request to 1,000 recipients (by 1,000 <addressee> elements in the XML request) would be the simplest way to do this. However, if the client wished to vary the text of the postcard, but keep the image constant, then the client would have to make 1,000 separate requests. If the postcard image were 1 MB and included in each request, this would require a transfer of 1 GB of data! Separating (and reusing) resource upload from mail request saves bandwidth and eliminates needless redundancy.
Addressing
Domestic
Mail to the United States must be addressed using the following tags:
name required company address required address2 city required state required postal-code required
For example:
<?xml version="1.0" encoding="UTF-8"?>
<mail>
...
<addressees>
<addressee>
<name>Winnie the Pooh</name>
<company>The Pooh Company</company>
<address>4568 Main St</address>
<address2>Suite A</address2>
<city>Kenosha</city>
<state>WI</state>
<postal-code>53140</postal-code>
</addressee>
</addressees>
</mail>
will produce an envelope address:
Winnie the Pooh The Pooh Company 4568 Main St Suite A Kenosha, WI 53140
International
All international mail must be addressed using the following tags:
line1 required line2 required line3 required line4 line5 line6 line7 country required
For example:
<?xml version="1.0" encoding="UTF-8"?>
<mail>
...
<addressees>
<addressee>
<line1>Winnie the Pooh</line1>
<line2>Escuela Rural</line2>
<line3>B1000TBU San Sebastian</line3>
<country>Argentina</country>
</addressee>
</addressees>
</mail>
will produce an envelope address:
Winnie the Pooh Escuela Rural B1000TBU San Sebastian ARGENTINA
Please note that the value of the country tag must match one of the countries.
Return Addresses
If a mail request does not specify a return address, then the return address associated with the developer account shall be used.
All return addresses, whether domestic or international, must be addressed using the following tags:
line1 line2 line3 line4 line5 line6 line7
Unlike international addresses, there is no country tag on return addresses.
Here is an example of the XML:
<?xml version="1.0" encoding="UTF-8"?>
<mail>
...
<return-address>
<line1>Christopher Robin</line1>
<line2>1234 Main St</line2>
<line3>Kenosha, WI 53140</line3>
</return-address>
</mail>
Querying
Since it is a REST resource, the mail resource allows queries on two URLs.
An account's order history is available by an http GET to:
http://www.postful.com/service/mail
Each individual order can be queried at a URL like the following:
http://www.postful.com/service/mail/100000
where 100000 is the id of the order.
Tagging
The Postful Web Service allows developers to tag orders and then query them later by those tags. This would be useful, for example, in an invoicing application, where a developer might want to query the status of invoices mailed to a particular customer. Three user-specified tag fields (tag1, tag2, and tag3) of up to 256 bytes are provided.
This is how to set a tag:
<?xml version="1.0" encoding="UTF-8"?>
<mail>
<documents>
...
</documents>
<addressees>
...
</addressees>
<tag1>User 234500</tag1>
<tag2>Monthly newsletter</tag2>
</mail>
Query these tags by adding request parameters to your http GET:
http://www.postful.com/service/mail?tag1=User+234500
Callbacks
Callbacks allow developers to synchronize the status of orders posted through the Postful Web Service with records kept in their own applications. They are particularly useful for developers seeking to integrate Postful as an interface for their end users.
Postful callbacks sends notices on any change in order status after the initial post. For example, the typical Postful order will receive this sequence of callbacks:
| Callback | Status Change |
|---|---|
| First callback | Received -> Prepared |
| Second callback | Prepared -> Dispatched |
| Third callback | Dispatched -> Printed |
| Fourth callback | Printed -> Mailed |
You can set the URL for callbacks to your server at:
http://www.postful.com/developer/settings
The callback itself is an http POST with four parameters:
| Parameter | Description |
|---|---|
| order | the id of the order |
| changed_at | the time of the status change |
| new_status | the new status |
| previous_status | the previous status |
Callbacks will be issued only on orders posted through the Web Service. And there is no need to register orders individually for callback. Callbacks can be disabled, just by blanking out the callbacks url on the developer settings page.
Some status transitions will signal that other information has become available. For example, price, page count, and preview become available when an order transition to "Prepared", so it is a common idiom to issue a GET to the resource on receiving the callback.
Best Practices
Versioning
It is the goal of the Postful team to continue building an agile, feature-laden web service. However, it is a priority of the service to ensure compatibility with existing clients. In particular, developers who use code generating tools to unmarshal XML might find themselves susceptible to breakages caused by slight changes in outgoing XML responses, as the service continues to add features and report on them.
For that reason, the Postful Web Service is versioned. Any released version number of the service is considered frozen from any changes of specification.
In addition to these frozen releases, there's also the edge version of the web service at
http://www.postful.com/service/mail
It is recommended as a best practice that developers code to the latest frozen version of the web service to ensure the reliability of expectations on incoming and outgoing XML.
The latest frozen release of the Postful Web Service is 0.10, to be found at the URL:
http://www.postful.com/service/v/0.10/mail
Testing
Sandbox accounts are available for development and testing at:
http://www.postful.com/sandbox/signup
Sandbox users will receive a dummy notification (and callbacks) on mail requests. These notifications are only for the purposes of testing, and no mail is printed or delivered from sandbox accounts.
One caveat is that once a developer account is established with an e-mail address, that e-mail address will not be available for creating a production account. Please plan accordingly.
Appendix
A. Countries
The following is a list of countries supported for international mailing:
In supplying addresses for international mailing, as in:
<?xml version="1.0" encoding="UTF-8"?>
<mail>
...
<addressees>
<addressee>
<line1>The Queen</line1>
<line2>Buckingham Palace</line2>
<line3>London SW1A 1AA</line3>
<country>United Kingdom</country>
</addressee>
</addressees>
</mail>
please provide the country name exactly as it appears below:
| Afghanistan | Canada | Gambia | Laos | Nigeria | Suriname |
| Albania | Cape Verde | Georgia | Latvia | North Korea | Swaziland |
| Algeria | Cayman Islands | Germany | Lebanon | Norway | Sweden |
| Andorra | Chad | Ghana | Lesotho | Oman | Switzerland |
| Angola | Chile | Gibraltar | Liberia | Pakistan | Syria |
| Anguilla | China | Great Britain | Libya | Panama | Taiwan |
| Antigua and Barbuda | Colombia | Greece | Lichtenstein | Papua New Guinea | Tajikistan |
| Argentina | Comoros | Greenland | Lithuania | Paraguay | Tanzania |
| Armenia | Congo | Grenada | Luxemborg | Peru | Thailand |
| Aruba | Costa Rica | Guadeloupe | Macao | Philippines | Togo |
| Ascension | Croatia | Guatemala | Macedonia | Poland | Tonga |
| Australia | Cuba | Guinea | Madagascar | Portugal | Trinidad and Tobago |
| Austria | Cyprus | Guinea-Bissau | Malawi | Qatar | Tunisia |
| Azerbaijan | Czech Republic | Guyana | Malaysia | Romania | Turkey |
| Bahamas | Denmark | Haiti | Maldives | Russian Federation | Turkmenistan |
| Bahrain | Djibouti | Honduras | Mali | Rwanda | Tuvalu |
| Bangladesh | Dominica | Hong Kong | Malta | Saint Lucia | Uganda |
| Barbados | Dominican Republic | Hungary | Marshall Islands | Samoa | Ukraine |
| Belarus | Ecuador | Iceland | Martinique | San Marino | United Arab Emirates |
| Belgium | Egypt | India | Mauritania | Sao Tome and Principe | United Kingdom |
| Belize | El Salvador | Indonesia | Mauritius | Saudi Arabia | Uruguay |
| Benin | El Salvador | Iran | Mexico | Senegal | Uzbekistan |
| Bermuda | Equatorial Guinea | Iraq | Micronesia | Serbia-Montenegro | Vanuatu |
| Bhutan | Eritrea | Ireland | Moldova | Seychelles | Vatican City |
| Bolivia | Estonia | Israel | Mongolia | Sierra Leone | Venezuela |
| Bosnia-Herzegovina | Ethiopia | Italy | Morocco | Singapore | Vietnam |
| Botswana | Falkland Islands | Jamaica | Mozambique | Slovakia | Virgin Islands (U.S.) |
| Brazil | Faroe Islands | Japan | Myanmar (Burma) | Slovenia | Yemen |
| British Virgin Islands | Fiji | Jordan | Namibia | Solomon Islands | Zambia |
| Bulgaria | Finland | Kazakhstan | Nepal | South Africa | Zimbabwe |
| Burkina Faso | France | Kenya | Netherlands | South Korea | |
| Burundi | French Guiana | Kiribati | New Zealand | Spain | |
| Cambodia | French Polynesia | Kuwait | Nicaragua | Sri Lanka | |
| Cameroon | Gabon | Kyrgyzstan | Niger | Sudan |