Skip to main content

Create Match With AI

This guide helps your team implement POST /api/v1/matches/verified correctly.

Read this page as a human integration guide first. After you understand the rules, you can copy the AI prompt at the end into ChatGPT, Claude, Cursor, Copilot, or another coding assistant.

Use it if you want to:

  • submit completed WPPR verified matches from your own platform
  • understand the request rules before writing code
  • handle success, validation, auth, and upstream failure cases correctly
  • hand a clean, complete prompt to an AI assistant only after you have reviewed the contract yourself

Start here:

Before You Ask AI To Write Code

Make sure a developer on your team can answer these questions first:

  • How is your match_id generated and kept unique per source?
  • How do you generate a stable string source_player_id for every player in your platform?
  • Which players already have a real wppr_id, and which do not?
  • Where does your canonical club_id mapping come from?
  • What should your system do when the API rejects a duplicate source match or another identity conflict?

If your team cannot answer those questions yet, pause there first. AI can help implement the integration, but it should not invent business rules or identity mappings for you.

What This Endpoint Does

POST /api/v1/matches/verified creates one completed WPPR verified match per request.

When the submission is accepted, the match is attached to the relevant player profiles, match history, and stats.

Send match_id, team1, team2, match_details, and the played set scores. Every submitted player must include first_name and source_player_id. last_name, wppr_id, and phone_number are optional.

source_player_id is a required string from your system. It can be any stable value your source uses to identify that player, such as an email address, external user ID, UUID, or internal database ID.

If wppr_id is present, it is authoritative. Otherwise the upstream resolves the player by source + source_player_id and may create a new external player profile when no mapping exists. The same source + source_player_id must always represent the same player. Names are never used to auto-link an existing player.

One integration detail matters before you write code:

  1. source is derived from your API key. Do not send a source field in the request body. The same bearer token always maps to the same partner source, and that source is combined with your source_player_id and match_id for identity and deduplication.

If a player with the same name already exists but there is no existing mapping for this submitted source_player_id, the API may still create a new external/unclaimed player profile and let duplicate or merge tools handle it later.

If a submitted source_player_id is already linked to a different player, the request is rejected with 400. The developer portal preserves that actionable conflict message for callers, including the player slot, even if the upstream error body is incomplete.

Required Request Shape

Every request must include these top-level fields:

  • match_id
  • team1
  • team2
  • match_details

dry_run is optional.

Each player must include:

  • first_name
  • source_player_id as a string from your system

Optional player fields:

  • last_name
  • wppr_id
  • phone_number

match_details must include:

  • date in YYYY-MM-DD format
  • club_id as a real WPPR club UUID

Optional score fields:

  • set_2
  • set_3

Match Set Rules

Partners should validate set progression locally before sending a request.

Only these progression patterns are valid:

  • One set: send only set_1, and it must have a winner
  • Two sets: send set_1 and set_2, and the same team must win both sets so the match ends 2:0
  • Three sets: send set_1, set_2, and set_3 only when the first two sets are split 1:1, so set_3 is the deciding set

Never send these invalid patterns:

  • a two-set submission where the first two sets are split 1:1
  • a third set after one team already won the first two sets
  • a tied set score such as 6:6
  • a placeholder 0:0 set for a set that was not played

See the Match Set Validation guide for visual examples and an interactive validator.

Contract At A Glance

AreaWhat must be true
Match identitymatch_id is your source-system match ID
Player identityevery player must include first_name and source_player_id; last_name is optional
WPPR identitywppr_id is optional and authoritative when present
Source identitysource_player_id can be any stable string from your system; without wppr_id, the player is resolved by source + source_player_id
Name handlingnames are never used to auto-link an existing player
Scoresset_1 is required on both teams
Optional setsset_2 and set_3 are optional, but must be paired across both teams
Set winner ruleevery submitted set must have a winner; tied scores are invalid
Match progressiontwo sets means a 2:0 result, and three sets means the first two sets were split 1:1
Match detailsmatch_details.date and match_details.club_id are required

Validation Rules You Must Enforce

