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.

To price a saved creative, send its creative_id with your recipients instead of the design fields, exactly as you would to send it:

{
"creative_id": 123,
"recipients": [
{ "name": "Jane Doe", "address": "123 Main St", "city": "Austin", "province": "TX", "postal_code": "78701", "country": "US" }
]
}

The same rules apply as on send: a creative of another mail type or size, an incomplete creative, or a creative_id combined with design or message fields is refused with a 422. See Finding Creative & Template IDs.

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. Postcards are reported by size: postcard for 4x6, postcard6x9 for 6x9, and postcard6x11 for 6x11.
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.

Postage class​

An estimate is priced at the postage class the send would use. Send postage_class as first_class or standard (Standard Mail, also known as Marketing Mail) to price a specific class, or leave it out to price your account's default class, set by Standard Mail Mode in Settings → Mail Preferences. To compare the two, post the same body twice with each value.

Standard Mail's lower price applies to US addresses only, so costs_in_cents.international is the same either way. On the Free plan every piece is priced and mailed First Class, whichever class you send. Nonprofit accounts are priced at their nonprofit rate, except for multi-page letters.

The older send_standard_mail field is deprecated. It can only switch a request to Standard Mail, never to First Class, and a request that includes both send_standard_mail and postage_class is rejected with a 422. See Postage Options.

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.