Directory Sync #

Your ECW team-member directory is the list of people your organization celebrates and manages — it powers automations (birthdays, work anniversaries, recognition) and directory-restricted sending. Team members don't log into ECW — keeping their records in sync is a data problem, not a login problem, and it's fully independent of SSO.

Choose your sync method #

Method Best for Requires Guide
SCIM from your IdP (Okta, Entra ID, OneLogin, …) Orgs whose IdP already holds the employee list Enterprise plan + verified domain (SSO not required — pick SCIM-only in the wizard) SCIM provisioning
HR platform → IdP → SCIM (ADP, Workday, UKG, …) Orgs whose source of truth is an HR system Same as SCIM + HR-driven provisioning into your IdP (standard IT plumbing) Below
Directory Sync API Custom integrations, HR/CRM systems without an IdP in the middle, scheduled exports An API key Below
Zapier No-code sync from 6,000+ apps (BambooHR, Google Sheets, …) Zapier account Zapier guide
Spreadsheet import Initial backfill, one-time loads Nothing extra In-app: Directory → Import
Manual Small teams Nothing extra In-app: Directory

These compose: a common setup is a spreadsheet backfill first, then SCIM or API/Zapier for ongoing deltas.

ECW is receive-only. Whatever the method, your system is the source of truth — ECW never writes back to your IdP or HR platform. To be notified when the ECW directory changes, subscribe to member-change webhooks.

Syncing from HR platforms (ADP, Workday, UKG, …) #

The most common ask: "our people live in ADP/Workday/UKG — can we sync them into ECW?" Yes — but not by pointing ECW at the HR platform directly. HR systems are the source of employee identity, not a sync authority: none of them can push SCIM to a third-party app (that's an IdP capability, not an HR-platform capability — true for every SaaS vendor, not just ECW).

The supported pattern — your HR platform feeds your identity provider, and the IdP provisions ECW:

ADP / Workday / UKG  →  Entra ID or Okta  →  SCIM  →  ECW team directory
      (HR-driven provisioning)              (SCIM-only mode — no SSO needed)

The left leg is standard IT plumbing: Workday → Entra/Okta connectors are first-party, and ADP/UKG are covered by Entra's API-driven inbound provisioning and partner connectors. Once in place, new hires flow HR → IdP → ECW automatically, and offboarded employees are deactivated the same way.

No IdP in the middle? Use a scheduled export from your HR system into the Directory Sync API below (e.g. a Workday RaaS report or ADP export on a cron), Zapier, or a periodic spreadsheet import.

Platform notes:

  • Rippling — unlike most HR platforms, Rippling is also an identity provider; for SSO see the IdP compatibility table. For directory sync, treat it like an IdP if your plan supports custom app provisioning, otherwise use the API/Zapier.
  • ADP — ADP's own integrations (SSO or data) are available only to apps listed on ADP Marketplace (a vendor partnership, not a setting your admin can configure). ECW is not currently an ADP Marketplace app — contact us if this matters for your organization. Meanwhile, the ADP → IdP → SCIM chain above works today.
  • Workday / UKG — no customer-configurable identity-provider or outbound-SCIM capability. Use the IdP your tenant feeds, or a scheduled report export into the API.

Directory Sync API #

Sync team-member records from any system — HR/HRIS (Workday, BambooHR), CRM (Salesforce), or your own tools. These are the same endpoints the official Zapier integration uses, so you can build directly or use Zapier.

Base path: /v2/api/pub/team-member-actions Auth: Authorization: Bearer <YOUR_API_KEY> (see getting-started). Response envelope: { "success": …, "data": …, "messages": [] } (list endpoints add meta).


Create or update a member — POST /upsert #

Adds a member, or updates them if they already exist.

  • PATCH semantics: only the fields you send are changed; omitted fields are left untouched, so a partial sync never blanks existing data. To clear a field, send it as an empty string.
  • Matching: by default members match by email. To survive email changes, send a stable employee_id and set match_field to employee_id — then an email change updates the same person instead of creating a duplicate.

Body fields #

Field Notes
first_name required
email required, must be valid
last_name, job_position, profile_image_url optional strings (profile_image_url must be publicly fetchable)
employee_id stable external ID (recommended for HR syncs)
manager_email resolved to an existing member → manager link; if not present yet, resolves on a later sync
department or departments[] one or more names; auto-created if missing. Send one or the other — if both are present, departments[] is used and department is ignored.
date_of_birth, hire_date, custom_date_1..N dates; accepts YYYY-MM-DD, M/D/YYYY, etc. (birthday year is privacy-masked automatically; Feb 29 → Feb 28)
active false deactivates, true reactivates; omit to leave unchanged (an update never silently reactivates)
match_field email (default) or employee_id
mode add_update (default) or add_new_only (skip if the member already exists)
skip_if_missing_required true → skip rows missing first_name/email instead of erroring (invalid emails still error)
dry_run true → validate and report the would-be action without saving

Example #

curl -X POST https://app.ecardwidget.com/v2/api/pub/team-member-actions/upsert \
  -H "Authorization: Bearer $ECW_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "first_name": "Grace", "last_name": "Hopper", "email": "[email protected]",
    "employee_id": "EMP-100", "match_field": "employee_id",
    "job_position": "Engineer", "manager_email": "[email protected]",
    "departments": ["Engineering", "Leadership"], "hire_date": "2021-03-01"
  }'

Response data #

{ "action": "created", "id": 123, "changed_fields": ["job_position"], "warnings": [] }

action is one of created, updated, unchanged, or skipped. Sending active:false still reports created/updated (the member is just marked inactive) — the deactivated / reactivated / deleted actions come from the dedicated deactivate/reactivate/delete endpoints.


Find a member — GET /find #

GET /[email protected]
GET /find?employee_id=EMP-100

Returns the member in data and meta.found. data is empty when not found.


List members — GET /list #

Paginated, for reconciliation / verifying a sync.

Query param Notes
status active (default), deactivated, or all
perPage page size, ≤ 500
after_id cursor — pass the previous page's meta.next_after_id
updated_since ISO datetime — only members changed since then (delta pulls)

meta includes next_after_id and has_more.

Removing people (the streaming-safe replacement for a spreadsheet "Sync" that deletes everyone not in the file): periodically GET /list, diff against your source system, and deactivate anyone no longer present.


Deactivate / Reactivate — POST /deactivate, POST /reactivate #

Body: { "email": "…" } or { "employee_id": "…" }.

Deactivation is reversible: the member stops receiving automated cards and no longer counts toward your seat limit, but their record/history is kept. Reactivate to restore (subject to seat availability).


Delete (permanent) — POST /delete #

Body: { "email": "…" } or { "employee_id": "…" }.

Irreversible — for GDPR erasure only. For normal offboarding use deactivate.


Field discovery — GET /fields, GET /departments #

  • GET /fields — lists mappable fields (standard fields + your active custom date fields) with label, type, required, and accepted format (e.g. date formats). Use this to drive field mapping in your integration.
  • GET /departments — lists your departments as { "id": …, "name": "…" }.
curl https://app.ecardwidget.com/v2/api/pub/team-member-actions/fields \
  -H "Authorization: Bearer $ECW_API_KEY"

Initial backfill #

For the first load of an existing employee base, use the in-app spreadsheet importer (or page through many upsert calls). Use the API/Zapier for ongoing deltas thereafter. The bulk importer does not emit member-change webhooks — those fire only for per-record changes.

Notifications when the directory changes #

To push changes back to another system, subscribe to member-change webhooks.


Documentation