Before you send a request, make sure your integration follows these rules:

  • send exactly one completed match per request
  • every player must include first_name and source_player_id
  • source_player_id can be any stable string from your system, including an email, external ID, UUID, or database ID
  • wppr_id is optional and authoritative when present
  • the same source + source_player_id must always represent the same player
  • names are never used to auto-link an existing player
  • if the same name already exists but source_player_id is new, the API may create a new external/unclaimed player instead of linking by name
  • if a submitted source_player_id is already linked to another player, the request is rejected with 400
  • if a source_player_id conflict is returned, use the player slot in the error message to fix the submitted player identity before retrying
  • never submit any set as 0:0; if a set was not played, omit it
  • never submit a tied set score such as 5:5; every submitted set must produce a winner
  • never send set_2 for one team without sending it for the other team
  • never send set_3 for one team without sending it for the other team
  • never send set_3 unless set_2 is also present for both teams
  • if you send exactly two sets, the same team must win both sets
  • if you send set_3, the first two sets must be split so set_3 is the deciding set
  • only send fields supported by the endpoint
  • use a real canonical WPPR club_id

Request Examples

Valid payloads

{  "match_id": "13844",  "team1": {    "player1": {      "first_name": "Alice",      "source_player_id": "p-101"    },    "player2": {      "first_name": "Bob",      "source_player_id": "p-102"    },    "set_1": 6  },  "team2": {    "player1": {      "first_name": "Carlos",      "source_player_id": "p-201"    },    "player2": {      "first_name": "Diana",      "source_player_id": "p-202"    },    "set_1": 4  },  "match_details": {    "date": "2026-03-23",    "club_id": "87b2ee5d-1fc6-42be-90bc-ab69d95566a7"  }}
Valid request

Invalid payloads

How To Handle Responses

200 OK

200 means the match was accepted.

Example successful creation:

{
"source_match_id": "13844",
"status": "created",
"match_id": "MC123ABC"
}

Example successful dry-run validation:

{
"source_match_id": "13845",
"status": "created",
"match_id": "MC123ABD",
"dry_run": true
}

There is no successful duplicate response anymore. If the same source + match_id is submitted again, the endpoint returns 400 Bad Request.

Error Envelope

All validation, auth, and upstream failures use the same response shape:

{
"error": true,
"message": "Invalid or missing API token.",
"statusCode": 401
}

Outcome Handling Matrix

OutcomeMeaningRecommended action
HTTP 200 OK with status: "created"The match was accepted and savedPersist the canonical match_id and mark the sync successful
HTTP 200 OK with status: "created" and dry_run: trueThe request is valid but was not persistedUse for validation tooling or preflight checks
400Your request was rejected or invalidFix the payload or source data before retrying
401Authentication failedRotate or correct the bearer token before retrying
404 / 422 / 429 / 5xxUpstream or platform-level failureHandle as API failure, not as a business success

API Errors You Should Expect

400 Bad Request

Some business-rule 400 errors identify the exact submitted player slot, such as team1.player1 or team2.player2, so your operators can see which player in the payload needs to be fixed.

Examples already documented for this endpoint:

  • If set_2 is submitted for either team, it must be submitted for both team1 and team2.
  • If set_3 is submitted for either team, it must be submitted for both team1 and team2.
  • set_3 can only be submitted when set_2 is also submitted for both team1 and team2.
  • set_1 cannot be submitted as 0:0 for both team1 and team2. Please send the real first-set score.
  • set_2 cannot be submitted as 0:0 for both team1 and team2. Omit set_2 if that set was not played, or send the real second-set score.
  • set_3 cannot be submitted as 0:0 for both team1 and team2. Omit set_3 if that set was not played, or send the real third-set score.
  • set_1 must produce a winner. Tied set scores such as 5:5 are not allowed.
  • A two-set match must end 2:0. The submitted scores split the first two sets 1:1, so send set_3 as the deciding set.
  • set_3 can only be submitted as the deciding set after team1 and team2 split set_1 and set_2. If one team already won the first two sets, omit set_3.
  • body/match_details/date must match format "date"
  • body/match_details/club_id must match format "uuid"
  • body/team1/player1 must have required property 'first_name'
  • body/team2/player2 must have required property 'source_player_id'
  • Request body contains unsupported fields: [field list]
  • The provided club_id does not exist: [club_id]
  • A verified match already exists for this source and match_id.
  • The submitted match assigns the same player to more than one slot. Please make sure each of the four player slots refers to a different player and that each player has the correct source_player_id.
  • The submitted source_player_id (partner-player-2) already belongs to P77777 (Mapped Player) for team1.player2 (Player Two), but this request sent wppr_id PCD275. Send wppr_id P77777 with source_player_id partner-player-2, or send a different source_player_id if PCD275 is a different player. If PCD275 should replace P77777, ask support to merge or correct the existing player mapping before retrying.
  • The provided wppr_id does not exist: [wppr_id]

