Credits and billing
What a credit is, how a request is charged, what a hold is, and what happens when your credits run low.
You pay for requests with credits. A credit is a unit of usage, like a token. Credits are shown as a plain number, with no currency, and they are used only for requests. They can’t be withdrawn or moved to another account.
Credits belong to your workspace. You see your balance, and every request, in the dashboard.
How a request is charged
Charges are based on the tokens the request used, multiplied by the model’s published rate. The rate is locked when the request starts, so a later rate change doesn’t affect a request already running.
- Hold. Before the request runs, router.africa holds the credits it may need. The hold depends on the model’s rate and on
max_tokens. - Run. The request goes to the model.
- Settle. You are charged for the input and output tokens actually used. The rest of the hold is released.
If a request fails before it finishes, the hold is released and you are not charged for it.
A request can use slightly more than was held. You are charged the full amount and your balance stops at zero. The next request is then refused until you add credits.
When credits run low
Available credits are your balance minus what is on hold. When they are too low for a request, the API returns 402 with the reason insufficient_credits, and the model is not called.
curl -i https://api.router.africa/v1/chat/completions \
-H "Authorization: Bearer $ROUTER_AFRICA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "openai/gpt-4o-mini", "messages": [{"role": "user", "content": "Hello"}]}'
# HTTP/2 402
# {"error":{"code":402,"message":"This workspace doesn't have enough credits for this request. Add credits at https://app.router.africa.","metadata":{"error_type":"payment_required","reason":"insufficient_credits"}}}import os
import openai
from openai import OpenAI
client = OpenAI(base_url="https://api.router.africa/v1", api_key=os.environ["ROUTER_AFRICA_API_KEY"])
try:
client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
)
except openai.APIStatusError as e:
if e.status_code == 402 and e.body["metadata"]["reason"] == "insufficient_credits":
print("Add credits in the dashboard, then try again.")
else:
raiseimport OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.router.africa/v1",
apiKey: process.env.ROUTER_AFRICA_API_KEY,
});
try {
await client.chat.completions.create({
model: "openai/gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
});
} catch (err) {
if (err instanceof OpenAI.APIError && err.status === 402) {
console.log("Add credits in the dashboard, then try again.");
} else {
throw err;
}
}The SDKs don’t retry a 402. Don’t retry it yourself until you have added credits.
A key can also reach its own spend cap. That returns 402 with a different reason. See Spend caps and key scoping.
Adding credits
Add credits in the dashboard. The fee for a top-up is shown before you pay.