Platform
Authentication
API keys and agent keys authenticate REST and MCP clients, AI assistants among them. OAuth 2.1 at mydatahub.emailmovers.com/id signs you in to the app; OAuth sign-in for REST and MCP clients is planned for after launch.
One identity works everywhere, and an API key is a bearer token on REST and MCP alike. OAuth 2.1 with PKCE, issued by https://mydatahub.emailmovers.com/id, signs you in to the app. At launch, REST and MCP clients, AI assistants among them, use an API key; OAuth sign-in for them is planned for after launch.
You need neither a key nor a sign-in to look: the catalogue, counts, previews, quotes and plans work with no token, and the first 401 arrives only when an operation needs your account.
API keys
A key is mdh_live_ or mdh_test_ followed by 32 letters and digits.
| Prefix | Behaviour |
|---|---|
mdh_test_ | Returns synthetic data and never charges |
mdh_live_ | Reads your real account and spends real credits |
Send it in the Authorization header, never in a custom header or the query string.
curl "https://mydatahub.emailmovers.com/v1/account" \
-H "Authorization: Bearer $MYDATAHUB_API_KEY"Keys are made in the app at /api-keys by a signed-in person, and the secret is shown once. Only a hash is kept, so a lost secret means a new key.
No API key can make or change keys, even with the admin scope, so no key can raise its own limits. A key can carry an ip_allowlist of CIDR ranges, and an expiry.
Standard keys and agent keys
| Standard key | Agent key | |
|---|---|---|
kind | standard | agent |
| Can read, count, preview, quote | Yes, within its scopes | Yes, for the tools in allowed_tools |
| Can spend | Never on its own. A person must confirm | Within its per-order cap and monthly budget |
admin scope | Optional | Never |
An agent key is an API key with a budget, created by a human with these members.
| Member | Meaning |
|---|---|
label | What the key is for |
mode | live or test |
scopes | The scopes it holds. An agent key never takes admin |
allowed_tools | Required. The MCP tools, and the REST operations behind them, that the key may call |
allowed_connection_ids | The CRM connections a live push may use |
monthly_budget_credits | Credits the key may spend a month. The default is 1,000 (to confirm) |
per_order_max_credits | Required. The most one order may cost, no more than the monthly budget |
expires_at | When the key stops working |
webhook_url | An https endpoint for the key's notices. Register an endpoint at the same URL so the notice can be signed |
The app shows a live spend meter, and a key can be revoked at any time. An agent key may call only the tools it lists.
Any other operation, such as suppression uploads, webhooks, deleting a saved audience or the event log, is for a person. See Spending safely.
Scopes
Scopes are fine-grained, and OAuth tokens and API keys carry them the same way.
| Scope | What it grants | Spends credits |
|---|---|---|
account:read | Read the balance, plan, prices, rate limits, usage and key budgets. | no |
account:write | Set the business name and confirm that it is a UK business (PATCH /v1/account). A signed-in owner only; admin covers it too. | no |
counts:read | Run counts and breakdowns with the account's exact figures and New to you. | no |
previews:read | Draw masked samples. | no |
audiences:read | Read saved audiences. | no |
audiences:write | Save, update, refresh and delete audiences. | no |
quotes:read | Create and read machine quotes with the account's balance. | no |
orders:read | Read orders, compliance receipts and CRM pushes. | no |
orders:write | Spend credits: create and cancel orders. | yes |
records:read | Fetch and download delivered records under licence. | no |
enrich:write | Spend credits: enrich a known contact, charged only on a confident match. | yes |
suppressions:read | Read suppression lists and check records before a send. | no |
suppressions:write | Upload suppression lists and report objections. | no |
pushes:write | Connect CRMs, check overlap and push delivered records. | no |
webhooks:write | Manage webhook endpoints and read the event log. | no |
samples:request | Ask for a sample of a counted audience, sent by email to a confirmed work address. Never returns records. | no |
admin | Manage API keys, agent keys and the plan, including cancellation. Keys are made and changed by signed-in people only, and an agent key never holds admin. | no |
The first 401 challenge asks only for counts:read previews:read audiences:read. A later spend answers 403 insufficient-scope with required_scope set to orders:write and a WWW-Authenticate step-up challenge, so a consent screen names the spend. See insufficient-scope.
OAuth 2.1
https://mydatahub.emailmovers.com/id is the one issuer. At launch it signs people in to the app.
Sign-in from REST and MCP clients, so that an assistant connects with no key to copy, is planned for after launch; until then they use an API key. The list below describes the issuer as planned for all three.
- Authorization code with PKCE, and only the
S256method. - RFC 8414 authorization server metadata, and rotating refresh tokens.
- JWT access tokens that last 60 minutes, with
audset to the exact resource (RFC 8707). - RFC 9728 protected resource metadata for each resource on mydatahub.emailmovers.com, at
/.well-known/oauth-protected-resource/v1and/.well-known/oauth-protected-resource/mcp, naminghttps://mydatahub.emailmovers.com/idas the only authorization server.
After launch, client registration follows the 2026-07-28 MCP order: pre-registered redirect URIs for claude.ai, ChatGPT and Cursor first, then Client ID Metadata Documents, then Dynamic Client Registration for older clients. Loopback redirects match any port, for Claude Code. Every OAuth endpoint is built to answer within 2 seconds.
Every call is attributable
Each order records who called it: the OAuth client id or the key id, the user, the User-Agent, the client certificate fingerprint when one is presented (ChatGPT's mutual TLS), and any Web Bot Auth signature. It appears in the audit trail and on invoices. See Quotes and orders.
Anonymous use
With no token you can run counts, previews and quotes within the anonymous limits. These are 60 counts an hour and 600 a day per IP, and up to 6 filters in one audience.
Single-company counts, free text title search and a radius under 5 miles need a free account, which comes with 100 credits and no card. See Rate limits.
Today's credentials
The X-Api-Key header and POST /api/RunExtract belong to the current product. The plan is for them to keep working for 12 months from the v2 launch and then return 410. The v2 API does not accept the header or serve that route yet (to confirm).
Move to Authorization: Bearer with an mdh_ key. See the migration guide.
Next steps
- Count with a key in the Quickstart for developers.
- Create an agent key and read about budgets in Spending safely.
- Connect a client in the Quickstart for agents.