401 Unauthorized

Examples already documented for this endpoint:

  • Authorization header with bearer token is required.
  • Invalid or missing API token.

Other upstream and proxy errors

Your integration should also handle:

  • 404 when the upstream system cannot find a referenced resource
  • 422 when the upstream system rejects the submitted payload as unprocessable
  • 429 when the upstream system rate-limits your requests
  • 500 for internal proxy failures
  • 502 for bad gateway or malformed upstream failures
  • 503 when the upstream service is unavailable
  • 504 when the upstream service times out
  1. Resolve the canonical WPPR club_id.
  2. Build stable string source_player_id values for all four players.
  3. Include wppr_id only for players that already have one.
  4. Build the payload with only the sets that were actually played.
  5. Validate optional set pairing rules before making the API request.
  6. Send the request with bearer authentication from environment variables and remember that the token determines your partner source.
  7. Treat HTTP 200 OK as success, and note that the response body may report status: "created"; treat 400 as a rejected or invalid submission that needs operator review.

Implementation Checklist

Before releasing your integration, verify that:

  • your API key is stored in environment variables, not hard-coded
  • your request builder always sends first_name and source_player_id, and includes last_name when available
  • your source_player_id values are stable strings from your own system, such as emails or internal IDs
  • wppr_id is included only when known
  • names are never used to auto-link an existing player in your own integration logic
  • club_id comes from the WPPR clubs API or a trusted stored mapping
  • duplicate source matches are handled as 400 Bad Request
  • 400 validation errors are shown as actionable integration errors
  • 401 is handled differently from validation and server errors
  • retry logic, if any, is only used for the right classes of upstream failure

Optional: Give This To Your AI Assistant

If your team uses AI to accelerate implementation, use the prompt below only after a human has reviewed the rules above and confirmed the contract with your own team. The prompt is meant to be copied as-is and then customized where marked.

Implement WPPR verified match submission for this endpoint:
https://developers.wecourts.com/api-reference#tag/matches/post/api/v1/matches/verified

Please build this in production-ready code for my stack.

My stack:
- Framework: [replace this]
- Backend language: [replace this]
- Frontend if any: [replace this]

What I need:
- A clean integration for POST /api/v1/matches/verified
- Bearer authentication using environment variables
- Typed request and response models
- Validation before sending the request
- Clear handling for created, validation, auth, and upstream error cases
- Real code, not pseudo code

Endpoint rules:
- Submit one completed match per request
- match_id is my own match ID
- team1 and team2 are required
- every player must include `first_name` and `source_player_id`
- `wppr_id` is optional and authoritative when present
- `phone_number` is optional
- names are never used to auto-link an existing player
- set_1 is required
- set_2 and set_3 are optional and should only be sent if those sets were played
- if set_2 is sent for one team, it must also be sent for the other team
- if set_3 is sent for one team, it must also be sent for the other team, and set_2 must also be sent for both teams
- every submitted set must have a winner
- if only two sets are submitted, the same team must win both sets
- if three sets are submitted, the first two sets must be split and set_3 must decide the match
- match_details is required
- match_details must include date and club_id
- duplicate source matches are rejected with 400

Please generate:
- one service or API client method for create match
- request validation
- response parsing
- error handling
- one example controller, route, or frontend submit handler
- one small test example
- short setup instructions

Before coding:
- summarize the plan
- list assumptions
- list files to create or update

Next Steps