Send eCard API #
Send a branded eCard to a recipient by email, schedule it for later, or generate a shareable link (no email) that you route however you like (Slack, SMS, a CRM note, etc.).
Base path: /v2/api/pub/ecard-actions
Auth: Authorization: Bearer <YOUR_API_KEY> (see getting-started).
1. List your eCards — GET /get-ecards #
Look up the eCards available in a widget (to get the ecardId/widgetId you'll send with).
Query parameters
| Param | Required | Notes |
|---|---|---|
widgetId |
yes | The widget's vanity ID |
curl "https://app.ecardwidget.com/v2/api/pub/ecard-actions/get-ecards?widgetId=w6v62rn95yq" \
-H "Authorization: Bearer $ECW_API_KEY"
Response (standard envelope; data is an array)
{
"success": true,
"data": [
{
"widgetid": "w6v62rn95yq",
"ecardid": "e4xgrzltk",
"ecard_name": "Happy Birthday",
"ecard_details": "<div>…</div>",
"cover_image": "https://…/cover.png",
"cover_thumb_image": "https://…/thumb.png",
"envelope_bg_image_url": ""
}
],
"messages": []
}
2. Send an eCard — POST /send-ecard #
Sends (or schedules) an eCard. Delegates to the same internal pipeline the widget uses, so behavior matches a normal send.
Request body (JSON) #
| Field | Required | Notes |
|---|---|---|
ecardId |
yes | eCard vanity ID (from get-ecards) |
senderEmail |
yes | Who the eCard is from (valid email) |
senderName |
yes | Sender display name |
recipientName |
yes | Recipient display name |
recipientEmail |
conditional | Required for email sends. Optional/ignored for share links (type=ecard_copy_link) — those don't email anyone |
personalMessage |
no | Personal note; basic HTML allowed |
type |
no | email (default) or ecard_copy_link (generate a share link instead of emailing) |
is_sharing |
no | true is equivalent to type=ecard_copy_link |
sendAt |
no | ISO 8601 datetime. Leave blank to send now; a future value schedules the send |
locale |
no | Language code (default en). Supported: en, spanish, dutch, hebrew, korean, de, french, arabic, polish, brazilian-portuguese, nam (Vietnamese) |
optin |
no | Sender opt-in flag |
opennotification |
no | Notify the sender when the eCard is opened |
mergeTags |
no | Object of key/value pairs to fill custom fields / merge tags |
overrideProps |
no | Object overriding branding/eCard props (logo, colors, social links, etc.) |
Response (FLAT — no envelope) #
Unlike most endpoints, send-ecard returns the result fields at the top level:
Email send
{
"success": true,
"type": "email",
"scheduled": false,
"sendAt": "",
"ecardVanityId": "e4xgrzltk",
"widgetVanityId": "w6v62rn95yq",
"senderEmail": "sender@example.com",
"senderName": "Acme",
"recipientName": "Jordan",
"recipientEmail": "jordan@example.com",
"locale": "en",
"emailsSent": 1
}
Share-link send (type: "ecard_copy_link")
{
"success": true,
"type": "ecard_copy_link",
"scheduled": false,
"sendAt": "",
"ecardVanityId": "e4xgrzltk",
"widgetVanityId": "w6v62rn95yq",
"senderEmail": "sender@example.com",
"senderName": "Acme",
"recipientName": "Jordan",
"recipientEmail": "",
"locale": "en",
"statVanityId": "s2k7zqpvnll272r",
"shareUrl": "https://app.ecardwidget.com/e/s/s2k7zqpvnll272r"
}
Examples #
Email now
curl -X POST https://app.ecardwidget.com/v2/api/pub/ecard-actions/send-ecard \
-H "Authorization: Bearer $ECW_API_KEY" -H "Content-Type: application/json" \
-d '{
"ecardId": "e4xgrzltk",
"senderEmail": "sender@example.com", "senderName": "Acme",
"recipientName": "Jordan", "recipientEmail": "jordan@example.com",
"personalMessage": "Thank you for your support!"
}'
Schedule for later — add a future sendAt:
{ "...": "...", "sendAt": "2026-12-24T09:00:00Z" }
From a HubSpot workflow — add a Send a webhook action (Operations Hub Professional) that
POSTs to this endpoint with the Authorization header above, and map the body fields to the
contact's properties. The personal message is printed inside the card, so personalize it per contact:
{
"ecardId": "e4xgrzltk",
"senderEmail": "{{ contact.hubspot_owner_email }}", "senderName": "{{ contact.hubspot_owner_name }}",
"recipientName": "{{ contact.firstname }}", "recipientEmail": "{{ contact.email }}",
"personalMessage": "Hi {{ contact.firstname }}, thank you for a great year. Happy holidays from all of us!",
"mergeTags": { "company": "{{ contact.company }}" },
"sendAt": "2026-12-15T14:00:00Z",
"opennotification": true
}
Use the contact-property tokens HubSpot offers in the webhook body editor; mergeTags fills any custom
fields on the eCard. Opens are recorded per recipient under Logs in eCardWidget (and sent to the
sender when opennotification is on). On a HubSpot tier without the webhook action, use the
Zapier recipe instead.
Generate a share link (no email) — set type to ecard_copy_link and omit recipientEmail:
curl -X POST https://app.ecardwidget.com/v2/api/pub/ecard-actions/send-ecard \
-H "Authorization: Bearer $ECW_API_KEY" -H "Content-Type: application/json" \
-d '{
"ecardId": "e4xgrzltk", "type": "ecard_copy_link",
"senderEmail": "sender@example.com", "senderName": "Acme",
"recipientName": "Jordan", "personalMessage": "Thanks!"
}'
Use the returned shareUrl directly. If you prefer to build it yourself, it's always:
https://app.ecardwidget.com/e/s/<statVanityId>
The /e/s/ path is fixed/canonical — appending the share ID to it is fully supported — but consuming
shareUrl from the response insulates you from any future path changes.