FastAPI Showcase (Primary Example)
This is the primary developer example in this docs set.
It runs locally on your machine (localhost:9000) and calls Rankacy DEV:
https://highlights-api.rankacy.com
Source:
docs/examples/fastapi_public_demo_webhook_showcase.py
What it demonstrates
- upload
.demfiles to Public API - query demos, players, kills, highlights, render options, cost, and account data
- receive webhook callbacks for demo and highlight terminal events
demo.processed.success/demo.processed.failedhighlight.processed.success/highlight.processed.failed- deduplicate webhook events by event ID
Endpoints exposed by the example app
GET /integration/healthPOST /integration/upload-demoGET /integration/demosGET /integration/demos/{demo_id}GET /integration/demos/{demo_id}/killsGET /integration/demos/{demo_id}/playersGET /integration/highlightsGET /integration/highlights/{highlight_id}DELETE /integration/highlights/{highlight_id}GET /integration/highlights/resolutionsGET /integration/highlights/fpsGET /integration/highlights/costPOST /integration/highlights/standardPOST /integration/highlights/by-ticksPOST /integration/highlights/by-killGET /integration/me/creditGET /integration/me/transactionsGET /integration/webhook-eventsPOST /webhooks/rankacy
Run locally against DEV
export RANKACY_BASE_URL="https://highlights-api.rankacy.com"
export RANKACY_TOKEN="rk_live_..."
uvicorn fastapi_public_demo_webhook_showcase:app \
--app-dir docs/examples \
--reload \
--port 9000
Health:
curl -sS http://localhost:9000/integration/health | jq
You can use either:
curlcommands in this page, or- Swagger UI at
http://localhost:9000/docsto call the same integration endpoints interactively.
Expose webhook receiver
ngrok http 9000
Set webhook callback URL in Rankacy to:
https://<ngrok-subdomain>.ngrok.io/webhooks/rankacy
Example flow
Upload:
UPLOAD_RESPONSE=$(curl -sS -X POST http://localhost:9000/integration/upload-demo \
-F "file=@/absolute/path/to/match.dem" \
-F "generate_auto_highlight=true" \
-F "resolution_id=1" \
-F "fps_id=1")
echo "$UPLOAD_RESPONSE" | jq
DEMO_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.rankacy_response.demo_id')
Demo detail + kills:
curl -sS "http://localhost:9000/integration/demos/$DEMO_ID" | jq
KILLS_RESPONSE=$(curl -sS "http://localhost:9000/integration/demos/$DEMO_ID/kills?limit=50&offset=0")
echo "$KILLS_RESPONSE" | jq
curl -sS "http://localhost:9000/integration/demos/$DEMO_ID/players" | jq
DEMO_KILL_ID=$(echo "$KILLS_RESPONSE" | jq -r '.items[0].demo_kill_id // empty')
DEMO_KILL_TICK=$(echo "$KILLS_RESPONSE" | jq -r '.items[0].tick // empty')
DEMO_KILL_ATTACKER_STEAM_ID=$(echo "$KILLS_RESPONSE" | jq -r '.items[0].attacker_steam_id // empty')
Highlight options:
curl -sS http://localhost:9000/integration/highlights/resolutions | jq
curl -sS http://localhost:9000/integration/highlights/fps | jq
curl -sS "http://localhost:9000/integration/highlights/cost?resolution_id=1&fps_id=1" | jq
curl -sS http://localhost:9000/integration/me/credit | jq
Queue highlights:
HIGHLIGHT_RESPONSE=$(curl -sS -X POST http://localhost:9000/integration/highlights/standard \
-H "Content-Type: application/json" \
-d "{\"demo_id\":$DEMO_ID,\"resolution_id\":1,\"fps_id\":1,\"title\":\"Showcase standard\",\"show_tick\":true}")
echo "$HIGHLIGHT_RESPONSE" | jq
HIGHLIGHT_ID=$(echo "$HIGHLIGHT_RESPONSE" | jq -r '.highlight_id // empty')
if [ -n "$HIGHLIGHT_ID" ]; then
curl -sS "http://localhost:9000/integration/highlights/$HIGHLIGHT_ID" | jq
curl -sS -X DELETE "http://localhost:9000/integration/highlights/$HIGHLIGHT_ID" | jq
fi
if [ -n "$DEMO_KILL_TICK" ] && [ -n "$DEMO_KILL_ATTACKER_STEAM_ID" ]; then
curl -sS -X POST http://localhost:9000/integration/highlights/by-ticks \
-H "Content-Type: application/json" \
-d "{\"demo_id\":$DEMO_ID,\"ticks\":[{\"start_tick\":$DEMO_KILL_TICK,\"end_tick\":$DEMO_KILL_TICK,\"steam_id\":\"$DEMO_KILL_ATTACKER_STEAM_ID\"}],\"resolution_id\":1,\"fps_id\":1,\"show_tick\":true}" | jq
fi
if [ -n "$DEMO_KILL_ID" ]; then
curl -sS -X POST http://localhost:9000/integration/highlights/by-kill \
-H "Content-Type: application/json" \
-d "{\"demo_id\":$DEMO_ID,\"demo_kill_ids\":[$DEMO_KILL_ID],\"resolution_id\":1,\"fps_id\":1,\"show_tick\":true}" | jq
fi
curl -sS "http://localhost:9000/integration/me/transactions?limit=20&offset=0" | jq
Read received webhook events:
curl -sS http://localhost:9000/integration/webhook-events | jq
curl -sS http://localhost:9000/integration/webhook-events | jq -r '.items[].event_type'
Production notes
- replace in-memory stores with Redis/DB
- keep webhook handler fast and return
2xxquickly - move heavy processing to background workers
- keep API token in a secrets manager