Skip to main content

Estimating an Order's Cost

Before you send mail through the API, you can price the exact order you are about to place. Post the same request body you would send to /api/v2/send/{mailer-type} to /api/v2/estimate/{mailer-type} instead. The response tells you what the order costs and whether your balance covers it.

An estimate never places an order: nothing is charged, nothing is printed or mailed, and no order appears in your account.

Endpoints​

POST https://api.thanks.io/api/v2/estimate/{mailer-type}

There is one estimate endpoint for each send endpoint. Replace {mailer-type} with the same value you use to send:

Estimate endpointPrices the same order as
/api/v2/estimate/postcard/api/v2/send/postcard
/api/v2/estimate/letter/api/v2/send/letter
/api/v2/estimate/windowedletter/api/v2/send/letter (windowed letter)
/api/v2/estimate/windowlessletter/api/v2/send/windowlessletter
/api/v2/estimate/notecard/api/v2/send/notecard
/api/v2/estimate/magnacard/api/v2/send/magnacard
/api/v2/estimate/giftcard/api/v2/send/giftcard

Authenticate with the same Authorization: Bearer header you use to send. See Authorization Headers.

The request is validated exactly as the matching send is, so a payload that would be rejected on send (no recipients, no creative, an invalid field) comes back with the same 422 error from the estimate. That makes an estimate a safe first call while you build an integration.

Example​

Request:

curl -X POST https://api.thanks.io/api/v2/estimate/postcard \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size": "4x6",
"message": "Thanks for being a customer!",
"front_image_url": "https://example.com/front.jpg",
"recipients": [
{ "name": "Jane Doe", "address": "123 Main St", "city": "Austin", "province": "TX", "postal_code": "78701", "country": "US" }
]
}'

Response (values are illustrative):

{
"message": "OK",
"data": {
"type": "postcard",
"size": "4x6",
"total_recipients": 1,
"recipients": { "united_states": 1, "international": 0 },
"pending_email_lookups": 0,
"costs_in_cents": {
"united_states": 118,
"international": 0,
"additional_pages": 0,
"giftcard_face_value": 0,
"grand_total": 118
},
"total_cost_in_cents": 118,
"total_cost": "$1.18",
"current_balance_in_cents": 5000,
"covered_by_balance": true,
"test_mode": false,
"notes": []
}
}

Response fields​

FieldWhat it tells you
type, sizeThe mailer type and size that were priced.
total_recipientsHow many pieces the order would mail.
recipients.united_states, recipients.internationalThe recipient count split by destination.
pending_email_lookupsRecipients sent with an email address but no mailing address. See Email-only recipients.
costs_in_cents.united_states, costs_in_cents.internationalPostage and printing for US and international pieces.
costs_in_cents.additional_pagesExtra letter pages, charged per page.
costs_in_cents.giftcard_face_valueThe combined face value of every gift card in the order. 0 for other mailer types.
costs_in_cents.grand_totalEverything in the order except gift card face value.
total_cost_in_centsThe order total: grand_total plus giftcard_face_value.
total_costThe same total, formatted in dollars (for example $1.18).
current_balance_in_centsYour account's credit balance right now.
covered_by_balancetrue if your balance covers total_cost_in_cents.
test_modetrue if API Test Mode is on for your account.
notesPlain-language caveats about anything that could make the real charge differ. Empty when there are none.

For postcards, letters, Notecards, and MagnaCards, total_cost_in_cents is exactly what the same request is charged when you send it.

Things to know​

Email-only recipients​

When a recipient has an email address but no mailing address, a send looks up their address from the email, and that lookup is a paid data service. An estimate does not run the lookup. Instead, it prices those recipients as if the lookup finds an address, counts them in pending_email_lookups, and adds a note. When you send, any recipient whose address can't be found is not mailed and not charged, so the real charge can be lower than the estimate but not higher.

Additional letter pages​

Extra pages for a letter are priced by counting the pages in the PDF you supply. If the PDF can't be read, those pages are left out of the estimate and a note says so. They are still charged per page when the order is sent, so in that case the real charge will be higher than the estimate.

Gift cards​

A gift card estimate includes the face value of every card in costs_in_cents.giftcard_face_value and in total_cost_in_cents. On paid plans, a card's face value is only charged if the recipient redeems it (see Billing FAQs), so treat total_cost_in_cents as the most a gift card order can cost, and costs_in_cents.grand_total as the cost of mailing it.

If your account can't send gift cards, a gift card estimate is refused with HTTP 402 and the code giftcards_require_paid_plan, the same response the send endpoint returns.

Test mode​

An estimate always quotes your account's real rates. If test_mode is true, sending the same request places an order that is cancelled automatically and not charged. Turn test mode off before you rely on the estimate as the amount you will pay. See API Test Mode.

Balance​

If covered_by_balance is false, the send will need more credits than you have. For a gift card order on a paid plan, compare your balance to costs_in_cents.grand_total instead, since face value is charged later, as cards are redeemed. With Auto-Recharge on, your card is charged to top up your balance; with Auto-Recharge off, a send that would take your balance below $0 is blocked. See Credits, Balance & Auto-Recharge.

What an estimate doesn't check​

An estimate prices the order and validates the request. It does not render your artwork or handwriting, so a problem that only shows up when the piece is rendered, such as a message too long to fit the card, is reported when you send, not by the estimate.