Send physical letters anywhere in Canada programmatically. One endpoint, three modes.
Send a letter in one API call. You need an account with a payment method and an API key.
curl -X POST https://sendletter.app/api/v1/send \
-H "Authorization: Bearer sl_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "draft",
"letter_size": "standard",
"from": {
"name": "Jane Smith",
"line1": "123 Maple St",
"city": "Toronto",
"province": "ON",
"postal_code": "M5V 2T6",
"country": "CA"
},
"to": {
"name": "John Doe",
"line1": "456 Oak Ave",
"city": "Vancouver",
"province": "BC",
"postal_code": "V6B 1A1",
"country": "CA"
},
"letter": {
"date": "2026-03-23",
"salutation": "Dear John,",
"body": "This is a test letter sent via the sendletter API.",
"closing": "Sincerely,",
"signature": "Jane Smith"
}
}'All requests require a Bearer token in the Authorization header.
Authorization: Bearer sl_live_YOUR_API_KEY
API keys start with sl_live_. Keep your key secret. If compromised, regenerate it from your profile — this immediately invalidates the old key.
Your account must have a valid payment method on file. Requests without one return 402.
Creates a letter order. The letter is queued for printing and mailed within 1 business day via Canada Post.
| Field | Type | Required | Description |
|---|---|---|---|
| mode | string | Yes | "draft", "formatted", or "upload" |
| letter_size | string | No | "standard" (default), "large", or "legal" |
| from | object | Yes | Return address (see Addresses) |
| to | object | Yes | Delivery address — must be in Canada |
| letter | object | Draft only | Letter content fields (see Draft mode) |
| html | string | Formatted only | HTML content for the letter body |
| css | string | No | Additional CSS (formatted mode only) |
| file | string | Upload only | Base64-encoded PDF or DOCX |
| file_type | string | Upload only | "pdf" or "docx" |
| page_count | number | No | Number of pages (upload mode, max 15) |
| font | string | No | Font family (see Options) |
| font_size | number | No | Font size in pt (8–24, default 12) |
| vertical_center | boolean | No | Vertically center content on page |
{
"id": "uuid-of-order",
"status": "queued",
"letter_size": "standard",
"amount_cents": 379
}Provide structured letter fields. We render them into a properly formatted letter page.
| letter.* | Type | Required | Description |
|---|---|---|---|
| body | string | Yes | Main letter text (max 50,000 chars). Whitespace is preserved. |
| date | string | No | Date line (top-right) |
| salutation | string | No | Greeting, e.g. "Dear John," |
| subject | string | No | Subject line (rendered as bold Re: ...) |
| reference | string | No | Reference number |
| closing | string | No | Sign-off, e.g. "Sincerely," |
| signature | string | No | Printed name below closing |
| cc | string | No | CC line |
| enclosures | string | No | Enclosures note |
| ps | string | No | Post-script (italic) |
Send your own HTML content. We wrap it in a print-safe page template with proper dimensions (8.5×11" or 8.5×14" at 72dpi, 1" margins). Max 500 KB.
{
"mode": "formatted",
"html": "<h1>Hello World</h1><p>Custom HTML letter content.</p>",
"css": "h1 { color: navy; }",
"font": "Georgia",
"font_size": 14
}Upload a pre-formatted PDF or DOCX file as a base64 string. Max 10 MB, max 15 pages.
{
"mode": "upload",
"file": "JVBERi0xLjQK...",
"file_type": "pdf",
"page_count": 2
}| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Full name (max 200 chars) |
| line1 | string | Yes | Street address (max 200 chars) |
| line2 | string | No | Apt, suite, unit (max 200 chars) |
| city | string | Yes | City (max 200 chars) |
| province | string | CA/US | Province or state code (required for CA and US) |
| postal_code | string | CA/US | Postal or ZIP code (required for CA and US) |
| country | string | No | 2-letter ISO code. Defaults to "CA" |
to address must be in Canada ("country": "CA"). The from (return) address can be in any country. Canadian postal codes must match at least the FSA format (e.g. K1A) or full format (K1A 0B1).| Value | Dimensions | Envelope | Max Pages | Price |
|---|---|---|---|---|
| standard | 8.5 × 11 in | #10 (tri-fold) | 5 | $3.79 CAD |
| large | 8.5 × 11 in | 9 × 12 (flat) | 15 | $5.78 CAD |
| legal | 8.5 × 14 in | 10 × 15 (flat) | 15 | $5.78 CAD |
Available for draft and formatted modes:
All prices are in Canadian dollars (CAD) and include printing, envelope, Canada Post postage, and tax.
| Size | Price |
|---|---|
| Standard (tri-fold) | $3.79 |
| Large (flat 8.5×11) | $5.78 |
| Legal (flat 8.5×14) | $5.78 |
| Status | Meaning | Common Causes |
|---|---|---|
| 400 | Bad Request | Missing/invalid fields, non-CA delivery address, invalid postal code, content too large |
| 401 | Unauthorized | Missing or invalid API key |
| 402 | Payment Required | No payment method on file — add one at sendletter.app/profile |
| 500 | Server Error | Internal error — contact support |
All error responses include an error field with a human-readable message:
{ "error": "to.postal_code is not a valid Canadian postal code. Expected format: A1A 1A1" }API usage is billed daily. Each letter is charged at the listed price. Charges are processed automatically against your saved payment method. You can view usage and billing history on your profile.
| Constraint | Limit |
|---|---|
| Request body | JSON, Content-Type: application/json |
| File upload (base64) | 10 MB |
| HTML content | 500 KB |
| Draft body text | 50,000 characters |
| Page count | 1–15 |
| Font size | 8–24 pt |
| Address fields | 200 characters each |
| Delivery country | Canada only (to.country = "CA") |
Questions? support@sendletter.app