Developer portal

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.

POST/api/game-sdk/v2/events

Authentication

Game server secret

Secret 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}$
metadataobjectoptional

JSON 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-timerequired
eventIdstring · uuidrequired
eventTypestringrequired
  • Up to 64 characters
  • Pattern: ^[a-z][a-z0-9_.-]{0,63}$
gameIdstring · uuidrequired
idstring · uuidrequired
mode"sandbox"required
occurredAtstring · date-timerequired
organizationIdstring · uuidrequired
playerIdstring · uuidrequired
reason"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" | nullrequired
Show 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

null
replayedbooleanrequired
rewardGgbucksintegerrequired

Integer sandbox TEST ggbucks. 1,000 units represent one test dollar.

  • Minimum 0
  • Maximum 1,000,000,000,000
status"accepted" | "rejected"required

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown 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"required
messagestringrequired

Unknown fields are rejected.

Unknown fields are rejected.