POST /api/v1/postcards/send
Send one or many postcards with custom HTML. Authenticated callers can pay with tokens or saved card. Guest callers can send by providing a guest Stripe PaymentIntent or a Stripe shared payment token from an agentic payment flow.
Request body
{
"from": {
"firstName": "Avery",
"lastName": "Lane",
"line1": "123 Main St",
"city": "Denver",
"stateProvince": "CO",
"postalCode": "80202",
"country": "US"
},
"to": [
{
"firstName": "Jordan",
"lastName": "Parker",
"line1": "456 Ocean Ave",
"city": "San Francisco",
"stateProvince": "CA",
"postalCode": "94105",
"country": "US"
}
],
"imageUrl": "https://example.com/front.png",
"imageOrientation": "landscape",
"messageText": "Wish you were here.",
"messageFontFamily": "tpc-letters-home",
"agenticPayment": {
"sharedPaymentToken": "spt_..."
},
"templateContext": {
"front": { "templateId": 101, "templateName": "Summer Front" },
"back": { "templateId": 202, "templateName": "Photo Back" }
}
}Validation highlights
tosupports1-500recipients.- Default sends use
imageUrl,imageOrientation,messageText, andmessageFontFamily. - Use
frontHtml/backHtmlonly for template output or advanced custom HTML overrides. - Do not simulate requested generated artwork with HTML/CSS shapes. Generate or upload a real image and pass its URL as
imageUrl. - Public agent/API payloads place
backHtmlin the safe left message zone, about2.3165in x 3.75in, and reserve Lob’s lower-right no-ink area (3.2835in x 2.375in) for address/postage/barcode handling. - Handwritten-style notes can use bundled CSS font families:
"tpc-letters-home","tpc-ugly-dave","tpc-ugly-dave-alternates","tpc-marina-script", or"Dancing Script". - Do not draw recipient addresses, postage, postal barcodes, or stamp boxes into postcard HTML. Pass addresses in
to; tinypostcard handles mailing/addressing separately. - Each HTML string max length:
2,000,000. - Countries must be valid ISO alpha-2 codes.
Billing behavior
- If user has enough tokens, tokens are consumed.
- If not enough tokens and a saved card exists, card is charged.
- Guest sends require
guestPaymentIntentIdoragenticPayment.sharedPaymentToken. - Stripe shared payment tokens are charged with a
PaymentIntentusingpayment_method_data[shared_payment_granted_token]. - Guest agent clients can also call the endpoint without payment first. The endpoint returns
402 Payment Requiredwith aWWW-Authenticate: Paymentheader containing a Stripe machine-payment challenge. Uselink-cli mpp payor decode the challenge, approve a shared payment token, and retry withAuthorization: Payment .... - If tokens or card setup are missing for an authenticated caller, the endpoint returns
402and the agent can callPOST /api/v1/token-pack-checkoutto create a Link-compatible hosted checkout. - Partial failures automatically trigger refund/credit compensation for failed recipients.
Success response
{
"success": true,
"batchId": "uuid",
"recipientCount": 1,
"persistedSendIds": [1234],
"failedCount": 0,
"failedRecipients": [],
"billing": {
"mode": "token",
"amountCents": 0,
"tokenCount": 1,
"stripePaymentIntentId": null
}
}Common errors
401: missing/invalid API key for authenticated-only operations402: insufficient payment method or token race condition400: payload validation issues502: downstream print provider errors
For authenticated token-pack 402 responses, agents should not ask for raw card credentials. Call POST /api/v1/token-pack-checkout, open the returned hosted Checkout URL, and follow https://link.com/skill.md if the agent needs a Link-issued payment credential.
For guest agentic payments, call the MCP prepare_postcard_send tool first, read https://link.com/skill.md, authenticate Link if needed, and issue a Stripe shared payment token scoped to the tinypostcard Stripe business profile. Then call this endpoint with agenticPayment.sharedPaymentToken.
For the automatic machine-payment flow, post the final send payload without guestPaymentIntentId or agenticPayment. If the payload is otherwise valid, the endpoint returns a 402 Stripe challenge:
link-cli mpp pay https://tinypostcard.com/api/v1/postcards/send \
--spend-request-id spr_... \
--method POST \
--data "$(cat payload.json)"The Link skill/MCP or link-cli mpp pay probes the endpoint, reads WWW-Authenticate, creates the Authorization: Payment retry header from the approved shared payment token, and submits the paid request.