> For the complete documentation index, see [llms.txt](https://dupr.gitbook.io/dupr-raas/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dupr.gitbook.io/dupr-raas/integration-guides/ai-powered-ratings-and-match-annotations.md).

# AI-Powered Ratings & Match Annotations

{% hint style="info" %}
This flow is available only to AI / computer-vision partners that have been whitelisted by DUPR. Email **<tech@mydupr.com>** with your client ID to request access before integrating.
{% endhint %}

Use this flow when your platform produces an **AI-generated rating estimate** (e.g. from video analysis) and you want to attach that rating to one or more players on a match that DUPR should **not** rate through its own ELO pipeline. A common case: a player has no DUPR rating yet, and your model can supply an initial estimate based on observed play.

{% hint style="warning" %}
AI-generated ratings only attach to players who do **not** already have a DUPR rating for that format (singles or doubles). If a player is already rated, the annotation is still recorded for your reference, but their displayed rating will not change.
{% endhint %}

***

## Prerequisites

1. **Whitelist coordination with DUPR.** Your client key must be whitelisted to submit `INFORMATIONAL` matches. Submissions are rejected with an `INFORMATIONAL is not permitted` error otherwise.
2. **`MATCH::ANNOTATE` permission** on the API token used for the annotation call. Standard `MATCH::ADD` is still required to create the match itself.
3. **Players must be SSO-connected to your platform first.** Every player you intend to provide an AI-generated rating or annotation for must have completed the [SSO Login](/dupr-raas/integration-checklist/sso-login.md) flow on your platform. This is the only way to obtain their DUPR ID and the only mechanism by which they consent to your platform writing ratings/annotations against their DUPR profile — manually entering DUPR IDs is not permitted.

***

## Step 1 — Create the match as `INFORMATIONAL`

Submit the match through the standard match-create endpoint with `"matchPlayType": "INFORMATIONAL"`. Player rosters can be partial (for example, only one of the two doubles players present), and the match will not contribute to players' computed DUPR ratings.

```json
{
    "identifier": "your-unique-match-id",
    "location": "Newport Beach, CA",
    "matchDate": "2026-05-01",
    "teamA": {
      "player1": "L8EW8W",
      "game1": 11, "game2": 9, "game3": 11
    },
    "teamB": {
      "player1": "O8GJV8",
      "game1": 7, "game2": 11, "game3": 6
    },
    "format": "SINGLES",
    "matchType": "SIDEOUT",
    "matchPlayType": "INFORMATIONAL",
    "matchSource": "PARTNER"
}
```

Save the `matchCode` from the response — you'll need it in Step 2.

See [Match Upload & Management](/dupr-raas/integration-checklist/match-upload-and-management.md) for the full match-create endpoint reference.

***

## Step 2 — Annotate the match with AI-generated ratings

<table><thead><tr><th width="186">Environment</th><th>API</th></tr></thead><tbody><tr><td>UAT</td><td><a href="https://uat.mydupr.com/api/swagger-ui/index.html#/Match/annotateVendorMatch">UAT: Annotate Match</a></td></tr><tr><td>Production</td><td><a href="https://prod.mydupr.com/api/swagger-ui/index.html#/Match/annotateVendorMatch">Prod: Annotate Match</a></td></tr></tbody></table>

`POST /match/{version}/annotate`. DUPR IDs are the keys in the `players` map, and the `rating` value is a string-encoded float.

```json
{
    "matchId": 1234567890,
    "players": {
        "L8EW8W": { "rating": "3.75" },
        "O8GJV8": { "rating": "3.50" }
    },
    "teams": {
        "TEAM_A": { "confidence": "0.91" }
    },
    "match": {
        "modelVersion": "vision-2026.03"
    }
}
```

Field reference:

* **`matchId`** *(required, long)* — the DUPR match ID returned as `matchCode` from match-create. **Not** the `hashedMatchCode` or your own `identifier`.
* **`players`** — map of 6-character DUPR ID to free-form string-keyed metadata. The `rating` key (string-encoded float) is what DUPR uses to create the AI-generated rating for that player; other keys are stored alongside as free-form metadata for your own analysis.
* **`teams`** — per-team free-form metadata (for example, confidence scores). Keys are `TEAM_A` and `TEAM_B`.
* **`match`** — match-level metadata (for example, model version, capture device).
* **`additionalData`** — any extra context you'd like persisted with the match.

{% hint style="info" %}
Submitting the same `matchId` again is a **merge**, not a replace. Existing fields are preserved and overlaid with whatever you send, so you can enrich an annotation in multiple calls.
{% endhint %}

***

## Removing an annotation

`DELETE /match/{version}/annotate/{matchId}` soft-deletes the annotation. If the same DUPR ID had previously received an AI-generated rating from this annotation, the rating on the player profile is **not** automatically rolled back — contact **<tech@mydupr.com>** if you need to withdraw an already-applied rating.

***

## Attribution

The client key that posts the annotation is recorded as the **source** of each AI-generated rating it produces. This is internal-only — players do not see which partner produced their AI-generated rating — but DUPR ops uses it for support, lineage tracking, and audits.
