The API provides endpoints for storing and retrieving player money data at specific timestamps during gameplay.
Creates a new player money data record or returns existing record if the combination of timestamp_begin and timecode already exists.
Request Body:
{
"timestamp_begin": "2024-01-01T12:00:00Z",
"timecode": 12345,
"player_1_money": 1000,
"player_2_money": 2000,
"player_3_money": 0,
"player_4_money": 0,
"player_5_money": 0,
"player_6_money": 0,
"player_7_money": 0,
"player_8_money": 0
}Response (201 Created for new record, 200 OK for existing record):
{
"id": 1,
"timestamp_begin": "2024-01-01T12:00:00Z",
"timecode": 12345,
"player_1_money": 1000,
"player_2_money": 2000,
"player_3_money": 0,
"player_4_money": 0,
"player_5_money": 0,
"player_6_money": 0,
"player_7_money": 0,
"player_8_money": 0,
"created_at": "2024-01-01T12:00:00Z",
"updated_at": "2024-01-01T12:00:00Z"
}Note: If a record with the same timestamp_begin and timecode combination already exists, the API will return the existing record without creating a duplicate. No error is returned in this case.
Retrieves player money data with optional pagination.
Query Parameters:
limit(optional): Maximum number of records to returnoffset(optional): Number of records to skip
Example:
GET /player-money?limit=10&offset=0
Response (200 OK):
{
"data": [
{
"id": 1,
"timestamp_begin": "2024-01-01T12:00:00Z",
"timecode": 12345,
"player_1_money": 1000,
"player_2_money": 2000,
"player_3_money": 0,
"player_4_money": 0,
"player_5_money": 0,
"player_6_money": 0,
"player_7_money": 0,
"player_8_money": 0,
"created_at": "2024-01-01T12:00:00Z",
"updated_at": "2024-01-01T12:00:00Z"
}
],
"count": 1
}Retrieves a specific player money data record by ID.
Response (200 OK):
{
"id": 1,
"timestamp_begin": "2024-01-01T12:00:00Z",
"timecode": 12345,
"player_1_money": 1000,
"player_2_money": 2000,
"player_3_money": 0,
"player_4_money": 0,
"player_5_money": 0,
"player_6_money": 0,
"player_7_money": 0,
"player_8_money": 0,
"created_at": "2024-01-01T12:00:00Z",
"updated_at": "2024-01-01T12:00:00Z"
}Deletes a specific player money data record by ID.
Response (200 OK):
{
"message": "Player money data deleted successfully"
}Receives a Sentry envelope
from the Zulu GO client's sentry-native SDK. The client is pointed here with a
DSN of the form https://<api key>@cncstats.computersrfun.org/crash/1; the SDK
derives this URL from it and sends the key as sentry_key in the
X-Sentry-Auth header, which is checked against the same CNC_API_KEYS store
as the other write endpoints (sentry_key as a query parameter also works).
Content-Encoding: gzip bodies are accepted. The body is capped at 32 MiB.
Each envelope is stored under the logs volume as a day bucket, so a whole
night's crashes come back as one zip from GET /get_logs?seed=crash-YYYYMMDD:
crash-20261015/
Skip-013839-9b5e3a7c/ <display name>-<HHMMSS UTC>-<event id prefix>
envelope.raw the envelope as received (after gunzip)
event.json the event item, pretty-printed
<attachment> each attachment under its own filename (the minidump)
summary.txt player, release, exception, frames as module+offset
summary.txt prints every frame as <module>+<offset>, which is what
llvm-symbolizer --relative-address takes against that build's PDB; the Zulu
GO release keeps the PDB beside each release (scripts/zulugo/symbolicate.sh
in the client repo does the lookup).
Response: 200 {"id": "<event id>", "seed": "crash-20261015", "player": "Skip-013839-9b5e3a7c"}
Errors: 400 not an envelope, 401 bad or missing sentry_key, 413 too large.
All endpoints return appropriate HTTP status codes and error messages:
400 Bad Request: Invalid request format or parameters404 Not Found: Resource not found500 Internal Server Error: Server error
Error Response Format:
{
"error": "Error message",
"details": "Detailed error information"
}The player_money_data table has the following structure:
id: Primary key (auto-increment)timestamp_begin: Timestamp when the data was recorded (part of unique constraint with timecode)timecode: Game timecode at the moment of recording (part of unique constraint with timestamp_begin)player_1_moneythroughplayer_8_money: Money amounts for players 1-8created_at: Record creation timestampupdated_at: Record last update timestamp
Unique Constraint: The combination of timestamp_begin and timecode must be unique. This prevents duplicate entries for the same game moment and ensures data integrity.
DATABASE_URL: PostgreSQL connection stringCNC_INI: Path to CNC INI data directoryPORT: Application port (default: 8080)GORM_LOG_LEVEL: Database logging level (debug/info/silent)
DATABASE_URL: Automatically set by Heroku Postgres addonPORT: Automatically set by Heroku