Account security
Two-factor authentication, sessions and device alerts for dashboard users; scopes, IP allowlists, expiry and rotation for API keys.
Email verification
Every account confirms its email address with a link that is valid for 24 hours. Unverified accounts can use the sandbox freely, but creating a live key or submitting a go-live application fails with 403 email_unverified until the address is confirmed. Resend the link from the banner in the dashboard.
Two-factor authentication (TOTP)
Enable it under Settings → Security. Scan the QR code with any authenticator app (1Password, Google Authenticator, Authy, Microsoft Authenticator or anything implementing RFC 6238), confirm a code, and save the ten backup codes shown once. Each backup code signs you in one time; you can generate a new set with your password.
With two-factor on, sign-in is two steps: password, then POST /auth/mfa/verify with the 6-digit code (or a backup code). Five wrong codes end the attempt. Disabling needs both your password and a current code.
Accounts without an authenticator app get a 6-digit code by email when signing in from a browser Speedmap has not seen before; it expires in 10 minutes.
Requiring it for a workspace
Owners and admins can switch on Require two-factor authentication under Settings → Organization. Members who have not enabled it can still sign in and read, but every write in the dashboard answers 403 mfa_required_by_org until they do. Whoever turns the policy on must already have it enabled.
Sessions and devices
Settings → Security lists every active session with its browser, IP address and last activity. Sign out a single session, or all other sessions at once. Changing your password (or resetting it by email) signs out every other session. You are emailed when a new device signs in, when your password changes, and when an API key is created or revoked in a workspace you manage.
API key scopes, allowlists and expiry
Keys are created in API keys with least privilege:
| Setting | Effect | Error when violated |
|---|---|---|
Scopes | All products ( *), a list of product ids, or read (list and fetch only, no new checks). | 403 key_scope |
IP allowlist | IPv4/IPv6 addresses or CIDR blocks the key may be used from. Empty allows any address. | 403 ip_not_allowed |
Expiry | An optional date after which the key stops working. | 401 key_expired |
Every key records when and from which IP it was last used, visible in the dashboard.
Rotation
Rotate issues a replacement with the same name, mode, scopes, allowlist and expiry, and keeps the old key working for a grace period (default 60 minutes, from immediately to 24 hours) so you can deploy the new secret without downtime. The old key shows as retiring until it is revoked automatically. If a key may have leaked, rotate with no grace period or revoke it outright.
Handling these errors in code
Treat 401 key_expired, 403 key_scope and 403 ip_not_allowed as configuration errors: alert, do not retry. They never create a verification and are never billed.
{
"error": {
"code": "key_scope",
"message": "This key is not scoped to bvn",
"details": {
"scopes": [
"nin",
"account"
]
}
}
}Roles
Dashboard access is role-based: owner, admin, developer, analyst, billing and viewer. The matrix is enforced by the API on every request and shown under Team. Only an owner can transfer ownership, which needs their password.
Questions? Email developers@speedmap.ng. This page is also available as Markdown.