Recover API Key
Start the API key recovery flow. Directs users to sign in to the dashboard via a magic link.
Starts the API key recovery flow. This endpoint never returns an API key in the response — by design. The response directs the caller to sign in to the dashboard, where they can view or rotate their key after verifying ownership of the email via a magic link.
This is not an account-existence check. The response shape is identical whether the email matches a registered account or not — there is no exists: true|false field, no 404 branch, and the message / dashboard_url payload never varies. Agents that try to use /auth/recover as a lookup for "does this email have an account?" will be misled by the response body.
Security: why the response is uniform
The handler is timing-padded at the Python level: regardless of whether the email resolves to a user, it executes the same sequence of database lookups (one real, one against a sentinel address) so that branch-count divergence doesn't stack on top of any underlying cache-hit vs cache-miss timing oracle in the user store. This reduces branch asymmetry but does not claim to be fully timing-proof — the underlying cache layer can still differ in how long a hit vs a miss takes, and that is not mitigated at this endpoint.
Combined with the rate limit below, the intent is to make email enumeration impractical, not mathematically impossible.
The endpoint is also rate-limited 3 requests per hour per IP. Additional requests return 429 with a retry-after hint.
Request
emailstringrequiredThe email address to recover. Lowercased and stripped server-side.
Response
{
"message": "Sign in to your dashboard to view or rotate your API key.",
"dashboard_url": "https://dashboard.boringmarketing.com"
}
The response shape never varies. Even on an unknown email, you get the same message and dashboard_url — the dashboard's sign-in flow is what actually gates access to the key.
Errors
| Status | Meaning |
|---|---|
422 | email is missing or not a string. |
429 | Rate limit hit (more than 3 requests per hour from this IP). |
Example
curl -X POST \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}' \
https://api.boringmarketing.com/auth/recoverFlow
- User (or agent on behalf of a user) calls
POST /auth/recoverwith an email. - Server logs the attempt, runs the timing-padded lookup, and returns the dashboard URL.
- User opens
dashboard_url, signs in with a magic link sent to their email. - Once signed in, the dashboard calls
GET /auth/me/api-keyinternally to hydrate the session with the user's key. - From the dashboard, the user can either view the key or call
POST /auth/rotate-keyto invalidate the old one and get a fresh one.