Account and billing
Account security and alerts
Protect your account with two-factor sign-in, lock API keys to IP addresses, cap their spend, and get an email or webhook alert before your balance runs out.
On this page
Your Relaykit account holds prepaid money, and your API keys can spend it. This page covers the settings that protect both: how you sign in, what each key may do, and how to hear about a low balance before requests start failing. Account settings are on the Settings page of the console; key settings are on the API keys page.
Signing in
Two-factor authentication
With two-factor authentication on, signing in needs your password and a six-digit code from an authenticator app such as 1Password, Bitwarden, Google Authenticator or Aegis. Sensitive changes, such as turning two-factor off or deleting the account, ask for a code too.
- On the Settings page, choose Set up two-factor. Confirm your password if asked. Setup must be finished within 5 minutes.
- Add the account to your authenticator app with the setup key the console shows. It is a standard time-based key that makes six-digit codes.
- Save the backup codes shown during setup somewhere safe, away from your phone. Each one works once in place of an app code.
- Enter the current code from the app as the 6-digit code and choose Turn on.
To turn two-factor off (Turn off) or get new backup codes (New backup codes), confirm with a code from the app or a backup code in the Authentication code field. New backup codes replace all the old ones. After several wrong codes in a row, code checks pause for a while before you can try again.
If you lose your phone, sign in with a backup code and set up the app again. If you have lost both, write to support@relaykit.dev from the account’s email address.
Signed-in devices
The Settings page lists the browsers signed in to your account. End any session you do not recognise, or sign out everywhere else at once. Changing your password also signs out every other device. Your API keys keep working in both cases; they are separate from sign-in sessions.
Protecting API keys
Each key can carry its own limits. Set them when you create the key, or later by editing it on the API keys page.
| Setting | What it does | When a request breaks it |
|---|---|---|
| IP allowlist | Only requests from the listed addresses are accepted. Set it in the Allowed IP addresses field when you create or edit a key. One IP address or CIDR range per line, for example 203.0.113.7 or 203.0.113.0/24. IPv6 works too. Empty means any address. |
403 with “Your IP address is not on this key’s allowed list” |
| Spend limit | The key stops after spending this many dollars. | 403 while the rest is too small for one request, then 401 once used up |
| Expiry date | The key stops at the end of that day. | 401 |
| Model list | The key can only call the models you pick. | 403 with “This token has no access to model …” |
Authentication and keys explains spend limits, expiry dates and model lists in detail. The allowlist checks the address the request comes from as the gateway sees it: for a server behind NAT or a cloud load balancer, that is its public outgoing address, not its private one.
The Last used column on the keys page shows when each key was last used for a billed request, which makes forgotten keys easy to spot. A key that only calls free models may show as never used. Disable or revoke keys you no longer need.
Low-balance alerts
A low-balance alert tells you when your balance falls below a level you choose, so you can top up before requests start failing with 403. On the Settings page, under Low-balance alerts, choose Email or Webhook under Send alerts by, enter the level in Alert when the balance is below (USD) (for a webhook also the Webhook URL and, optionally, a Signing secret), then choose Save alerts.
How alerts behave:
- The gateway checks the balance after every billed request. If the balance left after that request is below your level, it sends an alert.
- While the balance stays below the level, alerts repeat, at most two in any ten minutes.
- If you set no level, the service’s default level applies.
By webhook
The gateway sends a POST request with a JSON body to your URL. Any 2xx response counts as delivered. Use a public HTTPS URL: the gateway does not send alerts to localhost or to private-network addresses.
| Field | Contents |
|---|---|
type |
quota_exceed for a low-balance alert. |
title |
A short heading. |
content |
The message text. |
values |
The parts filled into content: the heading, your balance as text and a link for adding credit. |
timestamp |
When the alert was sent, in Unix seconds. |
Base your handling on type and write your own message. The wording of title and content may change and is not guaranteed to be in English.
If you set a secret, each request carries an X-Webhook-Signature header: the hex-encoded HMAC-SHA256 of the raw request body, keyed with your secret. Check it before you act on the alert:
import hashlib, hmac
def is_valid(raw_body: bytes, signature: str | None, secret: str) -> bool:
"""raw_body: the request body exactly as received, before any JSON parsing."""
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature or "")
# signature = request.headers.get("X-Webhook-Signature")import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received (a Buffer), before JSON.parse
export function isValid(rawBody, signature, secret) {
const expected = Buffer.from(createHmac("sha256", secret).update(rawBody).digest("hex"));
const given = Buffer.from(signature ?? "");
return expected.length === given.length && timingSafeEqual(expected, given);
}
// const signature = req.headers["x-webhook-signature"];By email
If your account has an email address, alerts go to it by default, even before you save anything: then they start once the balance is nearly used up. Save a level to be warned earlier. Each email states your balance and links to Billing.
Alerts go only to the address on your account, never to another one. Accounts without an email address get alerts by webhook.
If a key leaks
- On the API keys page, disable the key straight away. It stops working at once.
- Create a replacement with an IP allowlist and a spend limit, and deploy it.
- On the usage page, filter by the old key to see what it was used for.
- Revoke the old key.
- Remove the key from wherever it leaked: repository history, logs, shared documents.
If you see usage you did not make, write to support@relaykit.dev with the key’s name and the time range.
Related
- Authentication and keys: sending keys, rotating them, and every per-key setting.
- Cost control: spend limits, cheaper models and caching.
- Routing and privacy: what the gateway records about each request.