Technical guide · Webhooks
Webhooks for direct mail automation
Turn one verified software event into one mail record. Keep the event ID, address, creative version, duplicate key, and mailpiece ID together.
- Reviewed against primary sources
- Last updated: October 11, 2026
- No setup fees
Payload
Send IDs and fields, not sentences.
Every retry reuses the same event ID.
How retries stay safe{
"event_id": "lead_4821_created",
"source_record_id": "4821",
"recipient": { "first_name": "Avery" },
"address": {
"city": "Sample City",
"state": "AZ"
},
"template_id": "seller-intro-v3",
"test": true
}
A retry must reuse the same event ID. Test mode must not release live mail.
Start here
How do you use webhooks for direct mail automation?
Create an event-to-mail contract before you connect the systems.
- Choose the eventName the exact business change that makes the record eligible.
- Define the payloadSend stable IDs, structured address fields, template data, and test state.
- Define the resultReturn and store accepted, held, failed, and released states.
Read the full answer
The source system sends one documented event. The receiving workflow validates the payload, checks the address and duplicate key, renders a proof, and records a release decision. A webhook is only the transport. The controls around it determine whether the workflow is safe. For the record design behind this contract — the fields an event must carry before it is safe to release — see direct mail API guidance.
Use direct mail automation for the broader operator workflow and direct mail API guidance for record design.
Field map
Write the contract before the first request.
Agree on these fields before anyone sends a live request.
| Control | Example value | Decision before launch |
|---|---|---|
| Source event | lead.created, job.closed, or payment_intent.succeeded | The event that proves the business condition. |
| Source key | CRM record ID or order ID | One stable key through retries and writeback. |
| Recipient | Name plus structured postal fields | Hold incomplete or ambiguous records. |
| Creative | Template ID, version, and merge fields | Render the exact values the recipient sees. |
| Duplicate rule | Source event key plus campaign ID | Retries keep the same key; duplicate records are held. |
| Result | Accepted, held, failed, or released | Status and reason, written back to the source. |
Webhook FAQ
Settle tests and retries first.
Pricing it out? See plans and per-piece rates.
Primary sources
No public Sendvo endpoint published. Plans: list upload, dedupe, and automated mail need Operator or Growth. Integrations and API access need Growth and connect through a no-code tool or our API. Product plans, trigger names, and connector access can change. Confirm yours before production use.
Payload and fields
How do you send one personalized postcard from a webhook?
Send structured fields, not a finished sentence. Map each source field to one named template field. Keep recipient name and postal address separate from optional personalization, such as property city, service type, or order number. Use a fallback or hold the record when an optional value is empty.
Render a proof from the same payload that will create the mail record. Save the template version with the source event ID.
How do you map CRM fields to postcard personalization fields?
Use a field map with a type, requirement, fallback, and failure rule for every value. For example, map contact.firstname to first_name, property.city to property_city, and the CRM record ID to source_record_id. Do not place the same field in the address block and the marketing copy unless both uses are intentional.
A visible field map makes changes reviewable. It also stops a CRM rename from silently creating blank postcard copy.
Tests and retries
How do you test a direct-mail webhook without sending live mail?
Use a non-mailing test boundary and a record that is easy to identify. Send a test flag or use the account's approved test environment. Confirm that the request authenticates, validates, deduplicates, renders, and returns a test result. A successful HTTP response alone does not prove that the proof or field map is correct.
If no non-mailing test mode is available, stop. Do not use a real address as a substitute for an explicit test boundary.
How do you handle webhook retries without sending duplicate postcards?
Treat retries as repeat attempts for the same event, not as new sends. Reuse the same event ID and idempotency key. Store the first accepted result. If the same key returns with the same payload, return the saved result. If the payload changes, hold the request for review.
Use the detailed direct-mail idempotency key guide to define key scope and retention.
How do you use an idempotency key for a physical-mail request?
Build the key from the business event that must create at most one mail record. A useful key can combine the source system, source record ID, trigger name, and source event ID. Do not generate a new random key for every retry. That defeats duplicate protection.
Keep the key after the network request finishes. Physical production cannot always be reversed after release.
How do you pause a direct-mail automation without deleting the connection?
Disable release while keeping intake and audit records visible. A paused workflow can continue to record or hold eligible events, but it must not release mail. Show the pause owner, start time, reason, held-record count, and restart decision. Do not rely only on deleting a webhook URL.
Decide whether held events expire, need manual review, or can release after restart.
How do you handle a missing or invalid mailing address in an automated workflow?
Hold the record before proof or release and return a specific reason. Separate missing fields, malformed fields, secondary-unit risk, and other address exceptions. Write the reason to the source system when possible. Do not guess a unit number or silently drop part of an address.
Use the mailable address guide for the review fields that support this decision.
After release
How do you track a webhook-triggered postcard after submission?
Store the source event ID, campaign ID, batch ID, and mailpiece ID in one join record. Subscribe to available status events and save each event with its time and source. Mailstream visibility can support operations. It does not prove that a person saw the piece, responded, or caused revenue.
Use the USPS postcard tracking guide for measurement boundaries.
How do you write mail status back to a CRM?
Update dedicated mail-status fields or create a related mail-activity record. Store the source event ID, current operational state, exception reason, campaign ID, mailpiece ID, and event time. Keep trigger fields separate from result fields so the writeback cannot replay the send workflow. Use a related record when one contact, deal, or property can have several mail events.
Label accepted, held, failed, released, mailstream, response, and revenue states separately. One state does not prove another.
Quick answers
Does a 200 response mean the postcard was mailed?
No. It can mean only that the receiver accepted the request. Store the returned state and do not call the piece mailed until the workflow reports a release state.
Can a webhook retry create duplicate mail?
Yes. A retry can create another mail record if the receiver does not enforce idempotency and duplicate rules.
Does tracking prove delivery or response?
No. Mailstream events are operational signals. They do not prove recipient exposure, response, or revenue.
Before launch
Preflight checklist before the first live send
- Use one stable source-event ID and save it with the mail record.
- Require recipient name, address line 1, city, state, and ZIP Code before release.
- Set a duplicate rule for the person, household, property, order, or job.
- Render a proof with a test record before any funded send.
- Define who can pause the workflow and who can approve release.
- Store the source record ID, campaign ID, and returned mailpiece ID together.
- Treat mailstream events as operational signals, not proof of attention or revenue.
Turn one event into one mail record.
Confirm access, test the payload, check the proof, and set the duplicate rule before you turn on release.