{
  "components": {
    "schemas": {
      "ActivityBatchAccepted": {
        "description": "The batch as stored. A replay returns the original batch, including its current `state`.",
        "properties": {
          "batch_id": {
            "description": "Your `batch_id`.",
            "type": "string"
          },
          "received_at": {
            "format": "date-time",
            "type": "string"
          },
          "received_events": {
            "description": "Number of events received in the batch.",
            "type": "integer"
          },
          "state": {
            "description": "Processing state: `accepted`, then `processing`, then `processed` (or `processed_with_errors`).",
            "type": "string"
          }
        },
        "required": [
          "batch_id",
          "state",
          "received_events",
          "received_at"
        ],
        "type": "object"
      },
      "ActivityBatchRequest": {
        "properties": {
          "batch_id": {
            "description": "Your id for the batch, unique per integration. Re-sending it with the same events returns the existing batch; different events are `409 idempotency_conflict`.",
            "minLength": 1,
            "type": "string"
          },
          "events": {
            "items": {
              "$ref": "#/components/schemas/ActivityEvent"
            },
            "minItems": 1,
            "type": "array"
          },
          "schema_version": {
            "description": "Defaults to `1.0`.",
            "type": "string"
          }
        },
        "required": [
          "batch_id",
          "events"
        ],
        "type": "object"
      },
      "ActivityBatchStatus": {
        "properties": {
          "batch_id": {
            "description": "Your `batch_id`.",
            "type": "string"
          },
          "completed_at": {
            "description": "When processing finished; `null` until then.",
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "received_at": {
            "format": "date-time",
            "type": "string"
          },
          "received_events": {
            "description": "Number of events received in the batch.",
            "type": "integer"
          },
          "state": {
            "description": "Processing state: `accepted`, `processing`, `processed` or `processed_with_errors`.",
            "type": "string"
          }
        },
        "required": [
          "batch_id",
          "state",
          "received_events",
          "received_at",
          "completed_at"
        ],
        "type": "object"
      },
      "ActivityEvent": {
        "description": "One gameplay event. The request is rejected (`400`) if any event lacks `event_id`, `player_id` or `type`, has a `player_id` that is not a provider alias, or has a malformed `market`. Events that pass those checks are accepted and attributed asynchronously; events that cannot be attributed (alias unknown or not linked at `occurred_at`, unsupported `type`, non-EUR currency, market not licensed for the integration) are dropped during processing.",
        "properties": {
          "bet": {
            "description": "Stake as a decimal string, in `currency`.",
            "type": "string"
          },
          "currency": {
            "description": "Defaults to `EUR`; any other currency is dropped during processing.",
            "type": "string"
          },
          "event_id": {
            "description": "Your id for the event, unique per integration (at most 128 characters are stored). Re-send a failed batch under the same `batch_id` rather than resending its events in a new batch.",
            "minLength": 1,
            "type": "string"
          },
          "game_ref": {
            "description": "Your game identifier.",
            "type": "string"
          },
          "market": {
            "description": "Two uppercase letters. Optional when the integration is licensed for a single market (that market is used).",
            "pattern": "^[A-Z]{2}$",
            "type": "string"
          },
          "occurred_at": {
            "description": "When the round settled (ISO 8601, UTC). Used to check the player was linked at that moment.",
            "format": "date-time",
            "type": "string"
          },
          "player_id": {
            "description": "The provider-scoped player alias PlayerPal issued to your integration (`pp_plr_prv_…`). Never a player name, email or your own account id.",
            "pattern": "^pp_plr_prv_",
            "type": "string"
          },
          "round_ref": {
            "description": "Your round identifier.",
            "type": "string"
          },
          "type": {
            "description": "Event type. Only `round_settled` is processed today; other types are accepted but dropped during processing.",
            "minLength": 1,
            "type": "string"
          },
          "win": {
            "description": "Win as a decimal string, in `currency`.",
            "type": "string"
          }
        },
        "required": [
          "event_id",
          "player_id",
          "type"
        ],
        "type": "object"
      },
      "ActivityUploadComplete": {
        "properties": {
          "batch_id": {
            "description": "Your id for the batch the file becomes, unique per integration (same rules as `POST /v1/activity-batches`).",
            "minLength": 1,
            "type": "string"
          },
          "checksum": {
            "description": "SHA-256 of the exact bytes you uploaded, as 64 hex characters. A `sha256:` prefix and upper case are accepted. A mismatch is `400 checksum_mismatch`.",
            "type": "string"
          },
          "operator_id": {
            "description": "Accepted and ignored; the audience comes from `x-integration-id`.",
            "type": "string"
          },
          "row_count": {
            "description": "Optional. If present, must equal the number of events parsed from the file (`400 row_count_mismatch`).",
            "type": "number"
          },
          "schema_version": {
            "description": "Defaults to `1.0`.",
            "type": "string"
          }
        },
        "required": [
          "batch_id",
          "checksum"
        ],
        "type": "object"
      },
      "ActivityUploadRequest": {
        "properties": {
          "content_length": {
            "description": "Exact size of the file in bytes. Must not exceed the upload limit (64 MiB unless configured otherwise), otherwise `400 object_too_large`.",
            "minimum": 1,
            "type": "integer"
          },
          "content_type": {
            "description": "Format of the file you will upload. NDJSON (one event per line), JSON (an array of events, `{\"events\": [...]}` or a single event), CSV (header row with `event_id` recommended), or gzip of any of these. Parameters after `;` are ignored; case-insensitive.",
            "enum": [
              "application/x-ndjson",
              "application/json",
              "application/gzip",
              "application/x-gzip",
              "text/csv",
              "text/plain"
            ],
            "type": "string"
          },
          "operator_id": {
            "description": "Accepted and ignored; the audience comes from `x-integration-id`.",
            "type": "string"
          }
        },
        "required": [
          "content_type",
          "content_length"
        ],
        "type": "object"
      },
      "ActivityUploadTicket": {
        "properties": {
          "expires_at": {
            "description": "The upload URL and the upload expire at this time (15 minutes by default). Completing an expired, uncompleted upload is `400 upload_expired`.",
            "format": "date-time",
            "type": "string"
          },
          "required_headers": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Headers that must be sent unchanged with the `PUT`.",
            "type": "object"
          },
          "upload_id": {
            "description": "Id to pass to the complete call.",
            "type": "string"
          },
          "upload_url": {
            "description": "Presigned URL: `PUT` the file bytes here, without PlayerPal credentials.",
            "type": "string"
          }
        },
        "required": [
          "upload_id",
          "upload_url",
          "expires_at",
          "required_headers"
        ],
        "type": "object"
      },
      "AliasStatus": {
        "properties": {
          "status": {
            "description": "`revoked` once the player unlinked your audience or deleted their account; stop sending data for that alias.",
            "enum": [
              "active",
              "revoked"
            ],
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "type": "object"
      },
      "AttributionRecord": {
        "description": "Affiliate attribution for a player (`playerpal.affiliate.attribution.v1`). In v1 only operators may send it. Upserted by affiliate and player.",
        "properties": {
          "affiliate_ref": {
            "description": "Affiliate party public id; unknown affiliates are rejected with `affiliate_ref_unknown`.",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "attributed_at": {
            "oneOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "attribution_source": {
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "attribution_status": {
            "enum": [
              "CLAIMED",
              "OBSERVED",
              "VERIFIED"
            ],
            "type": "string"
          },
          "campaign_ref": {
            "oneOf": [
              {
                "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "click_ref": {
            "oneOf": [
              {
                "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "player_ref": {
            "description": "The operator-scoped player alias PlayerPal issued to you (`pp_plr_opr_…`).",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          }
        },
        "required": [
          "player_ref",
          "affiliate_ref",
          "attribution_status",
          "attribution_source"
        ],
        "type": "object"
      },
      "Error": {
        "description": "Error body returned for every 4xx/5xx raised by the API. `message` carries a stable, machine-readable snake_case code (for example `batch_not_found`); branch on it rather than on the HTTP status alone. `error` is the HTTP reason phrase. Two exceptions: malformed JSON bodies return the JSON parser's message, and unexpected server errors return `{\"statusCode\": 500, \"message\": \"Internal server error\"}`; neither includes `error`.",
        "example": {
          "error": "Not Found",
          "message": "batch_not_found",
          "statusCode": 404
        },
        "properties": {
          "error": {
            "description": "HTTP reason phrase.",
            "example": "Not Found",
            "type": "string"
          },
          "message": {
            "description": "Machine-readable error code.",
            "example": "batch_not_found",
            "type": "string"
          },
          "statusCode": {
            "description": "HTTP status code, repeated in the body.",
            "example": 404,
            "type": "integer"
          }
        },
        "required": [
          "statusCode",
          "message"
        ],
        "type": "object"
      },
      "GameCatalogueRecord": {
        "description": "One game in your catalogue (`playerpal.provider.game_catalogue.v1`), upserted by `game_ref`.",
        "properties": {
          "active": {
            "description": "Anything other than false is treated as true.",
            "type": "boolean"
          },
          "category": {
            "description": "Case-insensitive; defaults to OTHER.",
            "enum": [
              "SLOTS",
              "LIVE",
              "TABLE",
              "CRASH",
              "INSTANT",
              "OTHER"
            ],
            "type": "string"
          },
          "game_ref": {
            "description": "Your game identifier.",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "name": {
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "release_date": {
            "oneOf": [
              {
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "rtp_percent": {
            "oneOf": [
              {
                "exclusiveMinimum": 0,
                "maximum": 100,
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "volatility": {
            "oneOf": [
              {
                "description": "Case-insensitive.",
                "enum": [
                  "LOW",
                  "MEDIUM",
                  "HIGH",
                  "VERY_HIGH"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "game_ref",
          "name"
        ],
        "type": "object"
      },
      "IngestEnvelope": {
        "description": "Batch envelope. The envelope is validated first: any envelope problem rejects the whole request with `400` and the code as `message`. Records are then validated one by one; an invalid record is listed in the receipt's `rejections` and never fails the rest of the batch. At most 10,000 records per batch.",
        "properties": {
          "batch_id": {
            "description": "Your id for this batch and its idempotency key, unique per party. Re-sending the same `batch_id` with identical `schema` and `records` returns the stored receipt; different content is `409 idempotency_conflict`.",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "generated_at": {
            "description": "When you produced the batch (ISO 8601, UTC).",
            "format": "date-time",
            "type": "string"
          },
          "integration_id": {
            "description": "Optional integration public id, stored with the batch for provenance.",
            "type": [
              "string",
              "null"
            ]
          },
          "period_end": {
            "description": "End of the reporting period (ISO 8601, UTC). Must be after `period_start`.",
            "format": "date-time",
            "type": "string"
          },
          "period_start": {
            "description": "Start of the reporting period (ISO 8601, UTC).",
            "format": "date-time",
            "type": "string"
          },
          "records": {
            "description": "Record shape depends on `schema`.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/PlayerGameDailyRecord"
                },
                {
                  "$ref": "#/components/schemas/GameCatalogueRecord"
                },
                {
                  "$ref": "#/components/schemas/PlayerCommercialDailyRecord"
                },
                {
                  "$ref": "#/components/schemas/AttributionRecord"
                }
              ]
            },
            "maxItems": 10000,
            "type": "array"
          },
          "schema": {
            "description": "Provider schemas require source_party GAME_PROVIDER and a PROVIDER party; operator and attribution schemas require OPERATOR.",
            "enum": [
              "playerpal.provider.player_game_daily.v1",
              "playerpal.provider.game_catalogue.v1",
              "playerpal.operator.player_commercial_daily.v1",
              "playerpal.affiliate.attribution.v1"
            ],
            "type": "string"
          },
          "schema_version": {
            "const": 1,
            "description": "Schema version; only `1` is accepted.",
            "type": "integer"
          },
          "source_id": {
            "description": "Your party public id. Must equal the authenticated party, otherwise `403 source_id_must_be_authenticated_party`.",
            "minLength": 1,
            "type": "string"
          },
          "source_party": {
            "description": "`GAME_PROVIDER` for provider schemas, `OPERATOR` for operator and attribution schemas.",
            "enum": [
              "GAME_PROVIDER",
              "OPERATOR"
            ],
            "type": "string"
          }
        },
        "required": [
          "schema",
          "schema_version",
          "batch_id",
          "source_party",
          "source_id",
          "period_start",
          "period_end",
          "generated_at",
          "records"
        ],
        "type": "object"
      },
      "IngestReceipt": {
        "description": "Result of a batch. `records_received` = `records_accepted` + `records_rejected`. `replayed` is `true` when the receipt was read back from an earlier submission (replay or receipt lookup).",
        "properties": {
          "batch_id": {
            "description": "The `batch_id` you sent.",
            "type": "string"
          },
          "received_at": {
            "description": "When PlayerPal first received the batch (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "records_accepted": {
            "description": "Records that passed validation and were stored.",
            "type": "integer"
          },
          "records_received": {
            "description": "Records in the batch.",
            "type": "integer"
          },
          "records_rejected": {
            "description": "Records that failed validation; see `rejections`.",
            "type": "integer"
          },
          "rejections": {
            "description": "Per-record rejections, capped at the first 500 (`records_rejected` holds the full count).",
            "items": {
              "properties": {
                "index": {
                  "description": "Index into `records`.",
                  "type": "integer"
                },
                "reason": {
                  "description": "Rejection code, e.g. `player_ref_unknown`, `date_outside_period`, `duplicate_in_batch`, `currency_unsupported` or a field-validation code.",
                  "type": "string"
                }
              },
              "required": [
                "index",
                "reason"
              ],
              "type": "object"
            },
            "maxItems": 500,
            "type": "array"
          },
          "replayed": {
            "description": "`true` when this receipt was read back from an earlier submission of the same batch, or fetched by ID.",
            "type": "boolean"
          },
          "schema": {
            "description": "The schema the batch was validated against.",
            "type": "string"
          }
        },
        "required": [
          "batch_id",
          "schema",
          "received_at",
          "records_received",
          "records_accepted",
          "records_rejected",
          "rejections",
          "replayed"
        ],
        "type": "object"
      },
      "KpiResult": {
        "additionalProperties": true,
        "description": "Analytics read result. Shape varies by endpoint; described loosely.",
        "type": "object"
      },
      "LinkIntentCreate": {
        "description": "Two flows. **Operator-led** (no `x-integration-id` header): send `operator_assertion` and `return_origin`, optionally `requested_provider_integrations`. **Provider-led** (`x-integration-id` set): send only `return_origin`; any of `operator_assertion`, `requested_provider_integrations`, `operator_id`, `integration_id` or an `x-operator-id` header is rejected with `400 scope_override_rejected`.",
        "properties": {
          "integration_id": {
            "description": "Not used; rejected on the provider-led flow.",
            "type": "string"
          },
          "operator_assertion": {
            "description": "Operator-led only. A JWT (ES256 or RS256) signed with a key from your registered JWKS: `iss` = your operator public id, `sub` = your pseudonymous account id for the player, a unique `jti`, and a lifetime of at most 5 minutes. Must not carry personal data claims (`email`, `name`, `given_name`, `family_name`, `phone`, `phone_number`); each `jti` can be used once.",
            "type": "string"
          },
          "operator_id": {
            "description": "Not used; rejected on the provider-led flow.",
            "type": "string"
          },
          "requested_provider_integrations": {
            "description": "Operator-led only. Integration public ids (`pp_int_…`) to link in the same flow; each must belong to your operator (`integration_not_authorized_for_operator`).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "return_origin": {
            "description": "Absolute `http(s)` origin the player returns to after linking, e.g. `https://casino.example.com`. No path, query or fragment.",
            "type": "string"
          }
        },
        "required": [
          "return_origin"
        ],
        "type": "object"
      },
      "LinkIntentCreated": {
        "properties": {
          "expires_at": {
            "description": "The intent expires 5 minutes after creation.",
            "format": "date-time",
            "type": "string"
          },
          "link_intent_id": {
            "description": "Public link intent id (`pp_lnk_…`).",
            "type": "string"
          },
          "link_url": {
            "description": "PlayerPal link page URL to send the player to. Contains a one-time code; do not log or share it.",
            "type": "string"
          }
        },
        "required": [
          "link_intent_id",
          "link_url",
          "expires_at"
        ],
        "type": "object"
      },
      "LinkResultExchange": {
        "properties": {
          "result_code": {
            "description": "The one-time result code PlayerPal handed back to your `return_origin` when the player finished linking.",
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "result_code"
        ],
        "type": "object"
      },
      "LinkResultOperator": {
        "description": "Operator exchange result (no `x-integration-id`).",
        "properties": {
          "connection_id": {
            "description": "Id of the completed link.",
            "type": "string"
          },
          "effective_from": {
            "description": "Time of the exchange.",
            "format": "date-time",
            "type": "string"
          },
          "player_id": {
            "description": "Your operator-scoped player alias (`pp_plr_opr_…`). Store it against your account.",
            "type": "string"
          },
          "provider_aliases": {
            "description": "Provider-scoped aliases minted for the requested provider integrations.",
            "items": {
              "properties": {
                "integration_id": {
                  "type": "string"
                },
                "player_id": {
                  "type": "string"
                }
              },
              "required": [
                "integration_id",
                "player_id"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "status": {
            "const": "active",
            "type": "string"
          }
        },
        "type": "object"
      },
      "LinkResultProvider": {
        "description": "Provider exchange result (`x-integration-id` set): only the alias for that integration.",
        "properties": {
          "effective_from": {
            "description": "Time of the exchange.",
            "format": "date-time",
            "type": "string"
          },
          "integration_id": {
            "description": "Your integration public id.",
            "type": "string"
          },
          "player_id": {
            "description": "Your provider-scoped player alias (`pp_plr_prv_…`). Use it as `player_id` in activity events and `player_ref` in ingest.",
            "type": "string"
          },
          "status": {
            "description": "Always `active`.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PlayerCommercialDailyRecord": {
        "description": "Commercial totals per player and UTC day (`playerpal.operator.player_commercial_daily.v1`). `date` must fall within the envelope period. Rows are upserted by player and date.",
        "properties": {
          "bonus_cost": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "description": "Only 'EUR' in v1 (case-insensitive).",
            "type": "string"
          },
          "date": {
            "description": "UTC day, `YYYY-MM-DD`.",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string"
          },
          "deposits_amount": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "deposits_count": {
            "oneOf": [
              {
                "maximum": 2147483647,
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "first_deposit": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "ggr": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places.",
                "oneOf": [
                  {
                    "pattern": "^-?\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "market": {
            "oneOf": [
              {
                "pattern": "^[A-Z]{2}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "ngr": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places.",
                "oneOf": [
                  {
                    "pattern": "^-?\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "player_ref": {
            "description": "The operator-scoped player alias PlayerPal issued to you (`pp_plr_opr_…`).",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "stake_amount": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "win_amount": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "withdrawals_amount": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "withdrawals_count": {
            "oneOf": [
              {
                "maximum": 2147483647,
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "date",
          "player_ref",
          "currency"
        ],
        "type": "object"
      },
      "PlayerGameDailyRecord": {
        "description": "One row per player, game and UTC day (`playerpal.provider.player_game_daily.v1`). `currency` is required when any money field is present; at least one of `sessions`, `rounds`, `active_seconds` or `total_bet` is required; `date` must fall within the envelope period. Rows are upserted by player, game and date, so a later batch can correct an earlier one.",
        "properties": {
          "active_seconds": {
            "oneOf": [
              {
                "maximum": 2147483647,
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "oneOf": [
              {
                "description": "Only 'EUR' in v1 (case-insensitive).",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "date": {
            "description": "UTC day, `YYYY-MM-DD`.",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string"
          },
          "game_ref": {
            "description": "Your game identifier, matching `game_ref` in the game catalogue.",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "jackpot_win": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "market": {
            "oneOf": [
              {
                "pattern": "^[A-Z]{2}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "operator_ref": {
            "oneOf": [
              {
                "description": "Operator party public id where the play happened. Must be an operator you are integrated with (`operator_ref_not_integrated`); defaults to the alias's integration operator.",
                "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "player_ref": {
            "description": "The provider-scoped player alias PlayerPal issued to your integration (`pp_plr_prv_…`). Unknown or revoked aliases are rejected with `player_ref_unknown`.",
            "pattern": "^[A-Za-z0-9_.:-]{1,128}$",
            "type": "string"
          },
          "rounds": {
            "oneOf": [
              {
                "maximum": 2147483647,
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "sessions": {
            "oneOf": [
              {
                "maximum": 2147483647,
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "total_bet": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "total_win": {
            "oneOf": [
              {
                "description": "Decimal amount, string preferred, at most 2 decimal places, not negative.",
                "oneOf": [
                  {
                    "pattern": "^\\d{1,15}(\\.\\d{1,2})?$",
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "date",
          "player_ref",
          "game_ref"
        ],
        "type": "object"
      },
      "PlayerLinkNotice": {
        "description": "Notice that a player alias issued to you was revoked.",
        "example": {
          "alias_type": "operator",
          "audience_id": "pp_opr_EXAMPLE0000",
          "player_alias": "pp_plr_opr_EXAMPLE0000000000000000",
          "status": "revoked"
        },
        "properties": {
          "alias_type": {
            "description": "`operator` for an operator alias (`pp_plr_opr_…`), `provider_operator` for a provider integration alias (`pp_plr_prv_…`).",
            "enum": [
              "operator",
              "provider_operator"
            ],
            "type": "string"
          },
          "audience_id": {
            "description": "Your operator or integration public id.",
            "type": "string"
          },
          "player_alias": {
            "description": "The revoked alias.",
            "type": "string"
          },
          "status": {
            "const": "revoked",
            "type": "string"
          }
        },
        "required": [
          "audience_id",
          "player_alias",
          "alias_type",
          "status"
        ],
        "type": "object"
      },
      "StudioAlias": {
        "description": "The same figures as the rollup for one player alias (no `accounts` field).",
        "properties": {
          "bet_eur": {
            "description": "Total stake on your games, in EUR.",
            "type": "number"
          },
          "bets": {
            "description": "Total stake on your games in the range.",
            "type": "number"
          },
          "from": {
            "description": "Echo of the requested range start.",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string"
          },
          "rounds_elsewhere": {
            "description": "Rounds the same players played on other studios' games.",
            "type": "number"
          },
          "rounds_on_you": {
            "description": "Rounds played on your games.",
            "type": "number"
          },
          "share_of_their_slot_turnover": {
            "description": "Your share (0–1) of these players' total slot stake across PlayerPal; `0` when they have no stake.",
            "type": "number"
          },
          "to": {
            "description": "Echo of the requested range end.",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string"
          },
          "wins": {
            "description": "Total wins paid on your games in the range.",
            "type": "number"
          }
        },
        "required": [
          "from",
          "to",
          "bets",
          "wins",
          "bet_eur",
          "share_of_their_slot_turnover",
          "rounds_on_you",
          "rounds_elsewhere"
        ],
        "type": "object"
      },
      "StudioRollup": {
        "description": "Aggregate across every linked player who played your games in the range. Returned only when at least the account floor (50 accounts) is reached; otherwise the call is `404 studio_cohort_suppressed`.",
        "properties": {
          "accounts": {
            "description": "Number of player accounts in the aggregate.",
            "type": "number"
          },
          "bet_eur": {
            "description": "Total stake on your games, in EUR.",
            "type": "number"
          },
          "bets": {
            "description": "Total stake on your games in the range.",
            "type": "number"
          },
          "from": {
            "description": "Echo of the requested range start.",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string"
          },
          "rounds_elsewhere": {
            "description": "Rounds the same players played on other studios' games.",
            "type": "number"
          },
          "rounds_on_you": {
            "description": "Rounds played on your games.",
            "type": "number"
          },
          "share_of_their_slot_turnover": {
            "description": "Your share (0–1) of these players' total slot stake across PlayerPal; `0` when they have no stake.",
            "type": "number"
          },
          "to": {
            "description": "Echo of the requested range end.",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string"
          },
          "wins": {
            "description": "Total wins paid on your games in the range.",
            "type": "number"
          }
        },
        "required": [
          "from",
          "to",
          "bets",
          "wins",
          "bet_eur",
          "share_of_their_slot_turnover",
          "rounds_on_you",
          "rounds_elsewhere",
          "accounts"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "PartnerHmac": {
        "description": "PP-HMAC-SHA256 request signing (see docs/api/hmac-signing.md). Value: `PP-HMAC-SHA256 keyId=pp_kid_XXXX, signature=<base64url>` where signature = base64url(HMAC-SHA256(secret, METHOD\\nPATH\\nSORTED_QUERY\\nhex(sha256(body))\\nTIMESTAMP\\nNONCE)). Must be sent together with X-PP-Timestamp and X-PP-Nonce.",
        "in": "header",
        "name": "Authorization",
        "type": "apiKey"
      },
      "PartnerHmacNonce": {
        "description": "Single-use nonce, 16-128 characters [A-Za-z0-9_-]; a replayed nonce is rejected. Part of PP-HMAC-SHA256 (see docs/api/hmac-signing.md).",
        "in": "header",
        "name": "X-PP-Nonce",
        "type": "apiKey"
      },
      "PartnerHmacTimestamp": {
        "description": "Unix time in seconds (9-11 digits), within 300 seconds of server time. Part of PP-HMAC-SHA256 (see docs/api/hmac-signing.md).",
        "in": "header",
        "name": "X-PP-Timestamp",
        "type": "apiKey"
      },
      "PartnerOAuthBearer": {
        "bearerFormat": "JWT",
        "description": "OAuth 2.0 client-credentials access token (JWT) from the configured issuer. The API verifies signature (issuer JWKS), iss, aud and exp, then maps client_id (or sub) to a registered partner client. The token endpoint belongs to the issuer, not this API.",
        "scheme": "bearer",
        "type": "http"
      },
      "SharedApiKey": {
        "description": "Shared machine API key (phase 1). Also accepted as `Authorization: Bearer <key>`.",
        "in": "header",
        "name": "x-api-key",
        "type": "apiKey"
      },
      "SharedApiKeyBearer": {
        "description": "Shared machine API key presented as a bearer token (same key as x-api-key).",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "contact": {},
    "description": "The PlayerPal Partner API lets operators, game providers and affiliates send activity and facts to PlayerPal, link players without exchanging personal data, and read analytics about their own players.\n\nNew here? Start with the [Quickstart](/docs/developers/quickstart).\n\n## Authentication\n\nPartner routes accept one of:\n\n- **PP-HMAC-SHA256 request signing**: `Authorization: PP-HMAC-SHA256 keyId=pp_kid_XXXX, signature=…` together with `X-PP-Timestamp` (within 300 seconds of server time) and a single-use `X-PP-Nonce`.\n- **OAuth 2.0 client-credentials tokens**: `Authorization: Bearer <token>` issued for your partner client.\n\nSome activity and linking routes currently use a shared integration key in `x-api-key` together with `x-integration-id`; per-partner credentials for those routes are in development. Each operation lists the methods it accepts. Details: [Authentication](/docs/developers/authentication).\n\nCredentials carry scopes: `ingest.write` to send facts, `kpis.read` to read KPIs, `studio.read` for provider studio analytics.\n\n## Conventions\n\n- **Versioning**: every route is under `/v1`.\n- **Asynchronous and idempotent**: writes are accepted for processing and return a receipt. Re-sending the same batch ID (or idempotency key) returns the original result instead of creating a duplicate; reusing it with different content is rejected with `409`. See [Idempotency and errors](/docs/developers/idempotency-and-errors).\n- **No personal data**: players are identified only by the pairwise aliases PlayerPal issues to you. Player references that are not valid aliases, such as email addresses, are rejected.\n- **Dates and money**: dates are UTC calendar days (`YYYY-MM-DD`); amounts are in EUR.\n- **Privacy floors**: analytics cells below the account floor, and comparisons below the peer thresholds, are suppressed rather than returned. See [Privacy thresholds](/docs/analytics/privacy-thresholds).\n\n## Errors\n\nErrors use a JSON body with `statusCode`, a machine-readable `message` code and an `error` label. Each operation lists the codes it can return.",
    "title": "PlayerPal Partner API",
    "version": "v1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/activity-batches": {
      "post": {
        "description": "Accepted for asynchronous processing. Resubmitting the same batch_id (or idempotency key) with the same events returns the existing batch.",
        "operationId": "activitySubmitBatch",
        "parameters": [
          {
            "description": "Optional idempotency key; same key with a different payload is a conflict.",
            "in": "header",
            "name": "idempotency-key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Integration public id; the batch audience comes only from this header.",
            "in": "header",
            "name": "x-integration-id",
            "required": true,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityBatchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityBatchAccepted"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Validation error code, e.g. integration_id_required, events_required, player_id_must_be_provider_alias, integration_not_found."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "idempotency_conflict"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Submit an activity event batch",
        "tags": [
          "Activity"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/activity-batches/{batchId}": {
      "get": {
        "description": "Returns the processing status of an activity batch you submitted, with event counts. Poll it after submitting, with backoff; processing is asynchronous.",
        "operationId": "activityGetBatch",
        "parameters": [
          {
            "in": "path",
            "name": "batchId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Integration public id; the batch audience comes only from this header.",
            "in": "header",
            "name": "x-integration-id",
            "required": true,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityBatchStatus"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "integration_id_required"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "batch_not_found"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Get activity batch status",
        "tags": [
          "Activity"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/activity-uploads": {
      "post": {
        "description": "Starts a bulk activity upload. Returns a short-lived pre-signed URL to upload one file to, then call **Complete an upload**. Use uploads instead of JSON batches for large volumes or backfills.",
        "operationId": "activityRequestUpload",
        "parameters": [
          {
            "description": "Integration public id; the batch audience comes only from this header.",
            "in": "header",
            "name": "x-integration-id",
            "required": true,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityUploadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityUploadTicket"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Error code, e.g. content_type_unsupported, content_length_required, object_too_large, object_storage_not_configured."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Request a presigned upload for a bulk activity file",
        "tags": [
          "Activity"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/activity-uploads/{uploadId}/complete": {
      "post": {
        "description": "Tells PlayerPal that the file for an upload is in place, so it can be parsed and processed as an activity batch. Safe to retry: completing an upload twice returns the same batch.\n\nAlso routed as POST /v1/activity-uploads/{uploadId}:complete.",
        "operationId": "activityCompleteUpload",
        "parameters": [
          {
            "in": "path",
            "name": "uploadId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional idempotency key; same key with a different payload is a conflict.",
            "in": "header",
            "name": "idempotency-key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Integration public id; the batch audience comes only from this header.",
            "in": "header",
            "name": "x-integration-id",
            "required": true,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityUploadComplete"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityBatchAccepted"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Error code, e.g. checksum_required, checksum_mismatch, upload_expired, upload_incomplete, row_count_mismatch."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "upload_not_found or batch_not_found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "idempotency_conflict"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Complete an upload and submit its events as a batch",
        "tags": [
          "Activity"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/activity-uploads/{uploadId}:complete": {
      "post": {
        "description": "Same operation as `POST /v1/activity-uploads/{uploadId}/complete`, in the `:complete` custom-method form. Use either.\n\nAlso routed as POST /v1/activity-uploads/{uploadId}:complete.",
        "operationId": "activityCompleteUploadAlias",
        "parameters": [
          {
            "in": "path",
            "name": "uploadId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional idempotency key; same key with a different payload is a conflict.",
            "in": "header",
            "name": "idempotency-key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Integration public id; the batch audience comes only from this header.",
            "in": "header",
            "name": "x-integration-id",
            "required": true,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityUploadComplete"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityBatchAccepted"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Error code, e.g. checksum_required, checksum_mismatch, upload_expired, upload_incomplete, row_count_mismatch."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "upload_not_found or batch_not_found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "idempotency_conflict"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Complete an upload and submit its events as a batch",
        "tags": [
          "Activity"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/aliases/{playerAlias}": {
      "get": {
        "description": "Returns whether a player alias issued to you is still linked or has been revoked (for example after the player unlinked or deleted their Account). An alias that was not issued to you gets the same response as an unknown alias. Use it to reconcile after an unlink notice.",
        "operationId": "getAliasStatus",
        "parameters": [
          {
            "in": "path",
            "name": "playerAlias",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Operator public id (operator-led path).",
            "in": "header",
            "name": "x-operator-id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Integration public id (audience). Either this or x-operator-id is required.",
            "in": "header",
            "name": "x-integration-id",
            "required": false,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AliasStatus"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "player_alias_required or audience_required"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "alias_not_found, integration_not_found or party_not_found"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Status of a player alias issued to your audience",
        "tags": [
          "Linking"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/analytics/studio": {
      "get": {
        "description": "Game-provider rollup across the accounts linked to you: distinct accounts and activity totals for the period. Accounts are counted distinctly and results under the account floor are suppressed.",
        "operationId": "studioRollup",
        "parameters": [
          {
            "description": "Accepted and ignored.",
            "in": "query",
            "name": "operator_id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD), not before from.",
            "in": "query",
            "name": "to",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Legacy shared-key access only: your provider party public id (starts with `pp_prv_`). Ignored when the request authenticates with HMAC or OAuth; the party then comes from the credential.",
            "in": "header",
            "name": "x-party-id",
            "required": false,
            "schema": {
              "example": "pp_prv_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioRollup"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "date_range_required, date_range_invalid or provider_party_required"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing` (credential lacks `studio.read`) or `provider_party_required` (the authenticated party is not a game provider)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "provider_not_found or studio_cohort_suppressed"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          },
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Provider studio rollup across your accounts",
        "tags": [
          "Studio analytics"
        ],
        "x-audience": "partner",
        "x-partner-scope": "studio.read"
      }
    },
    "/v1/analytics/studio/aliases/{alias}": {
      "get": {
        "description": "Figures for one player alias issued to you, for your own games. Returns numbers only, never identity attributes, and nothing for aliases issued to other audiences.",
        "operationId": "studioByAlias",
        "parameters": [
          {
            "description": "Your provider-scoped player alias.",
            "in": "path",
            "name": "alias",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Accepted and ignored.",
            "in": "query",
            "name": "operator_id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD), not before from.",
            "in": "query",
            "name": "to",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Legacy shared-key access only: your provider party public id (starts with `pp_prv_`). Ignored when the request authenticates with HMAC or OAuth; the party then comes from the credential.",
            "in": "header",
            "name": "x-party-id",
            "required": false,
            "schema": {
              "example": "pp_prv_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioAlias"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "date_range_required, date_range_invalid or provider_party_required"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing` (credential lacks `studio.read`) or `provider_party_required` (the authenticated party is not a game provider)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "provider_not_found or alias_not_found"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          },
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Provider studio figures for one player alias",
        "tags": [
          "Studio analytics"
        ],
        "x-audience": "partner",
        "x-partner-scope": "studio.read"
      }
    },
    "/v1/ingest": {
      "post": {
        "description": "Batch-first, idempotent fact ingestion. Records are validated individually; invalid records are listed in the receipt without failing the batch. Re-sending the same batch_id with the same records replays the receipt.",
        "operationId": "ingestSubmit",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestEnvelope"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestReceipt"
                }
              }
            },
            "description": "Batch receipt."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Envelope invalid (message is the envelope error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "source_id_must_be_authenticated_party or schema_not_allowed_for_party.\n\n`partner_scope_missing`: the credential does not carry the `ingest.write` scope."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "idempotency_conflict: same batch_id, different payload."
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Submit a fact batch",
        "tags": [
          "Ingest"
        ],
        "x-audience": "partner",
        "x-partner-scope": "ingest.write"
      }
    },
    "/v1/ingest/batches/{batchId}": {
      "get": {
        "description": "Returns the receipt for a fact batch: accepted and rejected record counts and the rejection reasons for individual records. Receipts are stable, so you can fetch one as often as you need.",
        "operationId": "ingestReceipt",
        "parameters": [
          {
            "description": "The partner batch_id from the envelope.",
            "in": "path",
            "name": "batchId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestReceipt"
                }
              }
            },
            "description": "Stored receipt (replayed=true)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `ingest.write` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "batch_not_found"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Get a batch receipt",
        "tags": [
          "Ingest"
        ],
        "x-audience": "partner",
        "x-partner-scope": "ingest.write"
      }
    },
    "/v1/kpis/benchmarks": {
      "get": {
        "description": "Anonymous benchmarks against peers of your party type (for example other operators). Published only when enough distinct peers and accounts contribute and no single peer dominates.",
        "operationId": "kpisBenchmarks",
        "parameters": [
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Time grain.",
            "in": "query",
            "name": "grain",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comparison period.",
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "KPI id from the catalogue.",
            "in": "query",
            "name": "kpi",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Anonymous peers of your party type",
        "tags": [
          "Comparison"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/breakdown": {
      "get": {
        "description": "Returns one KPI split by a dimension (market, game or partner) for a date range. Rows under the account floor are withheld rather than returned.",
        "operationId": "kpisBreakdown",
        "parameters": [
          {
            "description": "Breakdown dimension.",
            "in": "query",
            "name": "dimension",
            "required": false,
            "schema": {
              "enum": [
                "market",
                "game",
                "partner"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "KPI id from the catalogue.",
            "in": "query",
            "name": "kpi",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "One KPI by market, game or partner",
        "tags": [
          "KPIs"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/catalogue": {
      "get": {
        "description": "Lists the KPIs available to your party type, with their IDs, names and units. Use the IDs with **Get one KPI** and **Break down a KPI**.",
        "operationId": "kpisCatalogue",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "KPI catalogue for your party type",
        "tags": [
          "KPIs"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/cohorts/retention": {
      "get": {
        "description": "Monthly first-play cohorts with their retention, plus a pooled network retention curve for comparison. The range is given in months.",
        "operationId": "kpisCohortsRetention",
        "parameters": [
          {
            "description": "Last cohort month (YYYY-MM). At most 24 months from `from`; otherwise `month_range_too_long`.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "example": "2026-09",
              "type": "string"
            }
          },
          {
            "description": "First cohort month (YYYY-MM).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "example": "2026-01",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Monthly cohort retention with a pooled network curve",
        "tags": [
          "KPIs"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/compare": {
      "get": {
        "description": "Compares one KPI for your players with the rest of the PlayerPal network over closed periods. The network side is anonymous and suppressed when it falls below the peer, account or dominance thresholds.",
        "operationId": "kpisCompare",
        "parameters": [
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Time grain.",
            "in": "query",
            "name": "grain",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comparison period.",
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "KPI id from the catalogue.",
            "in": "query",
            "name": "kpi",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Your players vs the rest of the PlayerPal network",
        "tags": [
          "Comparison"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/compare/summary": {
      "get": {
        "description": "Every comparison KPI for your party type in one call, for a closed period: your quartile band against the network for each, suppressed comparisons marked, and a count of KPIs where you sit in the better half. With a market filter, KPIs not published for that market fall back to the network-wide comparison and say so.",
        "operationId": "kpisCompareSummary",
        "parameters": [
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Time grain.",
            "in": "query",
            "name": "grain",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comparison period.",
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "KPI id from the catalogue.",
            "in": "query",
            "name": "kpi",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Comparison summary across KPIs",
        "tags": [
          "Comparison"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/benchmark-history": {
      "get": {
        "description": "Twelve months of your comparisons against the network quartiles, for published segments only.",
        "operationId": "kpisExploreBenchmarkHistory",
        "parameters": [
          {
            "description": "Number of months.",
            "in": "query",
            "name": "months",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: your comparisons against network quartiles over time",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/comparison": {
      "get": {
        "description": "Your counterparts compared side by side: per-counterpart rows with their market mix and top games. Cells under the floor are withheld.",
        "operationId": "kpisExploreComparison",
        "parameters": [
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: comparison",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/dimension": {
      "get": {
        "description": "Ranked rows for one dimension (games, markets or counterparts) with derived metrics.",
        "operationId": "kpisExploreDimension",
        "parameters": [
          {
            "description": "Dimension to break down.",
            "in": "query",
            "name": "dim",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: one dimension",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/funnel": {
      "get": {
        "description": "The journey funnel for the most recent complete 30-day first-play cohort.",
        "operationId": "kpisExploreFunnel",
        "parameters": [
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: funnel",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/game": {
      "get": {
        "description": "One game: its catalogue entry and cross-game behaviour (what its players also play and where they came from). The account floor applies.",
        "operationId": "kpisExploreGame",
        "parameters": [
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: one game",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/options": {
      "get": {
        "description": "Values you can filter the explore views by: your games, markets and counterparts.",
        "operationId": "kpisExploreOptions",
        "parameters": [
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: filter options (games, markets, partners)",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/performance": {
      "get": {
        "description": "Engagement KPIs with per-period series compared with the previous period.",
        "operationId": "kpisExplorePerformance",
        "parameters": [
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: performance",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/players": {
      "get": {
        "description": "Player lifecycle KPIs, the mix of lifecycle states over time and movement between states.",
        "operationId": "kpisExplorePlayers",
        "parameters": [
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: players",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/retention": {
      "get": {
        "description": "Retention cohort matrix (D1 to D90) and your retention curve against the pooled network curve.",
        "operationId": "kpisExploreRetention",
        "parameters": [
          {
            "description": "Number of months.",
            "in": "query",
            "name": "months",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Time grain.",
            "in": "query",
            "name": "grain",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: retention cohorts",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/segments": {
      "get": {
        "description": "Your players grouped by engagement lifecycle, turnover tier and behaviour. Groups under the floor are withheld.",
        "operationId": "kpisExploreSegments",
        "parameters": [
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: segments",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/explore/summary": {
      "get": {
        "description": "Headline KPIs with sparklines (active, new and reactivated players, D7 retention, average session duration and game GGR) and the activity series against the previous period at the requested granularity.",
        "operationId": "kpisExploreSummary",
        "parameters": [
          {
            "description": "Time grain.",
            "in": "query",
            "name": "grain",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: counterpart (studio or operator).",
            "in": "query",
            "name": "partner",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter: game ref.",
            "in": "query",
            "name": "game",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Explore: summary",
        "tags": [
          "Explore"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/funnels/link": {
      "get": {
        "description": "The link-to-play funnel for your party over a date range, from link intents to linked players who play. The account floor applies to the first step.",
        "operationId": "kpisFunnelsLink",
        "parameters": [
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Link to play funnel for your party",
        "tags": [
          "KPIs"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/intelligence/ask": {
      "get": {
        "description": "Answers a question in plain language by routing it to one of a fixed set of analytics functions and returning that function's result. Questions outside the supported topics return a not-understood answer with suggestions.",
        "operationId": "kpisIntelligenceAsk",
        "parameters": [
          {
            "description": "Question text (max 300 characters used).",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Ask a question routed to a fixed analytics function",
        "tags": [
          "Insights"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/intelligence/insights": {
      "get": {
        "description": "Ranked insights for your party, each with an explanation and evidence, plus a short executive summary. Insights come from deterministic detectors over your analytics.",
        "operationId": "kpisIntelligenceInsights",
        "parameters": [
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Ranked, explainable insights and an executive summary",
        "tags": [
          "Insights"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/intelligence/insights/{id}": {
      "get": {
        "description": "One insight with its full evidence: the figures, comparison periods and the detector that produced it.",
        "operationId": "kpisIntelligenceInsight",
        "parameters": [
          {
            "description": "Insight id (16 lowercase hex characters).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "One insight with its evidence",
        "tags": [
          "Insights"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/intelligence/suggestions": {
      "get": {
        "description": "Example questions that Ask can answer for your party type.",
        "operationId": "kpisIntelligenceSuggestions",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Suggested questions for intelligence/ask",
        "tags": [
          "Insights"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/overview": {
      "get": {
        "description": "The partner overview: every KPI in the overview registry with its value, availability (`available`, `requires_feed`, `not_applicable` or `suppressed`), data source and freshness. Use it to see which KPIs your current feeds support.",
        "operationId": "kpisOverview",
        "parameters": [
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "Partner overview: every registry KPI with availability, source and freshness",
        "tags": [
          "KPIs"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/kpis/own": {
      "get": {
        "description": "Returns one KPI from the catalogue for your own players over a date range, optionally as a time series. Values under the account floor are suppressed.",
        "operationId": "kpisOwn",
        "parameters": [
          {
            "description": "Filter: market.",
            "in": "query",
            "name": "market",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Time grain.",
            "in": "query",
            "name": "grain",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD).",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (YYYY-MM-DD).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "KPI id from the catalogue.",
            "in": "query",
            "name": "kpi",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiResult"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid KPI request (message is the error code)."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authentication failed. `message` is one of: `partner_auth_required`, `invalid_signature`, `stale_timestamp`, `invalid_nonce`, `replayed_nonce`, `hmac_not_configured`, `oauth_not_configured`, `invalid_token`, `unknown_client`. See [Authentication](/docs/developers/authentication)."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`partner_scope_missing`: the credential does not carry the `kpis.read` scope."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A *_not_found error code."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "kpi_backend_not_configured"
          }
        },
        "security": [
          {
            "PartnerHmac": [],
            "PartnerHmacNonce": [],
            "PartnerHmacTimestamp": []
          },
          {
            "PartnerOAuthBearer": []
          }
        ],
        "summary": "One of your own KPIs over a period",
        "tags": [
          "KPIs"
        ],
        "x-audience": "partner",
        "x-partner-scope": "kpis.read"
      }
    },
    "/v1/link-intents": {
      "post": {
        "description": "Provider-led when x-integration-id is present (audience from the integration only); otherwise operator-led with a signed operator assertion.",
        "operationId": "createLinkIntent",
        "parameters": [
          {
            "description": "Operator public id (operator-led path).",
            "in": "header",
            "name": "x-operator-id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Integration public id; selects the provider-led flow.",
            "in": "header",
            "name": "x-integration-id",
            "required": false,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkIntentCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkIntentCreated"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Linking error code, e.g. return_origin_required, assertion_invalid, scope_override_rejected."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "party_not_found or integration_not_found"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Create a link intent",
        "tags": [
          "Linking"
        ],
        "x-audience": "partner"
      }
    },
    "/v1/link-results/exchange": {
      "post": {
        "description": "With x-integration-id returns only the matching provider alias; otherwise the operator result.",
        "operationId": "exchangeLinkResult",
        "parameters": [
          {
            "description": "Integration public id; selects the provider exchange.",
            "in": "header",
            "name": "x-integration-id",
            "required": false,
            "schema": {
              "example": "pp_int_EXAMPLE0000",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkResultExchange"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/LinkResultOperator"
                    },
                    {
                      "$ref": "#/components/schemas/LinkResultProvider"
                    }
                  ]
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Linking error code, e.g. result_code_required, provider_alias_missing."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`machine_auth_required`: the shared integration key is missing or wrong (send it as `x-api-key` or `Authorization: Bearer`)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "result_not_found or integration_not_found"
          }
        },
        "security": [
          {
            "SharedApiKey": []
          },
          {
            "SharedApiKeyBearer": []
          }
        ],
        "summary": "Exchange a one-time link result code for the player alias",
        "tags": [
          "Linking"
        ],
        "x-audience": "partner"
      }
    }
  },
  "tags": [
    {
      "description": "Send daily fact batches (game, commercial and attribution facts) and read their receipts. Batches are validated record by record and are idempotent on your batch ID. Guide: [Fact ingest](/docs/developers/fact-ingest).",
      "name": "Ingest"
    },
    {
      "description": "Send player activity (game rounds and related events) as JSON batches or bulk file uploads. Processing is asynchronous and idempotent. Guide: [Sending activity](/docs/developers/sending-activity).",
      "name": "Activity"
    },
    {
      "description": "Connect a player's PlayerPal Account to your platform and receive the pairwise alias issued to you. Guide: [Linking players](/docs/developers/linking-players).",
      "name": "Linking"
    },
    {
      "description": "Read your own KPIs: the catalogue, single KPIs over a period, breakdowns, cohorts, funnels and the partner overview. Scope is always the authenticated party. Definitions: [Metric definitions](/docs/analytics/metrics).",
      "name": "KPIs"
    },
    {
      "description": "Compare your players with the rest of the PlayerPal network, anonymously. Results below peer or account thresholds are suppressed. See [Privacy thresholds](/docs/analytics/privacy-thresholds).",
      "name": "Comparison"
    },
    {
      "description": "Ranked, explainable insights produced by deterministic detectors, and Ask, which routes a question to a fixed analytics function. No language model is involved. See [Insights](/docs/analytics/insights).",
      "name": "Insights"
    },
    {
      "description": "Detailed analytics views used by the partner portal: summaries, performance, games, segments, players, retention and funnels. Cells under the account floor are withheld.",
      "name": "Explore"
    },
    {
      "description": "Game-provider analytics across your linked accounts, and figures for a single player alias. Requires the `studio.read` scope.",
      "name": "Studio analytics"
    }
  ],
  "webhooks": {
    "player-link-notice": {
      "post": {
        "description": "In development. Sent when a player unlinks your audience: PlayerPal POSTs JSON to `/v1/player-link-notices` on the notice endpoint registered for your integration, authenticated with the shared integration key in `x-api-key` (no request signature yet). Respond with any 2xx; other responses count as a failed delivery. Delivery is best-effort, so reconcile with `GET /v1/aliases/{playerAlias}`. Delivery is currently limited to demo integrations. Guide: [Webhooks](/docs/developers/webhooks).",
        "operationId": "playerLinkNotice",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlayerLinkNotice"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Notice received."
          }
        },
        "security": [
          {
            "SharedApiKey": []
          }
        ],
        "summary": "Player link revoked notice",
        "tags": [
          "Linking"
        ],
        "x-audience": "partner"
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "Data in",
      "tags": [
        "Ingest",
        "Activity"
      ]
    },
    {
      "name": "Players",
      "tags": [
        "Linking"
      ]
    },
    {
      "name": "Analytics",
      "tags": [
        "KPIs",
        "Comparison",
        "Insights",
        "Explore",
        "Studio analytics"
      ]
    }
  ]
}
