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.


Documentation