Webhooks #
eCardWidget has two webhook families:
ecard_shared— fires when an eCard is sent/shared (email, link, social). Configured once in the dashboard (Settings → Developers → Webhook URL). See eCard-shared webhook.- Member-change webhooks — fire when your directory changes (member created / updated / deactivated / deleted). Subscribed via the API; signed and retried. See Member-change webhooks.
eCard-shared webhook #
Set a Webhook URL under Settings → Developers and click Save (blank disables it). eCardWidget
sends a POST with header User-Agent: eCardWidget Hook whenever an eCard is shared. The body is a
JSON array of one or more events:
[
{
"event_type": "ecard_shared",
"type": "email",
"sender_request_id": "rmmbps64tn8tyl5ghdft4",
"ecardid": 14744,
"widgetid": 4069,
"vanity_id": "smcxzw64jky8tcg",
"sender_name": "Sender",
"sender_email": "[email protected]",
"recipient_name": "Recipient",
"recipient_email": "[email protected]",
"personal_message": "<p>Thinking of you!</p>",
"locale": "en",
"scheduled_to_be_sent_at": "2026-03-12T15:49:25Z",
"sent": false,
"opened": false,
"merge_tags": "",
"override_props": ""
}
]
typeis the share method:email,facebook,twitter,linkedin,sms,whatsapp, etc.sentisfalsefor pending email sends (the hook fires before dispatch) andtruefor immediate share/social sends. Usescheduled_to_be_sent_atfor the expected send time.- This is the same event behind the Zapier "eCard Sent via Email" trigger (Zapier).
Member-change webhooks #
Get notified when your directory changes — e.g. to push new hires, updates, or terminations back into another system. These are the same events that power the eCardWidget Zapier triggers.
Base path: /v2/api/pub/team-member-actions
Auth: Authorization: Bearer <YOUR_API_KEY> (see getting-started).
Subscribe — POST /subscribe #
curl -X POST https://app.ecardwidget.com/v2/api/pub/team-member-actions/subscribe \
-H "Authorization: Bearer $ECW_API_KEY" -H "Content-Type: application/json" \
-d '{ "event_type": "team_member_updated", "hookUrl": "https://your-app.example.com/hooks/ecw" }'
Returns the subscription id:
{ "success": true, "data": { "id": "<subscription-id>" }, "messages": [] }
Unsubscribe — POST /unsubscribe #
curl -X POST https://app.ecardwidget.com/v2/api/pub/team-member-actions/unsubscribe \
-H "Authorization: Bearer $ECW_API_KEY" -H "Content-Type: application/json" \
-d '{ "id": "<subscription-id>" }'
Event types #
| Event | Fires when |
|---|---|
team_member_created |
a member is added |
team_member_updated |
a member materially changes (idempotent re-syncs do not fire) |
team_member_deactivated |
a member is deactivated |
team_member_deleted |
a member is permanently deleted |
Delivery payload #
Each delivery is a JSON POST to your hookUrl:
{
"event_id": "00000000-0000-0000-0000-000000000000",
"event_type": "team_member_updated",
"timestamp": "2026-01-01T09:00:00Z",
"source": "api",
"changed_fields": ["job_position"],
"member": {
"id": 123,
"email": "[email protected]",
"employee_id": "EMP-100",
"first_name": "Grace",
"last_name": "Hopper",
"job_position": "Engineer",
"departments": ["Engineering"],
"date_of_birth": "1800-04-12",
"hire_date": "2021-03-01",
"profile_image_url": "",
"disabled": 0,
"updatedat": "2026-01-01T09:00:00Z"
}
}
source— where the change came from:api,zapier,ui, orimport.changed_fields— present onteam_member_updated; lists what changed.- Birthday years are privacy-masked (stored as year
1800).
Signing & reliability #
- Deliveries are signed with your account's webhook signing secret:
X-ECW-Signature: sha256=<hmac>(HMAC-SHA256 of the raw request body). Verify it before trusting a payload. - Failed deliveries are retried automatically.
- Use
event_idto de-duplicate (a retry reuses the same id). - The bulk spreadsheet importer does not emit these events — they're for ongoing per-record changes.
Loop awareness #
If you both write to ECW (via upsert) and listen for changes, use the source
field to avoid feedback loops (e.g. ignore events your own integration caused).