Security
Every operation in this group: what it accepts, what it returns and the errors it can answer with.
Operations
Verification codes for OAuth access tokens. A few operations change who can reach the workspace or where its mail goes, and an app acting for a person has to confirm who they are before it does them, exactly as the app does: ask for a code, send the code the person typed, and repeat the call. API keys are never asked for a code.
GET/security/step-up
Whether this access token is verified
Needs no scope, and is for OAuth access tokens only: an API key is refused with 400 step_up_not_applicable, because a key is never asked for a code.
Some operations change who can reach the workspace or where its mail goes, and the app asks the person to confirm who they are before it does them. An app acting for that person is held to the same rule: called with an OAuth access token, each of those operations answers 403 step_up_required until the token is verified, and one verification lasts 60 minutes. method says which kind of code to ask the person for.
Returns
Whether the token is verified, until when, and which kind of code it takes.
Errors
- 400
step_up_not_applicable: the call was made with an API key, which is never asked for a code.
The errors every operation can return401403404422429500Error catalog
Also available in
POST/security/step-up
Ask for a verification code
Needs no scope, and is for OAuth access tokens only. Starts a verification for the person the token acts for.
With method email, a six-digit code goes to the address they sign in with and works for 10 minutes. The email names the app and, when a call from it was refused for want of a code in the last 15 minutes, the last thing it asked to do. It also tells them that the code is not tied to that one call: for 60 minutes it lets the app make every change that needs a code, within the access they gave it. With totp, nothing is sent: they read the code off their authenticator app, or use one of their backup codes. Either way, send what they type to POST /security/step-up/verify.
A code already waiting is reused rather than sent again, which reused reports; pass resend: true to send a fresh one. A code that took 5 wrong tries is never reused, so a call without resend then starts a fresh one.
Each app has its own allowance for each person: 5 codes an hour and 20 in 24 hours. It is separate from every other app's and from the 10 an hour the person has on the website. After 10 wrong codes for one app in 24 hours, verification for that app is paused, and after 20 wrong codes across all of the person's apps it is paused for every app. Either way this answers 429 step_up_locked until the time its message gives.
Request body
resendbooleanSend a new code even though one is still waiting, and stop the waiting one from working. Left out, a waiting code that still has tries left is reused and nothing is sent.
methodstringemailsends a code to the address the person signs in with even when they have an authenticator app, for when they would rather use their inbox.totpasks for the authenticator code and only applies when two-factor sign-in is on. Left out, the authenticator is asked for when two-factor sign-in is on and an email code otherwise. A waiting code of the other kind is replaced.One of"totp""email"
Returns
How the person gets their code, and where it went.
Errors
- 400
step_up_not_applicable: the call was made with an API key, which is never asked for a code.- 429
step_up_throttled: this app has asked for too many codes for this person. Each app has its own allowance of 5 codes an hour and 20 in 24 hours, and the message says when the next one can be asked for. It is separate from every other app's and from the 10 an hour the person has on the website, so one app never uses those up.step_up_locked: 10 wrong codes were sent for this app in the last 24 hours, so verification is paused for it. No code can be asked for or checked until the time the message gives afterpaused until, which is when the oldest of those wrong codes is 24 hours old. The same answer comes once the person's apps together have sent 20 wrong codes in 24 hours: verification is then paused for every app they connected, and removing an app does not lift that pause. Codes entered on the website are not affected. The person is told by email.rate_limited: the key or app made more than 600 requests in 60 seconds. Wait for the seconds inRetry-After.- 503
step_up_undeliverable: the email with the code could not be sent just now. Try again in a moment.
The errors every operation can return401403404422500Error catalog
Also available in
POST/security/step-up/verify
Send the verification code
Needs no scope, and is for OAuth access tokens only. Checks the code the person typed against the one POST /security/step-up started, and on a match verifies this token for 60 minutes. Every operation that answered step_up_required works until elevatedUntil, and so do the app's MCP tools that need a code.
A code takes at most 5 tries, and an authenticator code is accepted only once. Wrong codes also add up for the app: after 10 in 24 hours, verification for that app is paused (after 20 across all of the person's apps, for every app), even a correct code is refused until the time the 429 message gives, and the person is told by email. The verification belongs to the app the token was issued to, by its client ID, so a second app verifies separately.
Request body
codestringRequiredThe six-digit code from the email or the authenticator app, or one of the backup codes, such as
abcde-12345. Spaces are ignored. A backup code works once.6 to 12 characters
Returns
Verified, and until when.
Errors
- 400
step_up_code_invalid: the code did not match, and the message says how many tries are left, counting down to whichever runs out first: this code's 5 tries, the 10 wrong codes the app may send in 24 hours, or the 20 wrong codes all of the person's apps together may send in 24 hours. An authenticator code is accepted once, so sending it again counts as a wrong code.step_up_code_expired: there is no code waiting, or it ran out after 10 minutes. Ask for a new one withPOST /security/step-up.step_up_not_applicable: the call was made with an API key.- 429
step_up_locked: 5 wrong codes were sent for this code, so it no longer works. Ask for a new one withPOST /security/step-up. A code that ran out of tries is never reused, so that call starts a fresh one even withoutresend.step_up_locked: 10 wrong codes were sent for this app in the last 24 hours, so verification is paused for it. No code can be asked for or checked until the time the message gives afterpaused until, which is when the oldest of those wrong codes is 24 hours old. The same answer comes once the person's apps together have sent 20 wrong codes in 24 hours: verification is then paused for every app they connected, and removing an app does not lift that pause. Codes entered on the website are not affected. The person is told by email.rate_limited: the key or app made more than 600 requests in 60 seconds. Wait for the seconds inRetry-After.
The errors every operation can return401403404422500Error catalog
Also available in
GET/security/events
Read the workspace security log
The changes people made to who can reach the workspace, newest first: invitations sent and withdrawn, members added and removed, roles created, changed and deleted, the two-factor requirement, passwords set for an address and directory sync. Each one names who did it. Nothing is ever removed from it. Paging is keyset: pass nextCursor back as cursor while hasMore is true.
Requires the members:read scope.
Query parameters
limitintegerRows per page, 1 to 100.
At least 1At most 100Default25cursorstringThe previous page's
nextCursor, passed back as it came. It is opaque: it holds where the last row sat in this list's order, so a row deleted or edited between pages never breaks the walk, and the next page starts at the first row that sorts after it. A value this list did not hand out is a 400invalid_cursor.
Returns
A page of the log.
Errors
The errors every operation can return400401403404422429500Error catalog
Also available in
- TypeScript
security.listEvents()security.listAllEvents()security.iterateEvents()- Python
security.list_events()security.list_all_events()security.iterate_events()- Ruby
security.list_eventssecurity.list_all_eventssecurity.iterate_events- PHP
security->listEventssecurity->listAllEventssecurity->iterateEvents- Go
Security.ListEventsSecurity.ListAllEventsSecurity.IterateEvents- Java
security().listEventssecurity().listAllEventssecurity().iterateEvents- C#
Security.ListEventsAsyncSecurity.ListAllEventsAsyncSecurity.IterateEventsAsync- CLI
openemail security list-events- MCP
listWorkspaceSecurityEvents
Objects
SecurityEventobject
objectstringRequired- One of
"security_event" idstringRequiredscopestringRequiredaccountfor the person's own log,workspacefor the workspace's.One of"account""workspace"kindstringRequired- One of
"sign-in""session-revoked""sessions-revoked""password-changed""password-reset""two-factor-enabled""two-factor-disabled""passkey-added""passkey-removed""member-added""member-removed""member-role-changed""invitation-sent""invitation-revoked""role-created""role-changed""role-deleted""two-factor-requirement-changed""address-password-set""address-password-removed""directory-sync-connected""directory-sync-disconnected""directory-sync-token-rotated""directory-sync-changed""connector-connected""connector-disconnected""connector-changed""ownership-offered""ownership-transferred" atstringRequired- Format
date-time actorobjectRequiredWho made a workspace change, or null for the person's own log.
Can be nullnamestringRequired- Can be null
emailstringRequired- Can be null
memberobjectRequiredThe person a workspace change was about.
Can be nullnamestringRequired- Can be null
emailstringRequired- Can be null
deviceobjectRequiredThe device it happened on, when one was known.
Can be nullkindstringRequiredbrowser,appfor the Nextmail phone app, orunknown.One of"browser""app""unknown"browserstringRequiredSuch as
Chrome.Can be nullosstringRequiredSuch as
macOSoriOS.Can be nullnamestringRequiredThe name of the phone, when the phone app reported one.
Can be nullappVersionstringRequired- Can be null
authMethodstringRequiredHow a sign-in was made.
Can be nullOne of"password""totp""backup-code""passkey""email-link""handoff"countrystringRequired- Can be null
citystringRequired- Can be null
detailSecurityEventDetailRequired
SecurityEventDetailobject
What the event was about. Only the fields that apply to its kind are present.
byKeybooleanTrue when an API key made the change.
byDirectorybooleanTrue when directory sync made the change.
rolestring- Can be null
previousRolestring- Can be null
passkeystringThe name of the passkey.
Can be nulldevicestringThe device that was signed out, as an English label.
Can be nulldeviceInfoobjectThe same device in parts, so a client can name it in its own language. Absent on entries recorded before it was added.
Can be nullkindstringRequiredbrowser,appfor the Nextmail phone app, orunknown.One of"browser""app""unknown"browserstringRequiredSuch as
Chrome.Can be nullosstringRequiredSuch as
macOSoriOS.Can be nullnamestringRequiredThe name of the phone, when the phone app reported one.
Can be nullappVersionstringRequired- Can be null
sessionsintegerHow many devices were signed out.
appsintegerHow many connected apps were removed.
newDevicebooleanTrue for a sign-in from a device not seen before.
addressstring- Can be null
requiredbooleanenabledbooleanconnectorstringThe name of the app a connector entry is about.
Can be nullaccessstringWhat the connector lets the assistant do,
readorfull.Can be nullpausedbooleanWhether the connector is paused.
SecurityEventListobject
objectstring- One of
"list" dataSecurityEvent[]hasMorebooleanTrue when another page follows. Pass
nextCursorback ascursorto read it.nextCursorstringAn opaque cursor for the next page, or null on the last page. Pass it back unchanged.
Can be null
StepUpChallengeobject
objectstring- One of
"step_up_challenge" methodstringtotpwhen the person has two-factor authentication turned on: the code comes from their authenticator app, or is one of their backup codes.emailotherwise: a six-digit code that works for 10 minutes is emailed to the address they sign in with.One of"totp""email"sentTostringOnly when
methodisemail: the address the code went to, masked to its first character and its domain, such asa•••@example.com.reusedbooleanTrue when a code sent earlier is still waiting and nothing new was sent. Pass
resend: trueto send a fresh one. A code that took 5 wrong tries is never reused, so the next call sends a fresh one withoutresend.
StepUpStatusobject
objectstring- One of
"step_up" elevatedbooleanWhether this access token may call the operations that need a verification code right now.
elevatedUntilstringWhen the current verification runs out. Null when there is none.
Can be nullFormatdate-timemethodstringtotpwhen the person has two-factor authentication turned on: the code comes from their authenticator app, or is one of their backup codes.emailotherwise: a six-digit code that works for 10 minutes is emailed to the address they sign in with.One of"totp""email"minutesintegerHow long one verification lasts, in minutes.
One of60
StepUpVerificationobject
objectstring- One of
"step_up" elevatedboolean- One of
true elevatedUntilstringWhen this verification runs out, 60 minutes from now.
Formatdate-time