Returning.AIDevelopers
v1

API reference / Gamification / Match Predictions

.md

Patch match prediction

Change fields on one match prediction, guarded by its version so you never overwrite someone else's change.

Last updated 26 Sep 2026API v1

Method
PATCH
Path
https://api.returning.ai/v1/match-predictions/{matchPredictionId}
Permission
matchPredictions
Retries
No Idempotency-Key; read back before retrying

When to use this

  • Fix a draft's teams, rewards or audience before you publish it.
  • A fixture is delayed, and kickoff and the prediction deadline should move later.
  • Correct a match title or description that traders already see.

Authentication#

Header
Authorization: Bearer <API_KEY>
Permission
matchPredictionsShown in the dashboard as “Match Prediction”

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.

Only the fields you send change. teamA, teamB, rewards, entryCost and viewPermission are replaced as a whole, so send every part of them. Each change adds 1 to version.

While the match is a draft, every field can change. Once it is published, only title, description, externalReference and the three times can change; anything else returns 409 LOCKED_FIELDS_IMMUTABLE. While a published match is scheduled, open or locked, its times can only move later.

The time order is checked only among the times in the same request, and kickoffAt must be in the future whenever you send it. When you move kickoff, send lockAt in the same request so the order stays right.

Request#

Path parameters#

matchPredictionId#stringREQUIRED

Egmp_01abc

Headers#

Authorization#stringREQUIRED
Community API key with matchPredictions.

RuleBearer <API_KEY>

Content-Type#stringREQUIRED
Request body format. Anything else returns 415.

Ruleapplication/json

X-Request-Id#stringOPTIONAL
Your own ID for this request, returned in meta.requestId. Without it, a req_... ID is generated.

Body#

Send version and at least one other field. Time and other rules are the same as for Create match prediction. id, status and communityId return 409 LOCKED_FIELDS_IMMUTABLE; other fields the server sets, such as createdAt, return 400 READ_ONLY_FIELD.

version#integerREQUIRED
The version you last read. The change is rejected if the match has changed since.

RuleWhole number, 1 or more

Eg1

title#stringOPTIONAL
The match title traders see.

Rule1-256 characters, trimmed

Eg"Australia vs New Zealand"

description#stringOPTIONAL
Longer text for traders.

RuleUp to 10,000 characters

Eg"Predict the final score."

externalReference#stringOPTIONAL
Your own fixture ID. Unique in your community, so it is the safest way to find the match again.

Rule1-128 characters, trimmed

Eg"provider-fixture-123"

teamA#objectOPTIONAL
The first team. Replaced as a whole.
name#stringREQUIRED
Team name.

Rule1-128 characters

Eg"Australia"

imageUrl#stringOPTIONAL
Team logo URL.

RuleA URL, up to 2,048 characters

Eg"https://cdn.example.com/teams/australia.png"

teamB#objectOPTIONAL
The second team. Replaced as a whole.
name#stringREQUIRED
Team name.

Rule1-128 characters

Eg"New Zealand"

imageUrl#stringOPTIONAL
Team logo URL.

RuleA URL, up to 2,048 characters

Eg"https://cdn.example.com/teams/new-zealand.png"

predictionStartAt#stringOPTIONAL
When traders can start predicting.

RuleISO 8601 in UTC ending in Z; at or before lockAt

Eg"2026-10-01T08:00:00.000Z"

lockAt#stringOPTIONAL
When predictions close.

RuleISO 8601 in UTC ending in Z; at or before kickoffAt

Eg"2026-10-10T18:55:00.000Z"

kickoffAt#stringOPTIONAL
When the match starts. You can settle only after this time.

RuleISO 8601 in UTC ending in Z; in the future

Eg"2026-10-10T19:00:00.000Z"

scoreBasis#stringOPTIONAL
Which score you will settle on.

Ruleregulation or extra_time

Eg"regulation"

rewards#objectOPTIONAL
What winners earn. Send both tiers.
correctResult#objectREQUIRED
Paid for picking the right result: team A, team B or a draw.
coins#integerREQUIRED
Coins.

RuleWhole number, 0-1,000,000

Eg100

xp#integerREQUIRED
XP.

RuleWhole number, 0-1,000,000

Eg50

exactScoreBonus#objectREQUIRED
Paid on top of correctResult when the called score is also exact.
coins#integerREQUIRED
Coins.

RuleWhole number, 0-1,000,000

Eg200

xp#integerREQUIRED
XP.

