Get started
Postaged developer docs
Send recipients to a dynamic campaign, sync a custom CRM, receive QR scan webhooks, and connect Claude to Postaged.
What you can build
Postaged prints and mails real cards. These APIs let your own systems decide who gets one, keep your contacts in sync, and react when someone scans a card's QR code.
Send recipients to a dynamic campaign
Post people to a live campaign as they qualify. We verify each address, apply your filters, and mail everyone who passes, up to your budget.
Mail your first recipient by API Dynamic Audience API reference
Sync a custom CRM
Push every contact from your own system once a day, mapped and typed, so campaigns can mail people from it.
Receive QR scan webhooks
Get a POST to your endpoint every time someone scans a QR code on one of your cards.
Connect Claude
Let Claude build and test your CRM sync, or help write address book formulas, through our MCP servers.
New here? Start with Mail your first recipient by API. It walks you through a test request before anything mails.
Send recipients
curl https://www.postaged.com/api/v1/recipients \
-H "Authorization: Bearer $POSTAGED_SEND_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": "PA-4H2K9C",
"recipients": [
{
"reference": "crm-001",
"first_name": "Dana",
"last_name": "Reyes",
"address_1": "25 Gale Road",
"city": "Bloomfield",
"state": "CT",
"zip": "06002"
}
]
}'const response = await fetch("https://www.postaged.com/api/v1/recipients", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.POSTAGED_SEND_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
campaign_id: "PA-4H2K9C",
recipients: [
{
reference: "crm-001",
first_name: "Dana",
last_name: "Reyes",
address_1: "25 Gale Road",
city: "Bloomfield",
state: "CT",
zip: "06002",
},
],
}),
});
const result = await response.json();
console.log(result);import os
import requests
response = requests.post(
"https://www.postaged.com/api/v1/recipients",
headers={"Authorization": f"Bearer {os.environ['POSTAGED_SEND_KEY']}"},
json={
"campaign_id": "PA-4H2K9C",
"recipients": [
{
"reference": "crm-001",
"first_name": "Dana",
"last_name": "Reyes",
"address_1": "25 Gale Road",
"city": "Bloomfield",
"state": "CT",
"zip": "06002",
},
],
},
timeout=300,
)
print(response.json()){
"summary": { "received": 1, "mailed": 1, "notMailed": 0 },
"results": [
{
"reference": "crm-001",
"address": "25 Gale Rd, Bloomfield, CT 06002-2214",
"status": "mailed",
"detail": "Queued to send.",
"product_type": "Handwritten Card & Handwritten Envelope",
"postage": "first_class",
"mail_by_date": "2026-10-06"
}
]
}The basics
- Every request goes to https://www.postaged.com over HTTPS and sends and receives JSON.
- You authenticate with an API key. An Owner or Admin creates keys in Settings > API & Webhooks, and integration keys on that integration's page. Each kind of key opens different endpoints: see Authentication and API keys.
- Send the key in the
Authorization: Bearerheader. Never put a key in a URL or a query string. - Keep keys in your own systems. Give an AI client only an integration key or a Formulas only key, never a Full access key.
- Postaged has no test keys or sandbox. Testing lists the safe ways to check an integration without mailing anyone.
Authorization: Bearer $POSTAGED_SEND_KEY
Content-Type: application/jsonDocs for your tools and your AI
Every page in these docs is also plain Markdown at its own address plus .md, with every code sample in all three languages. Use Copy page for Claude at the top of any page to paste it into a conversation.
/llms.txtlists every page with its title, a one-line description, and its Markdown address./openapi.jsonis the OpenAPI 3.1 description of the REST APIs and theqr.scannedwebhook.
https://www.postaged.com/llms.txt
https://www.postaged.com/openapi.json
https://www.postaged.com/docs/quickstart.mdChanges and versions
Changes to /v1 only add things, so build your integration to ignore fields and codes it doesn't recognize. Read Versioning for the rules and the Changelog for what changed and when.