Game SDK
Record a server-verified rewarded-play event
Send only after your trusted server verifies the game achievement. A key authenticates your server; it does not prove that gameplay is legitimate. eventId and playerId are UUIDs, occurredAt must be within 5 minutes of receipt, and eventType chooses an active game-scoped fixed reward rule. Callers cannot specify payouts. Admission checks linked active accounts, game state, UTC daily player cap, game/project budgets and lifetime ceilings. A valid authenticated event stores an immutable accepted or rejected decision and returns HTTP 200; inspect data.status and data.reason. Fresh events are limited to 120 per game per minute and excess attempts are stored as rejected/rate_limited. Reuse the same eventId and canonical JSON payload for durable retries; exact replay returns the original decision with replayed=true even after rules or budgets change. Reusing the ID with a changed payload returns 409. JSON property order does not matter; every field value, including timestamp text and metadata presence, does. Rejected decisions cannot later become accepted by replay. No production wallet is credited.
/api/game-sdk/v2/eventsAuthentication
Game server secretSecret game server credential. Keep it on a trusted server; never ship it in Unity, a browser, mobile binaries or public repositories. Public keys are rejected for writes. Revoked secrets are rejected.
# Illustrative request only. Replace IDs/tokens; events need a current occurredAt.
# Native examples require an already admitted native session/device permit.
curl --fail-with-body --max-time 15 -X POST \
"https://api.ggbucks.com/api/game-sdk/v2/events" \
-H "Authorization: Bearer ${GGBUCKS_GAME_SECRET}" \
-H "Content-Type: application/json" \
--data '{"eventId":"11111111-1111-4111-8111-111111111111","playerId":"11111111-1111-4111-8111-111111111111","eventType":"level.completed","occurredAt":"2026-10-11T12:00:00.000Z","metadata":{"level":7,"serverVerified":true}}'Illustrative examples; replace placeholders. Trusted game server only. Keep the secret in its secret manager. Record the UUID, current timestamp, and exact body once in a durable outbox before delivery.
Request body
{
"eventId": "11111111-1111-4111-8111-111111111111",
"eventType": "level.completed",
"metadata": {
"level": 7,
"serverVerified": true
},
"occurredAt": "2026-10-11T12:00:00.000Z",
"playerId": "11111111-1111-4111-8111-111111111111"
}eventIdstring · uuidrequired- Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
eventTypestringrequired- Up to 64 characters
- Pattern: ^[a-z][a-z0-9_.-]{0,63}$
metadataobjectoptionalJSON object only; canonical UTF-8 encoding is limited to 4,096 bytes, nesting depth 6, 100 items per array and 100 entries per object. Finite JSON values and valid Unicode without NUL are required. Metadata is included in immutable replay hashing.
- Up to 100 object entries
occurredAtstring · date-timerequired- Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
playerIdstring · uuidrequired- Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
Unknown fields are rejected.
Responses
200Immutable accepted or rejected sandbox decision. Inspect data.status; HTTP 200 does not imply a reward.
application/json
{
"data": {
"createdAt": "2026-10-11T12:00:00.000Z",
"eventId": "11111111-1111-4111-8111-111111111111",
"eventType": "level.completed",
"gameId": "11111111-1111-4111-8111-111111111111",
"id": "11111111-1111-4111-8111-111111111111",
"mode": "sandbox",
"occurredAt": "2026-10-11T12:00:00.000Z",
"organizationId": "11111111-1111-4111-8111-111111111111",
"playerId": "11111111-1111-4111-8111-111111111111",
"reason": null,
"replayed": false,
"rewardGgbucks": 100,
"status": "accepted"
}
}dataobjectrequired- Unknown fields are rejected
Show nested fields
createdAtstring · date-timerequiredeventIdstring · uuidrequiredeventTypestringrequired- Up to 64 characters
- Pattern: ^[a-z][a-z0-9_.-]{0,63}$
gameIdstring · uuidrequiredidstring · uuidrequiredmode"sandbox"requiredoccurredAtstring · date-timerequiredorganizationIdstring · uuidrequiredplayerIdstring · uuidrequiredreason"daily_player_cap" | "game_budget_exhausted" | "game_paused" | "game_payout_ceiling" | "player_not_linked" | "project_budget_exhausted" | "project_payout_ceiling" | "rate_limited" | "timestamp_out_of_window" | "unknown_or_inactive_rule" | "user_unavailable" | nullrequiredShow nested fields
Accepted shape 1
"daily_player_cap" | "game_budget_exhausted" | "game_paused" | "game_payout_ceiling" | "player_not_linked" | "project_budget_exhausted" | "project_payout_ceiling" | "rate_limited" | "timestamp_out_of_window" | "unknown_or_inactive_rule" | "user_unavailable"Accepted shape 2
nullreplayedbooleanrequiredrewardGgbucksintegerrequiredInteger sandbox TEST ggbucks. 1,000 units represent one test dollar.
- Minimum 0
- Maximum 1,000,000,000,000
status"accepted" | "rejected"requiredUnknown fields are rejected.
Unknown fields are rejected.
400Invalid request or allocation/cap constraint.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
401Missing or invalid credential/token.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
403Admission or organization permission denied.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
404Scoped resource not found.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
409Replay conflict, expired link or incompatible resource state.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
413JSON body exceeds 16,384 UTF-8 bytes.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
415Content-Type must be application/json.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.
503Platform disabled or admission/database dependency temporarily unavailable; no successful mutation is implied.
application/json
errorobjectrequired- Unknown fields are rejected
Show nested fields
code"AUTH_UNAVAILABLE" | "DEVELOPER_ACCESS_UNAVAILABLE" | "DEVELOPER_INVITATION_REQUIRED" | "EMAIL_VERIFICATION_REQUIRED" | "INVALID_CONTENT_TYPE" | "INVALID_CURSOR" | "INVALID_PLAYER" | "INVALID_PUBLIC_KEY" | "INVALID_RECORD_QUERY" | "INVALID_REQUEST" | "INVALID_SESSION_ORIGIN" | "PAYLOAD_TOO_LARGE" | "PLATFORM_DISABLED" | "PLATFORM_UNAVAILABLE" | "UNAUTHORIZED" | "already_linked" | "conflict" | "event_conflict" | "forbidden" | "game_limit" | "game_paused" | "insufficient_funds" | "invalid_action" | "invalid_event" | "invalid_key" | "invalid_link" | "invalid_metadata" | "invalid_player" | "limit_exceeded" | "link_disabled" | "not_found" | "owner_immutable" | "project_limit" | "retry_later" | "secret_key_required" | "unauthorized" | "unlimited_funding" | "user_unavailable"requiredmessagestringrequiredUnknown fields are rejected.
Unknown fields are rejected.