RuleWhole number, 0-1,000,000

Eg100

entryCost#objectOPTIONAL
What a trader pays to predict. Winners get it back at settlement, and everyone gets it back if you void.
enabled#booleanREQUIRED
true to charge coins for each prediction.

Egfalse

coins#integerREQUIRED
Coins per prediction.

RuleWhole number; 0 when enabled is false

Eg0

viewPermission#objectOPTIONAL
Who can see the match once it is published. Can be empty on a draft; publishing needs at least one role or user.
roleIds#string[]REQUIRED
Role IDs from your community. Traders with any of these roles can see it.

RuleRole IDs in your community

Eg["66f000000000000000000806"]

userIds#string[]REQUIRED
Platform user IDs, as strings, of traders who can see it.

RuleMembers of your community

Eg["3247779"]

curl --request PATCH \
  --url https://api.returning.ai/v1/match-predictions/mp_66f000000000000000000801 \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "version": 1,
    "lockAt": "2026-10-10T19:25:00.000Z",
    "kickoffAt": "2026-10-10T19:30:00.000Z"
  }'

Response#

A 200 returns the whole match prediction after the change, with the new version. Keep it for your next change.

meta#objectALWAYS
Result details.
status#stringALWAYS
Result of the request.

Rulesuccess

statusCode#integerALWAYS
The HTTP status, repeated.
code#stringALWAYS
Machine-readable result code.

RuleMATCH_PREDICTION_UPDATED

requestId#stringALWAYS
Your X-Request-Id if you sent one, otherwise a generated req_... ID. Quote it when you contact support.
message#stringALWAYS
Human-readable summary. Do not branch on it.
data#objectALWAYS
The match prediction after the change.
id#stringALWAYS
The match prediction ID. Use it in every other call.

Rulemp_ and 24 hex characters

externalReference#string
Your own fixture ID. Left out when not set.
title#stringALWAYS
The match title traders see.
description#string
Longer text for traders. Left out when not set.
teamA#objectALWAYS
The first team.
name#stringALWAYS
Team name.
imageUrl#string
Team logo URL. Left out when not set.
teamB#objectALWAYS
The second team.
name#stringALWAYS
Team name.
imageUrl#string
Team logo URL. Left out when not set.
predictionStartAt#stringALWAYS
When traders can start predicting, in UTC. Milliseconds always read .000.
lockAt#stringALWAYS
When predictions close, in UTC.
kickoffAt#stringALWAYS
When the match starts, in UTC.
scoreBasis#stringALWAYS
Which score you settle on. Settlement uses the score you send either way.

Ruleregulation or extra_time

viewPermission#objectALWAYS
Who can see the match once it is published.
roleIds#string[]ALWAYS
Role IDs. Traders with any of these roles can see it.
userIds#string[]ALWAYS
Platform user IDs, as strings, of traders who can see it.
rewards#objectALWAYS
What winners earn.
correctResult#objectALWAYS
Paid for picking the right result: team A, team B or a draw.
coins#integerALWAYS
Coins.
xp#integerALWAYS
XP.
exactScoreBonus#objectALWAYS
Paid on top of correctResult when the called score is also exact.
coins#integerALWAYS
Coins.
xp#integerALWAYS
XP.
entryCost#objectALWAYS
What a trader pays to predict.
enabled#booleanALWAYS
true when predicting costs coins.
coins#integerALWAYS
Coins per prediction. 0 when enabled is false.
status#stringALWAYS
draft until published. Then scheduled before predictionStartAt, open while traders can predict and locked from lockAt, all worked out from the clock. The rest follow a settle or void.

Ruledraft, scheduled, open, locked, settlement_in_progress, settled, settlement_failed, void_in_progress, voided or void_failed

