Clés API
Chaque opération de ce groupe : ce qu'elle accepte, ce qu'elle retourne et les erreurs qu'elle peut renvoyer.
Opérations
The keys of the workspace, their request log and their activity: the Settings, API keys page of the app. Reading needs keys:read; creating, changing, rotating, switching, revoking and deleting need keys:manage, a scope no key holds unless somebody gave it one. Step-up verification, which the app asks for before it mints or rotates a key, cannot apply to a call made with a key, so treat keys:manage as a credential that can make credentials: give it only to automation that provisions keys, narrow that key to the send scope and role it needs, and give it an expiry. A key never makes or reaches a key wider than itself.
GET/keys
List API keys
Every key in the workspace, newest first, a page at a time, with its status, scopes, role, send scope, when it was last used and who made and last changed it. Revoked and expired keys stay listed until somebody deletes them. No secret is ever returned here.
A key never makes or reaches a key wider than itself. What it creates, changes, rotates, switches, revokes or deletes has to sit inside it on every axis: scopes the caller holds (after its own role has narrowed them), the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where holding one address never covers its whole domain. A key narrowed to some domains or addresses also only SEES the keys whose send scope sits inside its own; any other is a 404. Over OAuth only the workspace owner reaches these calls, and a member's token is refused with owner_only.
Requires the keys:read scope.
Paramètres de requête
limitintegerRows per page, 1 to 100.
Au moins 1Au plus 100Par défaut25cursorstringThe 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.
Retourne
A page of keys.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
POST/keys
Create an API key
Mints a live key and returns its secret in token, once. Nothing recovers it afterwards, so store it before doing anything else.
Left out, scopes is emails:send, the role is the caller's own (or none), the send scope is the caller's own (or none, which means every address the workspace owns), and the expiry is the caller's (or none). The workspace cap on live keys applies, as a 422 workspace_limit_reached. The new key is attributed to the key that made it in the activity log, and it can make keys of its own only if it was given keys:manage.
A key never makes or reaches a key wider than itself. What it creates, changes, rotates, switches, revokes or deletes has to sit inside it on every axis: scopes the caller holds (after its own role has narrowed them), the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where holding one address never covers its whole domain. A key narrowed to some domains or addresses also only SEES the keys whose send scope sits inside its own; any other is a 404. Over OAuth only the workspace owner reaches these calls, and a member's token is refused with owner_only.
Requires the keys:manage scope.
Corps de la requête
namestringObligatoireA name, 1 to 60 characters.
De 1 à 60 caractèresscopesstring[]The scopes the key holds. Left out,
emails:send. Each one has to be held by the caller.Au moins un élémentL'un de"emails:send""emails:read""drafts:read""drafts:write""threads:read""threads:write""files:read""files:write""labels:read""labels:write""contacts:read""contacts:write""audiences:read""audiences:write""calendar:read""calendar:write""templates:read""templates:write""domains:read""domains:write""webhooks:read""webhooks:write""rules:read""rules:write""connections:read""members:read""members:write""roles:read""roles:write""settings:read""settings:write""keys:write""keys:read""keys:manage""forms:read""forms:write""billing:read""billing:write""account:read""account:write"Par défaut["emails:send"]roleIdstringA role to cap the key. Left out, the caller's own role, or none. A caller with a role can only give its own.
Peut être nullDe 1 à 64 caractèresaddressAllowliststring[]Single addresses the key may send as. Left out together with
domainAllowlist, the caller's own send scope.Jusqu'à 50 élémentsdomainAllowliststring[]Whole domains the key may send as, including addresses added to them later.
Jusqu'à 25 élémentsexpiresInMinutesintegerMinutes until the key expires, 5 to 5,256,000 (ten years). Left out, the caller's own expiry, or none.
Au moins 5Au plus 5256000
Retourne
The key, with its secret.
objectstring- L'un de
"api_key" idstring24 hex characters, the part of the token after
oe_live_.namestringmodestring- L'un de
"live""test" maskedKeystringEnough of the token to tell two keys apart, such as
oe_live_4c1b…kX7a.keyLast4stringstatusstring- L'un de
"revoked""expired""inactive""active" scopesstring[]- L'un de
"emails:send""emails:read""drafts:read""drafts:write""threads:read""threads:write""files:read""files:write""labels:read""labels:write""contacts:read""contacts:write""audiences:read""audiences:write""calendar:read""calendar:write""templates:read""templates:write""domains:read""domains:write""webhooks:read""webhooks:write""rules:read""rules:write""connections:read""members:read""members:write""roles:read""roles:write""settings:read""settings:write""keys:write""keys:read""keys:manage""forms:read""forms:write""billing:read""billing:write""account:read""account:write" roleIdstringThe role that caps the key, if any.
Peut être nullroleNamestring- Peut être null
addressAllowliststring[]- Peut être null
domainAllowliststring[]- Peut être null
expiresAtstring- Peut être nullFormat
date-time lastUsedAtstring- Peut être nullFormat
date-time totalUsesintegerCalls the key has made, leaving out the ones refused before it authenticated.
rotatedAtstring- Peut être nullFormat
date-time rotationCountintegerdeactivatedAtstring- Peut être nullFormat
date-time revokedAtstring- Peut être nullFormat
date-time revokedReasonstring- Peut être null
createdAtstring- Format
date-time createdByAuditActorupdatedAtstring- Format
date-time updatedByAuditActorlastChangeAtstring- Peut être nullFormat
date-time lastChangeTypestring- Peut être null
tokenstringThe whole secret,
oe_live_…, shown this once.
Erreurs
- 403
insufficient_scope: the caller lackskeys:manage.beyond_caller_authority: the key asked for would be wider than the caller, andparamnames the axis (scopes,roleId,mode,expiresInMinutesoraddressAllowlist).owner_only: a member's OAuth token.- 422
invalid_parameterorunknown_parameteron a field,role_not_foundonroleId, a domain or address the workspace does not own, orworkspace_limit_reached.
Les erreurs que toute opération peut renvoyer400401404500Catalogue des erreurs
Aussi disponible dans
GET/keys/requests
List the request log
Every authenticated call the workspace's keys made, newest first, the Requests tab of the app: method, path, status, error code, duration, IP and user agent, never a body or a query string. Calls refused before a key could be identified are not in it, and neither are calls made with an OAuth access token. Nothing is pruned. keyIds, failedOnly, since and until are the filters the app offers.
A narrowed key reads only the log of the keys it can see.
Requires the keys:read scope.
Paramètres de requête
keyIdsstringComma-separated key ids, at most 50. Left out, every key in the workspace.
failedOnlybooleanOnly calls answered with a status of 400 or more.
Par défautfalsesincestringOnly rows at or after this instant, ISO 8601. One that does not parse is a 400
invalid_parameter.Formatdate-timeuntilstringOnly rows before this instant. It has to be later than
since.Formatdate-timelimitintegerRows per page, 1 to 100.
Au moins 1Au plus 100Par défaut25cursorstringThe 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.
Retourne
A page of calls, newest first.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
GET/keys/activity
List API key activity
What happened to the workspace's keys, newest first, the Activity tab of the app: created, updated, rotated, deactivated, reactivated, revoked, deleted, and every attempt to authenticate with a key that was refused. actor says who, a person as @username or a key as API key <name>, and detail.source where from. A deleted key keeps its history. keyIds, since and until narrow it.
A narrowed key reads only the activity of the keys it can see.
Requires the keys:read scope.
Paramètres de requête
keyIdsstringComma-separated key ids, at most 50. Left out, every key in the workspace.
sincestringOnly rows at or after this instant, ISO 8601. One that does not parse is a 400
invalid_parameter.Formatdate-timeuntilstringOnly rows before this instant. It has to be later than
since.Formatdate-timelimitintegerRows per page, 1 to 100.
Au moins 1Au plus 100Par défaut25cursorstringThe 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.
Retourne
A page of changes, newest first.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
GET/keys/{id}
Retrieve an API key
One key, without its secret. A key the caller cannot see is a 404.
Requires the keys:read scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Retourne
The key.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
PATCH/keys/{id}
Update an API key
Renames a key, replaces its scopes or its send scope, or switches it off and on with enabled. A switched-off key is refused on every call with inactive_api_key and keeps everything it had, so switching it back on restores it exactly; that is the reversible alternative to revoking. scopes, addressAllowlist and domainAllowlist REPLACE what the key had, and a list left out stays as it was. A revoked key cannot be changed.
A key never makes or reaches a key wider than itself. What it creates, changes, rotates, switches, revokes or deletes has to sit inside it on every axis: scopes the caller holds (after its own role has narrowed them), the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where holding one address never covers its whole domain. A key narrowed to some domains or addresses also only SEES the keys whose send scope sits inside its own; any other is a 404. Over OAuth only the workspace owner reaches these calls, and a member's token is refused with owner_only. A key changing itself may only narrow itself.
Requires the keys:manage scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Corps de la requête
namestringA new name, 1 to 60 characters.
De 1 à 60 caractèresscopesstring[]The whole new list of scopes, at least one.
Au moins un élémentL'un de"emails:send""emails:read""drafts:read""drafts:write""threads:read""threads:write""files:read""files:write""labels:read""labels:write""contacts:read""contacts:write""audiences:read""audiences:write""calendar:read""calendar:write""templates:read""templates:write""domains:read""domains:write""webhooks:read""webhooks:write""rules:read""rules:write""connections:read""members:read""members:write""roles:read""roles:write""settings:read""settings:write""keys:write""keys:read""keys:manage""forms:read""forms:write""billing:read""billing:write""account:read""account:write"addressAllowliststring[]The whole new list of single addresses.
Jusqu'à 50 élémentsdomainAllowliststring[]The whole new list of whole domains.
Jusqu'à 25 élémentsenabledbooleanFalse switches the key off, true switches it back on. Reversible, unlike revoking.
Retourne
The key as it now stands.
Erreurs
- 409
revoked: a revoked key cannot be changed.
Les erreurs que toute opération peut renvoyer400401404422500Catalogue des erreurs
Aussi disponible dans
DELETE/keys/{id}
Delete an API key
Removes a revoked key from the list. Its request log and its activity stay, under Deleted key. A key that has not been revoked is refused, so nothing still calling with it can lose its credential without somebody deciding to first.
Requires the keys:manage scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Retourne
{ object: "api_key", id, deleted: true }.
Erreurs
- 409
not_revoked: revoke the key first.
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
POST/keys/{id}/rotate
Rotate an API key
Gives a key a new secret and returns it in token, once. The id, name, scopes, role, send scope, expiry and request history all carry on, and the old secret stops working the instant this returns, with no overlap window. Rotating the calling key itself follows POST /keys/self/rotate and is allowed with keys:write as well as keys:manage. A revoked or expired key cannot be rotated.
A key never makes or reaches a key wider than itself. What it creates, changes, rotates, switches, revokes or deletes has to sit inside it on every axis: scopes the caller holds (after its own role has narrowed them), the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where holding one address never covers its whole domain. A key narrowed to some domains or addresses also only SEES the keys whose send scope sits inside its own; any other is a 404. Over OAuth only the workspace owner reaches these calls, and a member's token is refused with owner_only. Rotation hands the caller a working secret for the key, which is why a key that is wider than the caller in any way is refused.
Requires the keys:manage scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Retourne
The key, with its new secret.
objectstring- L'un de
"api_key" idstring24 hex characters, the part of the token after
oe_live_.namestringmodestring- L'un de
"live""test" maskedKeystringEnough of the token to tell two keys apart, such as
oe_live_4c1b…kX7a.keyLast4stringstatusstring- L'un de
"revoked""expired""inactive""active" scopesstring[]- L'un de
"emails:send""emails:read""drafts:read""drafts:write""threads:read""threads:write""files:read""files:write""labels:read""labels:write""contacts:read""contacts:write""audiences:read""audiences:write""calendar:read""calendar:write""templates:read""templates:write""domains:read""domains:write""webhooks:read""webhooks:write""rules:read""rules:write""connections:read""members:read""members:write""roles:read""roles:write""settings:read""settings:write""keys:write""keys:read""keys:manage""forms:read""forms:write""billing:read""billing:write""account:read""account:write" roleIdstringThe role that caps the key, if any.
Peut être nullroleNamestring- Peut être null
addressAllowliststring[]- Peut être null
domainAllowliststring[]- Peut être null
expiresAtstring- Peut être nullFormat
date-time lastUsedAtstring- Peut être nullFormat
date-time totalUsesintegerCalls the key has made, leaving out the ones refused before it authenticated.
rotatedAtstring- Format
date-time rotationCountintegerdeactivatedAtstring- Peut être nullFormat
date-time revokedAtstring- Peut être nullFormat
date-time revokedReasonstring- Peut être null
createdAtstring- Format
date-time createdByAuditActorupdatedAtstring- Format
date-time updatedByAuditActorlastChangeAtstring- Peut être nullFormat
date-time lastChangeTypestring- Peut être null
tokenstringThe new secret, shown this once.
Erreurs
Les erreurs que toute opération peut renvoyer400401404422500Catalogue des erreurs
Aussi disponible dans
POST/keys/{id}/revoke
Revoke an API key
Revokes a key for good: every later call with it is refused with revoked_api_key, and it can never be switched back on, rotated or changed. The body is optional and may carry a reason, kept on the key. Revoking a key that is already revoked changes nothing and answers the same. A key may revoke itself, which is how an integration that suspects its secret has leaked retires it at once.
A key never makes or reaches a key wider than itself. What it creates, changes, rotates, switches, revokes or deletes has to sit inside it on every axis: scopes the caller holds (after its own role has narrowed them), the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where holding one address never covers its whole domain. A key narrowed to some domains or addresses also only SEES the keys whose send scope sits inside its own; any other is a 404. Over OAuth only the workspace owner reaches these calls, and a member's token is refused with owner_only.
Requires the keys:manage scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Corps de la requête
reasonstringWhy, at most 200 characters.
Jusqu'à 200 caractères
Retourne
The key, now revoked.
Erreurs
Les erreurs que toute opération peut renvoyer400401404422500Catalogue des erreurs
Aussi disponible dans
GET/keys/{id}/requests
List one key's requests
The request log of one key, newest first. A deleted key's log is still readable by a key that is not narrowed.
Requires the keys:read scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Paramètres de requête
failedOnlybooleanOnly calls answered with a status of 400 or more.
Par défautfalsesincestringOnly rows at or after this instant, ISO 8601. One that does not parse is a 400
invalid_parameter.Formatdate-timeuntilstringOnly rows before this instant. It has to be later than
since.Formatdate-timelimitintegerRows per page, 1 to 100.
Au moins 1Au plus 100Par défaut25cursorstringThe 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.
Retourne
A page of calls, newest first.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
GET/keys/{id}/activity
List one key's activity
What happened to one key, newest first. A deleted key's history is still readable by a key that is not narrowed.
Requires the keys:read scope.
Paramètres de chemin
idstringObligatoireThe key id, 24 hex characters.
Paramètres de requête
sincestringOnly rows at or after this instant, ISO 8601. One that does not parse is a 400
invalid_parameter.Formatdate-timeuntilstringOnly rows before this instant. It has to be later than
since.Formatdate-timelimitintegerRows per page, 1 to 100.
Au moins 1Au plus 100Par défaut25cursorstringThe 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.
Retourne
A page of changes, newest first.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
GET/keys/stats
Read API key stats
What the keys of the workspace did inside a window, the Analytics tab of the API keys page: the mail they sent and what became of it, the calls refused for a bad or revoked secret, the requests they made and how many failed, the 8 routes they called most with the median time each took, and the status codes they got back. Every key you can see, or the ones keyIds names. A key limited to some addresses sees only the keys whose send scope sits inside its own, and over OAuth only the owner of the workspace reaches it.
Requires the keys:read and emails:read scopes.
Paramètres de requête
keyIdsstringComma-separated key ids, at most 50. Left out, every key you can see.
sincestringThe start of the window, an ISO 8601 instant. Left out, 30 days before
until.Formatdate-timeuntilstringThe end of the window, an ISO 8601 instant, not included. Left out, now.
Formatdate-timegrainstringHow wide one bucket of the series is. The bucket keys change shape with it:
YYYY-MM-DDfor a day,YYYY-MM-DDTHHfor an hour,YYYY-MM-DDTHH:MMfor a minute.L'un de"minute""hour""day"Par défaut"day"offsetMinutesintegerMinutes to add to UTC before cutting the buckets, so a day starts at midnight where the reader is. 120 for UTC+2.
Au moins -840Au plus 840Par défaut0
Retourne
The figures for the window.
Erreurs
Les erreurs que toute opération peut renvoyer400401403404422500Catalogue des erreurs
Aussi disponible dans
Objets
ApiKeyobject
An API key without its secret. The secret is returned once, by the call that made or rotated it, and never again.
objectstring- L'un de
"api_key" idstring24 hex characters, the part of the token after
oe_live_.namestringmodestring- L'un de
"live""test" maskedKeystringEnough of the token to tell two keys apart, such as
oe_live_4c1b…kX7a.keyLast4stringstatusstring- L'un de
"revoked""expired""inactive""active" scopesstring[]- L'un de
"emails:send""emails:read""drafts:read""drafts:write""threads:read""threads:write""files:read""files:write""labels:read""labels:write""contacts:read""contacts:write""audiences:read""audiences:write""calendar:read""calendar:write""templates:read""templates:write""domains:read""domains:write""webhooks:read""webhooks:write""rules:read""rules:write""connections:read""members:read""members:write""roles:read""roles:write""settings:read""settings:write""keys:write""keys:read""keys:manage""forms:read""forms:write""billing:read""billing:write""account:read""account:write" roleIdstringThe role that caps the key, if any.
Peut être nullroleNamestring- Peut être null
addressAllowliststring[]- Peut être null
domainAllowliststring[]- Peut être null
expiresAtstring- Peut être nullFormat
date-time lastUsedAtstring- Peut être nullFormat
date-time totalUsesintegerCalls the key has made, leaving out the ones refused before it authenticated.
rotatedAtstring- Peut être nullFormat
date-time rotationCountintegerdeactivatedAtstring- Peut être nullFormat
date-time revokedAtstring- Peut être nullFormat
date-time revokedReasonstring- Peut être null
createdAtstring- Format
date-time createdByAuditActorupdatedAtstring- Format
date-time updatedByAuditActorlastChangeAtstring- Peut être nullFormat
date-time lastChangeTypestring- Peut être null
ApiKeyActivityEntryobject
objectstring- L'un de
"api_key_event" idstringkeyIdstringkeyNamestringDeleted keyonce the key itself is gone.typestring- L'un de
"created""updated""rotated""revoked""deactivated""reactivated""auth_failed""deleted" createdAtstring- Format
date-time actorAuditActordetailobjectWhat changed and where it was changed from (
source: console, api, mcp or documentation). A refused authentication carriesreason.
ApiKeyActivityListobject
objectstring- L'un de
"list" 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.
Peut être null
ApiKeyListobject
objectstring- L'un de
"list" dataApiKey[]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.
Peut être null
ApiKeyRequestobject
One authenticated call a key made. Never a body or a query string.
objectstring- L'un de
"api_key_request" idstringkeyIdstringkeyNamestringDeleted keyonce the key itself is gone.requestIdstringThe
X-Request-Idthe call was answered with.Peut être nullmethodstringpathstringstatusintegererrorCodestring- Peut être null
durationMsintegeripstring- Peut être null
userAgentstring- Peut être null
createdAtstring- Format
date-time
ApiKeyRequestListobject
objectstring- L'un de
"list" dataApiKeyRequest[]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.
Peut être null
ApiKeyStatsobject
objectstringObligatoire- L'un de
"api_key_stats" sincestringObligatoire- Format
date-time untilstringObligatoire- Format
date-time grainstringObligatoire- L'un de
"minute""hour""day" keyIdsstring[]ObligatoireThe keys asked for. Empty means every key you can see.
sendsobjectObligatoireThe mail the keys sent, with what became of it.
daysobject[]daystringThe bucket, shaped by
grain.sentintegerdeliveredintegerfailedintegerbouncedintegercomplainedinteger
totalsobjectsendsintegertestSendsintegerrecipientsintegerdeliveredintegerfailedintegerbouncedintegercomplainedintegeruncertainintegerpendinginteger
statusesobject[]Sends by status.
labelstringcountinteger
sourcesobject[]Sends by where they came from.
labelstringcountinteger
sendersobject[]Sends by the address they went out as.
labelstringcountinteger
suppressedobject[]Recipients skipped because they were suppressed, by reason.
labelstringcountinteger
rejectedobject[]ObligatoireCalls refused because the secret was wrong, revoked or expired, per bucket.
bucketstringcountinteger
requestsobject[]ObligatoireRequests made and how many of them failed with a 4xx or 5xx, per bucket.
bucketstringcountintegerfailedinteger
routesobject[]ObligatoireThe routes called most, with how many failed and the median time in milliseconds.
labelstringcountintegerfailedintegermedianMsinteger
codesobject[]ObligatoireRequests by the HTTP status they got back.
labelstringcountinteger
AuditActorobject
Who made the change: a person, or a key acting over the API. Null when OpenEmail made it on its own, such as switching a webhook off after 100 failed events in a row, and when the person or key has since been deleted.
kindstring- L'un de
"user""apiKey" idstringThe account id of the person, or the id of the key.
namestringThe name of the person, or
API key <name>for a key.usernamestring- Peut être null
labelstringWhat the app shows:
@usernamefor a person who has a username, otherwisename.