Skip to main content
InternalMarkdown

Partner fact ingestion (POST /v1/ingest)

This implements the PlayerPal Data, Analytics & Ingestion Specification v0.1. The principle: partners send pseudonymous daily facts, and PlayerPal computes every KPI from them. Ingestion is batch-first; daily or periodic payloads are enough.

Auth: OAuth client credentials or PP-HMAC-SHA256 (hmac-signing.md) with scope ingest.write. source_id must be your own party ID, and the schema must match your party type.

Envelope (§4)​

{
"schema": "playerpal.provider.player_game_daily.v1",
"schema_version": 1,
"batch_id": "01JAXAMPLEBATCHID",
"source_party": "GAME_PROVIDER",
"source_id": "pp_prv_example",
"integration_id": "int_example_prod",
"period_start": "2026-10-12T00:00:00Z",
"period_end": "2026-10-13T00:00:00Z",
"generated_at": "2026-10-13T01:15:00Z",
"records": []
}

The response is a 202 receipt: { batch_id, schema, received_at, records_received, records_accepted, records_rejected, rejections: [{ index, reason }], replayed }. You can fetch it again from GET /v1/ingest/batches/:batchId.

  • Idempotency. Re-sending a batch_id with the same records replays the receipt. Different records under the same batch_id return 409 idempotency_conflict.
  • Corrections (§15). Send the corrected facts in a new batch. Records upsert by natural key, revision is incremented, and received_at is kept separately from the activity date.
  • Per-record validation. One bad record never rejects the whole batch. If a batch contains duplicates, the last record for each natural key is kept and the earlier ones are rejected as duplicate_in_batch.
  • Limits. At most 10,000 records per batch. Daily facts must fall within [period_start day, period_end).
  • Currency. v1 accepts EUR only, because the canonical currency policy is still open (§18).
  • Pseudonymous refs only. player_ref must be an alias PlayerPal issued to you: pp_plr_prv_… for studios through their integrations, pp_plr_opr_… for operators. Anything else is rejected as player_ref_unknown. Email-shaped and other direct identifiers fail validation.

v1 schemas (§19)​

SchemaSenderNatural keyNotes
playerpal.provider.player_game_daily.v1Studioprovider × player × game × daysessions, rounds, active_seconds, total_bet, total_win, jackpot_win. operator_ref (a pp_opr_… ID) must be an operator you're integrated with; if omitted, it is inferred from the alias's integration.
playerpal.provider.game_catalogue.v1Studioprovider × gamename, category (SLOTS/LIVE/TABLE/CRASH/INSTANT/OTHER), release_date, rtp_percent, volatility, active.
playerpal.operator.player_commercial_daily.v1Operatoroperator × player × dayDeposits, withdrawals, stake, win, ggr, bonus_cost, ngr (GGR and NGR may be negative), first_deposit.
playerpal.affiliate.attribution.v1Operator (v1)affiliate × playeraffiliate_ref (a pp_aff_… ID), campaign_ref, click_ref, attributed_at, attribution_status (CLAIMED/OBSERVED/VERIFIED), attribution_source. Only operators can send attribution in v1, as the authoritative source (§8).

Points, rewards, redemptions and missions are native to PlayerPal (§9), so partners don't send them.

Privacy​

Delete Account removes the player's fact rows. Reward redemptions are kept for loyalty accounting, but lose the link to the player.