Skip to main content

API 1.0.1

Released September 13, 2026

This release makes it practical to keep Zapa portals in sync with the systems your firm already runs: portals can carry your own record IDs, every webhook tells you which external record it concerns, and tasks can be created and fulfilled end-to-end over the API.

Action may be required

Two changes affect existing integrations. Review Breaking and behavior changes before upgrading.

Highlights​

External system IDs on portals​

A portal can now store one identifier per external system (for example your CRM customer ID or tax-software client ID) and be looked up by it.

  • GET /api/v1/portals?externalSystem={system}&externalId={id} returns the matching portal (as a one-element array) or []. Both parameters are required together.
  • PATCH /api/v1/portals/{portalId} accepts externalSystemIds as a merge-patch: keys you send are set, a null value removes that key, keys you omit are untouched. The response echoes the full merged map.
  • Each (system, id) pair is unique within an organization. Assigning a pair that already belongs to another portal returns 409 Conflict.
  • Validation: system names are 1–100 printable characters, values 1–256 characters, at most 50 systems per portal.
curl -X PATCH https://api.zapaportal.com/api/v1/portals/PORTAL_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "externalSystemIds": { "QuickBooks": "cust_12345", "OldCRM": null } }'

Webhook payloads​

  • Every portal-scoped event (portal.created, portal.workflow_changed, file.uploaded, file.signed, task.created, task.completed, guest.invited) now includes external_system_ids — the portal's current map, or {} when none are set — so receivers can route events without an extra API call.
  • file.uploaded includes task_id when the upload was attached to a task (empty otherwise).
  • task.completed includes action_type, status, attached_files, and, when a File Request was fulfilled by an upload, the completing file_id.
  • task.completed now fires when a task is marked done in the Zapa web app, not only through the API, and when a client fulfils a File Request by uploading a document (see below).

Tasks over REST​

  • POST /api/v1/portals/{portalId}/tasks now honors:
    • assigned_guest_ids / assigned_member_ids — validated against the portal's guests and the organization's members; display names are resolved server-side.
    • send_reminder — when true, Zapa emails assignees about the task. Requires due_date (a request with send_reminder: true and no due_date returns 400).
  • Task status values are case-insensitive; open, done, completed, and closed are accepted.
  • PATCH /api/v1/tasks/{taskId} no longer clears assignees or comments when other fields are updated.

File uploads attached to tasks​

POST /api/v1/portals/{portalId}/files and POST /api/v1/portals/{portalId}/files/complete accept an optional task_id. The uploaded file is attached to that task (which must belong to the same portal). When a guest uploads to an open File Request, the task is completed automatically and a single task.completed event fires with the file_id. Uploads by team members attach the file but leave the task open.

Refresh token rotation​

Refresh tokens are now single-use and their lifetime slides:

  • Every grant_type=refresh_token response includes a new refresh_token. Store it and discard the old one.
  • The previous token is accepted again for about 60 seconds (in case the rotation response was lost) and then returns the same successor. Presenting it after that window is treated as token theft: the entire token chain is revoked and the user must re-authorize.
  • Each rotation restarts the 30-day lifetime, so an integration that refreshes at least once every 30 days stays connected indefinitely.

Breaking and behavior changes​

  1. client_secret is required on refresh. Clients created under Settings → API Settings must send client_secret with grant_type=refresh_token. Refreshes without it now return 401 invalid_client. The quickstart has always shown the secret on refresh; integrations that omitted it must add it.
  2. Refresh tokens rotate. Integrations that reuse the same refresh token indefinitely will be disconnected after the grace window described above. Persist the refresh_token from every token response.
  3. task.completed fires more often. Completions made in the web app and File Request auto-completions now emit events. Receivers should already be idempotent on X-Webhook-Delivery-Id; make sure downstream automations tolerate the additional volume.
  4. assigned_guest_names / assigned_member_names on task create are ignored — names are looked up from the IDs.

Zapier integration 1.0.1​

  • New search: Find Portal by External ID.
  • Update Portal gains an External System IDs field (leave a value blank to remove that system).
  • Upload File gains an optional Task field.
  • Create Task gains Task Type and Send Reminders fields.
  • Trigger output includes the new payload fields above (external_system_ids, task_id, action_type, attached_files, file_id, status).
  • Connections stay alive across refresh-token rotation.

Existing Zaps are migrated automatically; no action is required from Zap owners.

Documentation​

  • The webhook verification sample in the Developer Quickstart now verifies the HMAC over the raw request body with a constant-time comparison, checks the timestamp for replay protection, and reads event fields from the top level of the payload (there is no nested data object).
  • New Working with external system IDs section in the quickstart.

Resources​