Credit Balance
Description
Credit tokens directly to a user's spot balance. Testnet only — this endpoint is hard-gated by the TESTNET_ONLY=true environment variable. On mainnet (or any environment where TESTNET_ONLY is not exactly true), the route responds with 404 DISABLED to keep the surface uniform.
Admin only. Requires the ADMIN_API_KEY environment variable to be set on the server and passed as X-API-Key in the request header.
Side effects on success:
- Increments
availablefor the(user_address, token)pair inspot_balances(upsert — creates the row if it doesn't exist). - Writes an audit row in
spot_admin_creditswithadmin_actor = "admin_api_key"(the shared admin key is not per-user, so this generic actor is recorded). - Pushes a balance update via WebSocket so the UI reflects the new balance immediately without polling.
HTTP Request
POST /admin/spot/balances/credit (X-API-Key: ADMIN_API_KEY)
Testnet only (TESTNET_ONLY=true required on the server).
Weight
0 — admin endpoints have no weight limit. Each market mutation pings the engine with a ReloadMarket command so the in-memory MarketCache picks up the change without restart.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
user_address | STRING | YES | EVM wallet address of the recipient (e.g. "0xabc..."). Stored and matched lowercase. |
token | STRING | YES | Token symbol to credit (e.g. "DF", "USDT"). |
amount | DECIMAL | YES | Amount to credit as a string. Must be > 0 — returns 400 AMOUNT_NON_POSITIVE otherwise. |
reason | STRING | NO | Free-text reason recorded in the audit log. Omit if not applicable. |
Response Example
200 OK
{
"ok": true
}
| Field | Notes |
|---|---|
ok | Always true on success. The balance is updated and the audit row has been committed. |
Error Responses
| HTTP | error | When |
|---|---|---|
400 | AMOUNT_NON_POSITIVE | amount is <= 0. |
404 | DISABLED | TESTNET_ONLY env var is not set to "true" on this server (mainnet guard). |
500 | DB_ERROR | Unexpected Postgres error during the balance upsert or audit insert. Investigate server logs. |
Full list: Error Codes.
Code Examples
cURL
ADMIN_API_KEY="your_admin_api_key"
curl -s -X POST "https://api-sepolia.p99.world/api/v1/admin/spot/balances/credit" \
-H "X-API-Key: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"user_address": "0xabc123def456abc123def456abc123def456abc1",
"token": "DF",
"amount": "1000",
"reason": "testnet faucet grant"
}'
Python
import requests
ADMIN_API_KEY = "your_admin_api_key"
BASE_URL = "https://api-sepolia.p99.world/api/v1"
def credit_balance(user_address: str, token: str, amount: str, reason: str | None = None) -> dict:
body = {
"user_address": user_address,
"token": token,
"amount": amount,
}
if reason is not None:
body["reason"] = reason
r = requests.post(
f"{BASE_URL}/admin/spot/balances/credit",
json=body,
headers={"X-API-Key": ADMIN_API_KEY, "Content-Type": "application/json"},
timeout=5,
)
r.raise_for_status()
return r.json()
result = credit_balance(
user_address="0xabc123def456abc123def456abc123def456abc1",
token="DF",
amount="1000",
reason="testnet faucet grant",
)
print(result["ok"])