---
title: "API keys"
description: "A key per job, limited to the scopes and senders it needs, with every call logged."
url: "https://openemail.uk/docs/knowledge/developers/api-keys"
area: "Knowledge base"
category: "Developers"
status: "live"
---

# API keys

A key per job, limited to the scopes and senders it needs, with every call logged.

## Details

- Created in Settings → API keys on a workspace you own. The secret is shown once, and every key is an oe_live_ one.
- A key holds only the scopes you pick, and a new one starts with emails:send. It can also carry a role, which is a ceiling rather than a second grant: GET /ping returns the scopes the key names and the scopes the role left it, so a 403 for a scope the key plainly holds has a visible cause.
- The send scope names up to 25 whole domains and 50 single addresses. A whole domain also covers addresses added to it later, and a sender outside the list is refused with a 403.
- An optional expiry lets a key lapse on its own, up to ten years out.
- Rotating swaps only the secret: the id, the scopes, the send scope and the request history carry on, and the old secret stops working the moment the new one is created. A key holding keys:write can rotate itself over the API. Revoking is an update rather than a delete, so a later call is told revoked_api_key.
- Every authenticated call is logged with its method, path, status, error code, duration, IP and user agent, never a body or a query string. The key page shows it as Analytics, Activity and Requests, with the busiest routes, how often they fail and their median latency, and the same views cover several keys at once. The log is kept rather than pruned.
- Everything the page does is also on the API and the SDK: GET /keys and GET /keys/{id} read keys without their secrets, POST /keys mints one, PATCH /keys/{id} renames it, changes its scopes or send scope and switches it off and on, and rotate, revoke and delete do what they say. The request log and the activity read the same way, for one key or all of them, with the page’s filters. Reading needs keys:read and every change needs keys:manage, two scopes no key holds unless somebody gave it one. The MCP server reads the log and the activity too, as listApiKeyRequests and listApiKeyActivity.
- A key never makes or reaches a key wider than itself: its scopes, role, expiry, mode and send scope all have to sit inside the key making the call. Step-up verification cannot apply to a call made with a key, so keys:manage is a credential that makes credentials. Give it only to automation that provisions keys, with a role, a send scope and an expiry of its own, and watch the Activity tab, where everything it does is recorded against it.
- What is missing: a key cannot be tied to IP addresses, and no test-mode key can be created.
