Accounts
List, update, sync and delete connected accounts, connect IMAP mailboxes and token imports, and mint account tokens.
Guides: Connect flows, IMAP and SMTP, Authentication.
| Method | Path | Operation | Scope |
|---|---|---|---|
GET | /v1/accounts | List accounts | read |
POST | /v1/accounts | Connect an account from an existing refresh token | write |
GET | /v1/accounts/{accountId} | Get an account | read |
PATCH | /v1/accounts/{accountId} | Update an account | write |
DELETE | /v1/accounts/{accountId} | Delete an account | write |
POST | /v1/accounts/{accountId}/sync | Sync an account now | write |
POST | /v1/accounts/{accountId}/tokens | Mint an account-scoped token | write |
POST | /v1/imap-accounts | Connect an IMAP/SMTP account with a password | write |
PATCH | /v1/accounts/{accountId}/imap-settings | Change an IMAP account's servers or password | write |
GET | /v1/autoconfig | Find IMAP, SMTP and DAV settings for an address | read |
Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Newest first. q matches part of the email address or the external reference, case-insensitively; externalRef matches it exactly. An API key bound to accounts lists only those.
Required scope: read.
limit?integer1 <= value <= 20050cursor?string1 <= length <= 512externalRef?stringq?string1 <= length <= 200status?string"active""paused""reauth_required""disabled"orgConnectionId?stringuuiddelegateAccountId?stringuuidOK
application/json- response
items*array<>nextCursor*|nullcurl -X GET 'https://api.workwae.com/v1/accounts'{ "items": [ { "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "externalRef": "user_42", "provider": "gmail", "email": "string", "displayName": "string", "oauthAppId": "c6e11c75-050f-4212-9cff-bddb4fb07e36", "cloud": "global", "status": "active", "statusReason": "string", "settings": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "settingsOverride": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "runtime": { "state": "pending", "detail": "string", "ownerInstanceId": "b31a377d-3f38-46d6-b670-15babc0f5625", "updatedAt": "2026-05-04T09:30:00.000Z" }, "imap": { "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "auth": "password", "appendSent": true, "dav": { "calendarUrl": "string", "contactsUrl": "string", "user": "string", "auth": "imap_password" } }, "auth": { "method": "oauth", "orgConnectionId": "17f753c8-b2ec-494b-9468-6e20a9a2f99c", "delegateAccountId": "016ade53-f197-47ea-bd0e-48fda92e431f" }, "initializedAt": "2026-05-04T09:30:00.000Z", "calendarInitializedAt": "2026-05-04T09:30:00.000Z", "contactsInitializedAt": "2026-05-04T09:30:00.000Z", "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z" } ], "nextCursor": "eyJ0eG5pZCI6IjQyIiwiaWQiOjEwMDF9"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
The address is the provider's (Google's userinfo, Graph's /me).
Required scope: write.
application/json- body
provider*OAuthProvider"google""microsoft"microsoftCloud?MicrosoftCloud"global""global""gcc-high""dod""china"refreshToken*string1 <= lengthoauthAppId?stringuuidexternalRef?stringlength <= 255settings?sharedMailboxesEnabled?booleanOK
application/json- response
id*stringuuidexternalRef*string|nullprovider*AccountProvider"gmail""graph""imap"email*stringdisplayName*string|nulloauthAppId*|nullcloud*|nullstatus*AccountStatus"active""paused""reauth_required""disabled"statusReason*string|nullsettings*settingsOverride*runtime*|nullimap*|nullauth*initializedAt*|nullcalendarInitializedAt*|nullcontactsInitializedAt*|nullcreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X POST 'https://api.workwae.com/v1/accounts' \ -H 'Content-Type: application/json' \ -d '{ "provider": "google", "refreshToken": "string"}'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "externalRef": "user_42", "provider": "gmail", "email": "string", "displayName": "string", "oauthAppId": "c6e11c75-050f-4212-9cff-bddb4fb07e36", "cloud": "global", "status": "active", "statusReason": "string", "settings": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "settingsOverride": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "runtime": { "state": "pending", "detail": "string", "ownerInstanceId": "b31a377d-3f38-46d6-b670-15babc0f5625", "updatedAt": "2026-05-04T09:30:00.000Z" }, "imap": { "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "auth": "password", "appendSent": true, "dav": { "calendarUrl": "string", "contactsUrl": "string", "user": "string", "auth": "imap_password" } }, "auth": { "method": "oauth", "orgConnectionId": "17f753c8-b2ec-494b-9468-6e20a9a2f99c", "delegateAccountId": "016ade53-f197-47ea-bd0e-48fda92e431f" }, "initializedAt": "2026-05-04T09:30:00.000Z", "calendarInitializedAt": "2026-05-04T09:30:00.000Z", "contactsInitializedAt": "2026-05-04T09:30:00.000Z", "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Required scope: read.
accountId*stringuuidOK
application/json- response
id*stringuuidexternalRef*string|nullprovider*AccountProvider"gmail""graph""imap"email*stringdisplayName*string|nulloauthAppId*|nullcloud*|nullstatus*AccountStatus"active""paused""reauth_required""disabled"statusReason*string|nullsettings*settingsOverride*runtime*|nullimap*|nullauth*initializedAt*|nullcalendarInitializedAt*|nullcontactsInitializedAt*|nullcreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X GET 'https://api.workwae.com/v1/accounts/6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "externalRef": "user_42", "provider": "gmail", "email": "string", "displayName": "string", "oauthAppId": "c6e11c75-050f-4212-9cff-bddb4fb07e36", "cloud": "global", "status": "active", "statusReason": "string", "settings": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "settingsOverride": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "runtime": { "state": "pending", "detail": "string", "ownerInstanceId": "b31a377d-3f38-46d6-b670-15babc0f5625", "updatedAt": "2026-05-04T09:30:00.000Z" }, "imap": { "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "auth": "password", "appendSent": true, "dav": { "calendarUrl": "string", "contactsUrl": "string", "user": "string", "auth": "imap_password" } }, "auth": { "method": "oauth", "orgConnectionId": "17f753c8-b2ec-494b-9468-6e20a9a2f99c", "delegateAccountId": "016ade53-f197-47ea-bd0e-48fda92e431f" }, "initializedAt": "2026-05-04T09:30:00.000Z", "calendarInitializedAt": "2026-05-04T09:30:00.000Z", "contactsInitializedAt": "2026-05-04T09:30:00.000Z", "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Changing settings.bodyStorage, calendarEnabled or syncWindowDays restarts the account's syncs: full stores every indexed message and backfills, none deletes stored content. status only moves between active and paused; only a new grant clears reauth_required and disabled.
Required scope: write.
accountId*stringuuidapplication/json- body
externalRef?|nullstatus?SettableAccountStatus"active""paused"settings?OK
application/json- response
id*stringuuidexternalRef*string|nullprovider*AccountProvider"gmail""graph""imap"email*stringdisplayName*string|nulloauthAppId*|nullcloud*|nullstatus*AccountStatus"active""paused""reauth_required""disabled"statusReason*string|nullsettings*settingsOverride*runtime*|nullimap*|nullauth*initializedAt*|nullcalendarInitializedAt*|nullcontactsInitializedAt*|nullcreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X PATCH 'https://api.workwae.com/v1/accounts/6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "externalRef": "user_42", "provider": "gmail", "email": "string", "displayName": "string", "oauthAppId": "c6e11c75-050f-4212-9cff-bddb4fb07e36", "cloud": "global", "status": "active", "statusReason": "string", "settings": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "settingsOverride": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "runtime": { "state": "pending", "detail": "string", "ownerInstanceId": "b31a377d-3f38-46d6-b670-15babc0f5625", "updatedAt": "2026-05-04T09:30:00.000Z" }, "imap": { "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "auth": "password", "appendSent": true, "dav": { "calendarUrl": "string", "contactsUrl": "string", "user": "string", "auth": "imap_password" } }, "auth": { "method": "oauth", "orgConnectionId": "17f753c8-b2ec-494b-9468-6e20a9a2f99c", "delegateAccountId": "016ade53-f197-47ea-bd0e-48fda92e431f" }, "initializedAt": "2026-05-04T09:30:00.000Z", "calendarInitializedAt": "2026-05-04T09:30:00.000Z", "contactsInitializedAt": "2026-05-04T09:30:00.000Z", "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Stops syncing and removes the credential at once. The account's data is purged for good after the retention period (default 30 days), or shortly after the call with ?purge=true; account.purged announces it. Its events are left to age out of the event log (within 31 days). purge=true also purges an account that is already deleted.
Required scope: write.
accountId*stringuuidpurge?|falseOK
application/json- response
curl -X DELETE 'https://api.workwae.com/v1/accounts/6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b'nullRuns against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Wakes the account's sync the way a provider push does: one nudge per kind to the instance that owns it. The owner keeps at most one pending pass per kind, so a repeat while a pass is running becomes a single extra pass. At most 30 of these requests per account per minute (429 rate_limited). kinds defaults to every kind the account has enabled (mail always; calendar and contacts when its settings turn them on). With no live owner the answer is still 202: the next owner starts with a full pass, and the backstop poll covers a wake nobody was listening for.
Required scope: write.
accountId*stringuuidapplication/json- body
kinds?array<>1 <= itemsOK
application/json- response
kinds*array<>curl -X POST 'https://api.workwae.com/v1/accounts/6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b/sync' \ -H 'Content-Type: application/json' \ -d '{}'{ "kinds": [ "mail" ]}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
The token is returned once; it is not retrievable later.
Required scope: write.
accountId*stringuuidapplication/json- body
ttlSeconds?integer60 <= value <= 86400900OK
application/json- response
token*stringexpiresAt*stringdate-timecurl -X POST 'https://api.workwae.com/v1/accounts/6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b/tokens' \ -H 'Content-Type: application/json' \ -d '{}'{ "token": "string", "expiresAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
The login is checked before anything is stored, for DAV too. Giving dav switches settings.calendarEnabled and contactsEnabled on for the halves found unless settings names them.
Required scope: write.
application/json- body
email*stringemaillength <= 320displayName?stringlength <= 255password*string1 <= length <= 1024smtpPassword?string1 <= length <= 1024imap?smtp?|nullappendSent?booleandav?externalRef?stringlength <= 255settings?OK
application/json- response
id*stringuuidexternalRef*string|nullprovider*AccountProvider"gmail""graph""imap"email*stringdisplayName*string|nulloauthAppId*|nullcloud*|nullstatus*AccountStatus"active""paused""reauth_required""disabled"statusReason*string|nullsettings*settingsOverride*runtime*|nullimap*|nullauth*initializedAt*|nullcalendarInitializedAt*|nullcontactsInitializedAt*|nullcreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X POST 'https://api.workwae.com/v1/imap-accounts' \ -H 'Content-Type: application/json' \ -d '{ "email": "ada@example.com", "password": "string"}'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "externalRef": "user_42", "provider": "gmail", "email": "string", "displayName": "string", "oauthAppId": "c6e11c75-050f-4212-9cff-bddb4fb07e36", "cloud": "global", "status": "active", "statusReason": "string", "settings": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "settingsOverride": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "runtime": { "state": "pending", "detail": "string", "ownerInstanceId": "b31a377d-3f38-46d6-b670-15babc0f5625", "updatedAt": "2026-05-04T09:30:00.000Z" }, "imap": { "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "auth": "password", "appendSent": true, "dav": { "calendarUrl": "string", "contactsUrl": "string", "user": "string", "auth": "imap_password" } }, "auth": { "method": "oauth", "orgConnectionId": "17f753c8-b2ec-494b-9468-6e20a9a2f99c", "delegateAccountId": "016ade53-f197-47ea-bd0e-48fda92e431f" }, "initializedAt": "2026-05-04T09:30:00.000Z", "calendarInitializedAt": "2026-05-04T09:30:00.000Z", "contactsInitializedAt": "2026-05-04T09:30:00.000Z", "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Present fields replace the stored ones and the result is checked like a new account. An account in reauth_required becomes active again. A stored password is never sent to a new server or tried for another login: changing the IMAP server (host, port, security or user) needs password in the same request, changing the SMTP server (host, port, security or user) needs smtpPassword (or password when SMTP uses the IMAP password), switching SMTP from its own password to the IMAP one (smtpPassword: null) needs password, and adding DAV settings or changing their URLs, user or password source needs the password DAV logs in with (dav.password, or password when DAV uses the IMAP password). Sending dav: null removes the calendar and contacts; a CalDAV or CardDAV half the account did not have before switches settings.calendarEnabled or contactsEnabled on, unless the account's settings already name that key (an earlier opt-out stays); dav fields left out keep their stored values, or are discovered for an account without DAV settings. An account that signs in with OAuth always uses its provider's servers.
Required scope: write.
accountId*stringuuidapplication/json- body
password?string1 <= length <= 1024smtpPassword?|nullimap?smtp?|nullappendSent?booleandav?|nullOK
application/json- response
id*stringuuidexternalRef*string|nullprovider*AccountProvider"gmail""graph""imap"email*stringdisplayName*string|nulloauthAppId*|nullcloud*|nullstatus*AccountStatus"active""paused""reauth_required""disabled"statusReason*string|nullsettings*settingsOverride*runtime*|nullimap*|nullauth*initializedAt*|nullcalendarInitializedAt*|nullcontactsInitializedAt*|nullcreatedAt*stringdate-timeupdatedAt*stringdate-timecurl -X PATCH 'https://api.workwae.com/v1/accounts/6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b/imap-settings' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "externalRef": "user_42", "provider": "gmail", "email": "string", "displayName": "string", "oauthAppId": "c6e11c75-050f-4212-9cff-bddb4fb07e36", "cloud": "global", "status": "active", "statusReason": "string", "settings": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "settingsOverride": { "bodyStorage": "none", "syncWindowDays": 1, "calendarEnabled": true, "contactsEnabled": true, "undoSendSeconds": 0, "trackOpens": true, "trackClicks": true, "trackingHoneypot": true }, "runtime": { "state": "pending", "detail": "string", "ownerInstanceId": "b31a377d-3f38-46d6-b670-15babc0f5625", "updatedAt": "2026-05-04T09:30:00.000Z" }, "imap": { "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "auth": "password", "appendSent": true, "dav": { "calendarUrl": "string", "contactsUrl": "string", "user": "string", "auth": "imap_password" } }, "auth": { "method": "oauth", "orgConnectionId": "17f753c8-b2ec-494b-9468-6e20a9a2f99c", "delegateAccountId": "016ade53-f197-47ea-bd0e-48fda92e431f" }, "initializedAt": "2026-05-04T09:30:00.000Z", "calendarInitializedAt": "2026-05-04T09:30:00.000Z", "contactsInitializedAt": "2026-05-04T09:30:00.000Z", "createdAt": "2026-05-04T09:30:00.000Z", "updatedAt": "2026-05-04T09:30:00.000Z"}Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
dav carries CalDAV and CardDAV context URLs when a source names them; they need the login to resolve to the account's home sets, which creating the account does.
Required scope: read.
email*stringemaillength <= 320OK
application/json- response
source*AutoconfigSource"provider""autoconfig""ispdb""srv""mx"imap*smtp*|nulloauth*|nulldav*|nullcurl -X GET 'https://api.workwae.com/v1/autoconfig?email=ada%40example.com'{ "source": "provider", "imap": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "smtp": { "host": "string", "port": 0, "security": "tls", "user": "string" }, "oauth": "google", "dav": { "source": "provider", "calendarUrl": "string", "contactsUrl": "string" }}