API Reference
Base URL
Local and CI smoke tests reach the API through NGINX:
http://localhost:9999
The production compose file exposes the same public entrypoint on port 9999.
Client IDs and limits
The implementation has five predefined clients. The API keeps this small map in memory for fast invalid-client rejection, and PostgreSQL seeds the same limits in docker-entrypoint-initdb.d/rinha.dump.sql.
| Client ID | Limit, in cents |
|---|---|
1 |
100000 |
2 |
80000 |
3 |
1000000 |
4 |
10000000 |
5 |
500000 |
POST /clientes/{id}/transacoes
Submits a credit or debit transaction.
Request body
{
"valor": 1000,
"tipo": "c",
"descricao": "deposito"
}
| Field | Type | Rule |
|---|---|---|
valor |
integer | Required positive integer amount in cents (> 0) |
tipo |
string | Required; "c" for credit or "d" for debit |
descricao |
string | Required, non-empty, maximum 10 characters |
Successful response
The response uses snake_case JSON output generated by System.Text.Json source generation.
{
"id": 1,
"limite": 100000,
"saldo": 1000
}
Status codes
| Status | When |
|---|---|
200 |
Transaction accepted and a balance is returned |
404 |
Client ID is not one of 1 through 5 |
422 |
Payload validation fails (valor <= 0, invalid tipo, missing/empty/long descricao) |
Current implementation note
The intended Rinha contract treats a debit that would exceed the client’s limit as an unprocessable transaction. The current PostgreSQL function keeps the balance unchanged and returns the current balance when the limit update fails, so the API can return 200 with an unchanged balance for this case. If strict challenge behavior is required, adjust InsertTransacao/the route handler before documenting over-limit debits as guaranteed 422 responses.
GET /clientes/{id}/extrato
Returns the current account statement.
Successful response
{
"saldo": {
"total": 1000,
"limite": 100000,
"data_extrato": "2026-04-01T19:20:20.000000"
},
"ultimas_transacoes": [
{
"valor": 1000,
"tipo": "c",
"descricao": "deposito"
}
]
}
The statement returns the latest 10 transactions ordered from newest to oldest.
Status codes
| Status | When |
|---|---|
200 |
Client exists and statement data was returned |
404 |
Client ID is not one of 1 through 5 |
GET /healthz
Health check used by local smoke tests and GitHub Actions.
| Status | When |
|---|---|
200 |
ASP.NET Core health checks pass |
Responsibility split
| Layer | Responsibility |
|---|---|
API (Program.cs) |
Route mapping, JSON serialization, payload validation, fast invalid-client checks, database calls |
PostgreSQL (rinha.dump.sql) |
Seed clients, keep balances, apply atomic balance updates, insert transaction rows, return recent statement data |
NGINX (nginx.conf) |
Public port 9999 and load balancing across the two API instances |