curl -X POST https://thepostalcompany.com/api/v1/letters \
-H "Authorization: Bearer tpc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"content": "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards"
}'
curl -X POST https://thepostalcompany.com/api/v1/letters \
-H "Authorization: Bearer tpc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"content": "Dear Jane,\n\nThis is a draft letter.\n\nBest regards",
"send": false
}'
const response = await fetch("https://thepostalcompany.com/api/v1/letters", {
method: "POST",
headers: {
"Authorization": "Bearer tpc_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
recipient: "Jane Doe",
address: {
street: "Keizersgracht",
number: "123",
postalcode: "1015 CJ",
city: "Amsterdam",
country: "NL",
},
content: "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards",
}),
});
const data = await response.json();
console.log(data.id); // letter ID
import requests
response = requests.post(
"https://thepostalcompany.com/api/v1/letters",
headers={"Authorization": "Bearer tpc_your_api_key"},
json={
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL",
},
"content": "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards",
},
)
data = response.json()
print(data["id"]) # letter ID
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "processing",
"balance_cents": 1000
}
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "draft"
}
{
"error": "address.country must be a valid ISO 3166-1 alpha-2 code (e.g. NL, BE, DE)"
}
{
"error": "Invalid or revoked API key"
}
{
"error": "Insufficient balance",
"balance_cents": 100,
"letter_price_cents": 250
}
Letters
Create a Letter
Create a letter as a draft or send it immediately.
POST
/
api
/
v1
/
letters
curl -X POST https://thepostalcompany.com/api/v1/letters \
-H "Authorization: Bearer tpc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"content": "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards"
}'
curl -X POST https://thepostalcompany.com/api/v1/letters \
-H "Authorization: Bearer tpc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"content": "Dear Jane,\n\nThis is a draft letter.\n\nBest regards",
"send": false
}'
const response = await fetch("https://thepostalcompany.com/api/v1/letters", {
method: "POST",
headers: {
"Authorization": "Bearer tpc_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
recipient: "Jane Doe",
address: {
street: "Keizersgracht",
number: "123",
postalcode: "1015 CJ",
city: "Amsterdam",
country: "NL",
},
content: "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards",
}),
});
const data = await response.json();
console.log(data.id); // letter ID
import requests
response = requests.post(
"https://thepostalcompany.com/api/v1/letters",
headers={"Authorization": "Bearer tpc_your_api_key"},
json={
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL",
},
"content": "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards",
},
)
data = response.json()
print(data["id"]) # letter ID
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "processing",
"balance_cents": 1000
}
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "draft"
}
{
"error": "address.country must be a valid ISO 3166-1 alpha-2 code (e.g. NL, BE, DE)"
}
{
"error": "Invalid or revoked API key"
}
{
"error": "Insufficient balance",
"balance_cents": 100,
"letter_price_cents": 250
}
Create a Letter
Create a physical letter by providing recipient details, a validated address, and the letter content. By default, the letter is sent immediately. Setsend to false to create a draft you can review and send later.
Request
string
Name of the recipient. Maximum 30 characters.
object
required
The recipient’s postal address.
Show address properties
Show address properties
string
required
Street name (e.g. “Keizersgracht”).
string
required
House/building number (e.g. “123”).
string
Address suffix or addition (e.g. “A”, “2nd floor”).
string
required
Postal or ZIP code (e.g. “1015 CJ”).
string
required
City name (e.g. “Amsterdam”).
string
required
ISO 3166-1 alpha-2 country code (e.g. “NL”, “BE”, “DE”).
string
required
The letter body text. Line breaks (
\n) are preserved for formatting.boolean
default:"true"
Whether to send the letter immediately. Set to
false to create a draft. Drafts can be updated with PATCH /api/v1/letters/:id and sent with POST /api/v1/letters/:id/send.Response
string
The unique letter ID.
string
The letter status —
"processing" when sent immediately, "draft" when created as a draft.integer
Your remaining balance in cents after this letter. Only present when
send is true.Examples
curl -X POST https://thepostalcompany.com/api/v1/letters \
-H "Authorization: Bearer tpc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"content": "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards"
}'
curl -X POST https://thepostalcompany.com/api/v1/letters \
-H "Authorization: Bearer tpc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"content": "Dear Jane,\n\nThis is a draft letter.\n\nBest regards",
"send": false
}'
const response = await fetch("https://thepostalcompany.com/api/v1/letters", {
method: "POST",
headers: {
"Authorization": "Bearer tpc_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
recipient: "Jane Doe",
address: {
street: "Keizersgracht",
number: "123",
postalcode: "1015 CJ",
city: "Amsterdam",
country: "NL",
},
content: "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards",
}),
});
const data = await response.json();
console.log(data.id); // letter ID
import requests
response = requests.post(
"https://thepostalcompany.com/api/v1/letters",
headers={"Authorization": "Bearer tpc_your_api_key"},
json={
"recipient": "Jane Doe",
"address": {
"street": "Keizersgracht",
"number": "123",
"postalcode": "1015 CJ",
"city": "Amsterdam",
"country": "NL",
},
"content": "Dear Jane,\n\nThis is a letter sent via the API.\n\nBest regards",
},
)
data = response.json()
print(data["id"]) # letter ID
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "processing",
"balance_cents": 1000
}
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "draft"
}
{
"error": "address.country must be a valid ISO 3166-1 alpha-2 code (e.g. NL, BE, DE)"
}
{
"error": "Invalid or revoked API key"
}
{
"error": "Insufficient balance",
"balance_cents": 100,
"letter_price_cents": 250
}
Error codes
| Status | Description |
|---|---|
400 | Invalid request body — missing or invalid fields |
401 | Missing, invalid, or revoked API key |
402 | Insufficient balance to send the letter (only when send is true) |
500 | Internal server error |
