# Get settlement results

Read the outcome of a settlement or void: the totals and each trader's prediction and payout or refund, one page at a time.

- Endpoint: `GET https://api.returning.ai/v1/match-predictions/{matchPredictionId}/results`
- Section: Gamification / Match predictions
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `matchPredictions` (Shown in the dashboard as "Match Prediction")
- Retries: Read-only; poll at the Retry-After interval
- Guide: hand-written
- Verified: code, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/gamification-match-predictions/get-settlement-results

## When to use this

- Poll after you settle or void a match until the work finishes.
- Reconcile the coins and XP each winner received against your own records.
- After a void, confirm which traders had their entry cost refunded.

**Instead:** Use [Get match prediction](https://docs.returning.ai/api-reference/gamification-match-predictions/get-match-prediction.md) instead when you only need the settlement totals.

**Availability:** api.returning.ai doesn't serve this route yet: requests return an empty `404`. Ask Returning.AI before you build on it.

**Branch on meta.code:** A settled match and a voided match both return `200`, with different fields. Check `meta.code` before you read `data`.

## Authentication

- Header: `Authorization: Bearer <API_KEY>`
- Permission: `matchPredictions`

Use a Community API key with `matchPredictions`, shown in the dashboard as Match Prediction, and keep it on your server. The key decides the community: you only see and change match predictions in that community, and an ID from another community returns `404`, the same as an unknown ID. Personal API keys are rejected with `403`.

## Behaviour

api.returning.ai doesn't serve this route yet: requests return an empty `404`. Ask Returning.AI before you build on it.

What you get depends on where the match is:

- Settling or voiding: `202` with `MATCH_PREDICTION_SETTLEMENT_IN_PROGRESS` or `MATCH_PREDICTION_VOID_IN_PROGRESS`, progress counts, and a `Retry-After` header of 5 seconds.
- Settled: `200` with `MATCH_PREDICTION_RESULTS_RETRIEVED`, the totals and each prediction.
- Voided: `200` with `MATCH_PREDICTION_VOID_COMPLETED`, refund totals and each prediction.
- Settlement or void failed: `409 MATCH_PREDICTION_SETTLEMENT_FAILED` or `409 MATCH_PREDICTION_VOID_FAILED`.
- Not settled or voided yet: `409 INVALID_LIFECYCLE_TRANSITION`.

This read changes nothing. `summary` always covers the whole match; filters and paging apply only to `participants`.

## Request

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `matchPredictionId` | `string` | Yes | The match prediction ID from Create match prediction or List match predictions. (`mp_` and 24 hex characters) |

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `winner` | `string` | No | Settled matches only. `true` keeps right-result predictions, exact or not; `false` keeps wrong results. (`true` or `false`) |
| `outcome` | `string` | No | Settled matches only. Keep one outcome. (`correct_result`, `exact_score` or `missed`) |
| `payoutStatus` | `string` | No | Keep predictions that were paid, or that were not. On a voided match, `not_applicable` keeps predictions with no entry cost. (`paid` or `not_applicable`) |
| `userId` | `integer` | No | Only this trader's prediction, by platform user ID. An unknown ID returns an empty page. (Platform user ID) |
| `sort` | `string` | No | What to sort by. (`submittedAt` (default), `settledAt`, `outcome` or `payout.coins`) |
| `order` | `string` | No | Sort direction. (`asc` (default) or `desc`) |
| `page` | `integer` | No | Page number, starting at 1. (Whole number, 1 or more; default 1) |
| `limit` | `integer` | No | Traders per page. (Default 20; max 100) |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `matchPredictions`. (`Bearer <API_KEY>`) |
| `X-Request-Id` | `string` | No | Your own ID for this request, returned in `meta.requestId`. Without it, a `req_...` ID is generated. |

### Example request

```bash
curl --request GET \
  --url 'https://api.returning.ai/v1/match-predictions/mp_66f000000000000000000801/results?winner=true&limit=50' \
  --header 'Authorization: Bearer <API_KEY>'
```

## Response

The fields listed are for a settled match. A voided match returns a different shape:

- `summary`: `attemptsTouched` (predictions processed), `refunded`, `notApplicable` (no entry cost to refund), `failed` and `coinsRefunded`.
- Each participant: `attemptId`, `userId`, `username`, `pick`, `calledScore`, `payoutStatus` (`refunded` or `not_applicable`), `outcome` (always `refunded`), `refundAmount`, `submittedAt` and `refundedAt`.

On a voided match `winner` and `outcome` filters are ignored.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `meta` | `object` | always | Result details. |
| `meta.status` | `string` | always | Result of the request. (`success`) |
| `meta.statusCode` | `integer` | always | The HTTP status, repeated. |
| `meta.code` | `string` | always | Machine-readable result code. (`MATCH_PREDICTION_RESULTS_RETRIEVED` (settled) or `MATCH_PREDICTION_VOID_COMPLETED` (voided)) |
| `meta.requestId` | `string` | always | Your `X-Request-Id` if you sent one, otherwise a generated `req_...` ID. Quote it when you contact support. |
| `meta.page` | `integer` | always | The page you asked for. |
| `meta.limit` | `integer` | always | Items per page. |
| `meta.total` | `integer` | always | Items that match, across all pages. |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |
| `data` | `object` | always | The totals and this page of predictions. |
| `data.summary` | `object` | always | Totals for the whole match, whatever filters you set. |
| `data.summary.fullTimeScore` | `object` | - | The score you settled with. |
| `data.summary.fullTimeScore.teamA` | `integer` | - | Team A goals. |
| `data.summary.fullTimeScore.teamB` | `integer` | - | Team B goals. |
| `data.summary.predictionsTotal` | `integer` | - | Predictions on this match. |
| `data.summary.winnerCount` | `integer` | - | Predictions with the right result, exact or not. |
| `data.summary.correctResultCount` | `integer` | - | Right result, wrong score. |
| `data.summary.exactScoreCount` | `integer` | - | Right result and exact score. |
| `data.summary.missedCount` | `integer` | - | Wrong result. |
| `data.summary.coinsPaid` | `integer` | - | Coins paid to winners, including their entry cost returned. |
| `data.summary.xpPaid` | `integer` | - | XP paid to winners. |
| `data.summary.entryCoinsReturned` | `integer` | - | Always `0`. Returned entry costs are counted in `coinsPaid`. |
| `data.summary.payoutFailureCount` | `integer` | - | Payouts that could not be made. |
| `data.summary.settledAt` | `string` | - | When the match last changed, normally when settlement finished. |
| `data.summary.operationId` | `string` | - | The settlement ID (`mps_...`). |
| `data.participants` | `object[]` | always | This page of predictions, one per trader. Empty when nothing matches. |
| `data.participants.attemptId` | `string` | - | The prediction's ID. |
| `data.participants.userId` | `integer` | - | The trader's platform user ID. `null` if the account no longer exists. |
| `data.participants.username` | `string` | - | The trader's username or display name. `null` if unknown. |
| `data.participants.pick` | `string` | - | The result the trader picked. (`teamA`, `draw` or `teamB`) |
| `data.participants.calledScore` | `object` | - | The score the trader called. |
| `data.participants.calledScore.teamA` | `integer` | - | Team A goals. |
| `data.participants.calledScore.teamB` | `integer` | - | Team B goals. |
| `data.participants.outcome` | `string` | - | How the prediction scored. `unclassified` if it wasn't scored. (`correct_result`, `exact_score`, `missed` or `unclassified`) |
| `data.participants.payoutStatus` | `string` | - | `paid` once the payout was made; `not_applicable` for a miss or a payout that failed. (`paid` or `not_applicable`) |
| `data.participants.entryCostPaid` | `integer` | - | Coins the trader paid to predict. |
| `data.participants.payout` | `object` | - | What the trader received. |
| `data.participants.payout.coins` | `integer` | - | Coins paid, including the entry cost returned to a winner. |
| `data.participants.payout.xp` | `integer` | - | XP paid. |
| `data.participants.payout.entryCoinsReturned` | `integer` | - | Always `0`. A winner's entry cost is included in `coins`. |
| `data.participants.winner` | `boolean` | - | `true` for `correct_result` and `exact_score`. |
| `data.participants.submittedAt` | `string` | - | When the trader predicted. |
| `data.participants.settledAt` | `string` | - | When this prediction was scored. |

### Example response (200)

```json
{
  "meta": {
    "status": "success",
    "statusCode": 200,
    "code": "MATCH_PREDICTION_RESULTS_RETRIEVED",
    "requestId": "req_66f00000000000000000000000000811",
    "page": 1,
    "limit": 50,
    "total": 48
  },
  "message": "Match prediction results retrieved.",
  "data": {
    "summary": {
      "fullTimeScore": {
        "teamA": 2,
        "teamB": 1
      },
      "predictionsTotal": 120,
      "winnerCount": 48,
      "correctResultCount": 40,
      "exactScoreCount": 8,
      "missedCount": 72,
      "coinsPaid": 5600,
      "xpPaid": 2800,
      "entryCoinsReturned": 0,
      "payoutFailureCount": 0,
      "settledAt": "2026-10-10T21:05:00.000Z",
      "operationId": "mps_66f00000000000000000000000000803"
    },
    "participants": [
      {
        "attemptId": "66f000000000000000000805",
        "userId": 3247779,
        "username": "sample_trader",
        "pick": "teamA",
        "calledScore": {
          "teamA": 2,
          "teamB": 1
        },
        "outcome": "exact_score",
        "payoutStatus": "paid",
        "entryCostPaid": 0,
        "payout": {
          "coins": 300,
          "xp": 150,
          "entryCoinsReturned": 0
        },
        "winner": true,
        "submittedAt": "2026-10-05T12:00:00.000Z",
        "settledAt": "2026-10-10T21:04:00.000Z"
      }
    ]
  }
}
```

## Errors

Every error carries its code in `meta.code` and the request's ID in `meta.requestId`. Validation errors list each problem in `details`, with a `field`, `code` and `message`. The API key checks (`401`, `403`, `404 COMMUNITY_NOT_FOUND` and `500 AUTHENTICATION_FAILED`) return `detail` and `solution` instead. A `404` with an empty body means the route isn't available on api.returning.ai yet.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 404 | - | The body is empty: api.returning.ai doesn't serve this route yet. Ask Returning.AI before you build on it. |
| 400 | `MATCH_PREDICTION_VALIDATION_FAILED` | A query value is invalid: `page` below 1, `limit` outside 1-100, `winner` other than `true` or `false`, an unknown `outcome`, `payoutStatus`, `sort` or `order`, or a `userId` that isn't a whole number. `details` names each one. |
| 400 | `READ_ONLY_FIELD` | The request has a field the server sets, such as `id` or `version`, in the query. `details` names it. Remove it. |
| 401 | `AUTHENTICATION_REQUIRED` | The key is missing, invalid or expired. Send `Authorization: Bearer <API_KEY>` with a current Community API key. |
| 403 | `API_KEY_PERMISSION_DENIED` | The key lacks `matchPredictions`, or it is a personal key. Use a Community API key and add Match Prediction in Settings > Integration > API Keys. |

### Fix the data

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `MATCH_PREDICTION_NOT_FOUND` | No match prediction in your community has this ID. Check it is the full `mp_...` ID from Create match prediction or List match predictions. |
| 404 | `COMMUNITY_NOT_FOUND` | The community this key belongs to no longer exists. Contact Returning.AI support. |
| 409 | `INVALID_LIFECYCLE_TRANSITION` | The match hasn't been settled or voided, so there are no results yet. Settle or void it first. |
| 409 | `MATCH_PREDICTION_SETTLEMENT_FAILED` | The settlement failed. Settle the match again with a new `Idempotency-Key`. |
| 409 | `MATCH_PREDICTION_VOID_FAILED` | The void failed. Void the match again with a new `Idempotency-Key`. |

### Retry with backoff

| Status | Code | What to do |
| --- | --- | --- |
| 429 | `RATE_LIMITED` | Your community is over its [rate limit](https://docs.returning.ai/how-it-works.md#rate-limits). Wait for the seconds in `Retry-After`, then retry. |
| 500 | `INTERNAL_ERROR` | The results could not be read. Retry with exponential backoff. |
| 500 | `AUTHENTICATION_FAILED` | The key could not be checked. Retry with backoff; nothing changed. |
| 503 | `MATCH_PREDICTION_FROZEN` | Returning.AI has paused match prediction requests. Nothing changed. Retry later with backoff. |

**Retries:** This endpoint is read-only, so repeating it is safe. While it returns `202`, wait the `Retry-After` seconds between polls, and stop after a sensible limit. A `409` for a failed settlement or void won't change by polling; start a new one. Returning.AI can set a request limit for your community on these endpoints, counted per community and calling IP address. Over it, requests return `429 RATE_LIMITED` with a `Retry-After` header in seconds; wait that long, then retry.

## Next step

- [Get match prediction](https://docs.returning.ai/api-reference/gamification-match-predictions/get-match-prediction.md): `GET /v1/match-predictions/{matchPredictionId}`. Read the match, including its settlement totals, once results are final.
- [Settle again after a failure with Settle match prediction](https://docs.returning.ai/api-reference/gamification-match-predictions/settle-match-prediction.md): `POST /v1/match-predictions/{matchPredictionId}/settlements`.