isPublished#booleanALWAYS
true once published.
acceptingPredictions#booleanALWAYS
true while the match is open and the time is between predictionStartAt and lockAt.
attemptCount#integerALWAYS
Predictions traders have submitted.
settlement#objectALWAYS
Always null here. Read the match with Get match prediction for its settlement totals.
version#integerALWAYS
The current version. Send it with Patch match prediction. It goes up with every change, including publish, settle and void.
createdAt#stringALWAYS
When the match prediction was created.
updatedAt#stringALWAYS
When it last changed.
{
  "meta": {
    "status": "success",
    "statusCode": 200,
    "code": "MATCH_PREDICTION_UPDATED",
    "requestId": "req_66f00000000000000000000000000811"
  },
  "message": "Match prediction updated.",
  "data": {
    "id": "mp_66f000000000000000000801",
    "title": "Australia vs New Zealand",
    "teamA": {
      "name": "Australia",
      "imageUrl": "https://cdn.example.com/teams/australia.png"
    },
    "teamB": {
      "name": "New Zealand",
      "imageUrl": "https://cdn.example.com/teams/new-zealand.png"
    },
    "predictionStartAt": "2026-10-01T08:00:00.000Z",
    "lockAt": "2026-10-10T19:25:00.000Z",
    "kickoffAt": "2026-10-10T19:30:00.000Z",
    "scoreBasis": "regulation",
    "viewPermission": {
      "roleIds": ["66f000000000000000000806"],
      "userIds": []
    },
    "rewards": {
      "correctResult": {
        "coins": 100,
        "xp": 50
      },
      "exactScoreBonus": {
        "coins": 200,
        "xp": 100
      }
    },
    "entryCost": {
      "enabled": false,
      "coins": 0
    },
    "status": "draft",
    "isPublished": false,
    "acceptingPredictions": false,
    "attemptCount": 0,
    "settlement": null,
    "version": 2,
    "createdAt": "2026-09-27T09:00:00.000Z",
    "updatedAt": "2026-09-28T10:00:00.000Z",
    "externalReference": "provider-fixture-123",
    "description": "Predict the final score."
  }
}

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. A 400 or 409 changes nothing.

Fix the request08

404Fix the request
The body is empty: api.returning.ai doesn't serve this route yet. Ask Returning.AI before you build on it.
400MATCH_PREDICTION_VALIDATION_FAILEDFix the request
version is missing, the body changes nothing (EMPTY_UPDATE), a field breaks its rule or isn't recognised, the times you sent are out of order, kickoffAt isn't in the future, or a viewPermission role or user isn't in your community (INVALID_REFERENCE). details lists each problem. Nothing changed.
400READ_ONLY_FIELDFix the request
The request has a field the server sets, such as createdAt, isPublished or attemptCount. details names it. Remove it.
400INVALID_JSONFix the request
The body is not valid JSON. Fix the syntax and send it again.
415UNSUPPORTED_MEDIA_TYPEFix the request
Send the body as JSON with Content-Type: application/json.
401AUTHENTICATION_REQUIREDFix the request
The key is missing, invalid or expired. Send Authorization: Bearer <API_KEY> with a current Community API key.
403API_KEY_PERMISSION_DENIEDFix the request
The key lacks matchPredictions, or it is a personal key. Use a Community API key and add Match Prediction in Settings > Integration > API Keys.
409LOCKED_FIELDS_IMMUTABLEFix the request
The body has id, status or communityId, which never change, or the match is no longer a draft and you sent teamA, teamB, rewards, entryCost, scoreBasis or viewPermission. Nothing changed.

Fix the data04

404MATCH_PREDICTION_NOT_FOUNDFix the data
No match prediction in your community has this ID. Check it is the full mp_... ID from Create match prediction or List match predictions.
404COMMUNITY_NOT_FOUNDFix the data
The community this key belongs to no longer exists. Contact Returning.AI support.
409VERSION_CONFLICTFix the data
The match changed after you read it. Read it again with Get match prediction, check your change still applies, and send it with the new version.
409SCHEDULE_MAY_NOT_MOVE_EARLIERFix the data
The match is published and not yet settled, so its times can only move later. Send a time at or after the current one.

Retry with backoff04

429RATE_LIMITEDRetry with backoff
Your community is over its rate limit. Wait for the seconds in Retry-After, then retry.
500INTERNAL_ERRORRetry with backoff
The outcome is unclear. This is also the response when externalReference is already used by another match. Read the match, and send the change again with its current version if it isn't there.
500AUTHENTICATION_FAILEDRetry with backoff
The key could not be checked. Retry with backoff; nothing changed.
503MATCH_PREDICTION_FROZENRetry with backoff
Returning.AI has paused match prediction requests. Nothing changed. Retry later with backoff.
{
  "meta": {
    "status": "error",
    "statusCode": 404,
    "code": "MATCH_PREDICTION_NOT_FOUND",
    "requestId": "req_66f00000000000000000000000000811"
  },
  "message": "Match prediction not found."
}

Next step#

Publish match predictionPOST/v1/match-predictions/{matchPredictionId}/publishPublish the draft once it is ready.