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_idgenerated and kept unique per source? - How do you generate a stable string
source_player_idfor every player in your platform? - Which players already have a real
wppr_id, and which do not? - Where does your canonical
club_idmapping 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:
sourceis derived from your API key. Do not send asourcefield in the request body. The same bearer token always maps to the same partner source, and that source is combined with yoursource_player_idandmatch_idfor 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_idteam1team2match_details
dry_run is optional.
Each player must include:
first_namesource_player_idas a string from your system
Optional player fields:
last_namewppr_idphone_number
match_details must include:
dateinYYYY-MM-DDformatclub_idas a real WPPR club UUID
Optional score fields:
set_2set_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_1andset_2, and the same team must win both sets so the match ends2:0 - Three sets: send
set_1,set_2, andset_3only when the first two sets are split1:1, soset_3is 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:0set for a set that was not played
See the Match Set Validation guide for visual examples and an interactive validator.
Contract At A Glance
| Area | What must be true |
|---|---|
| Match identity | match_id is your source-system match ID |
| Player identity | every player must include first_name and source_player_id; last_name is optional |
| WPPR identity | wppr_id is optional and authoritative when present |
| Source identity | source_player_id can be any stable string from your system; without wppr_id, the player is resolved by source + source_player_id |
| Name handling | names are never used to auto-link an existing player |
| Scores | set_1 is required on both teams |
| Optional sets | set_2 and set_3 are optional, but must be paired across both teams |
| Set winner rule | every submitted set must have a winner; tied scores are invalid |
| Match progression | two sets means a 2:0 result, and three sets means the first two sets were split 1:1 |
| Match details | match_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_nameandsource_player_id source_player_idcan be any stable string from your system, including an email, external ID, UUID, or database IDwppr_idis optional and authoritative when present- the same source +
source_player_idmust always represent the same player - names are never used to auto-link an existing player
- if the same name already exists but
source_player_idis new, the API may create a new external/unclaimed player instead of linking by name - if a submitted
source_player_idis already linked to another player, the request is rejected with400 - if a
source_player_idconflict 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_2for one team without sending it for the other team - never send
set_3for one team without sending it for the other team - never send
set_3unlessset_2is 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 soset_3is 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" }}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
| Outcome | Meaning | Recommended action |
|---|---|---|
HTTP 200 OK with status: "created" | The match was accepted and saved | Persist the canonical match_id and mark the sync successful |
HTTP 200 OK with status: "created" and dry_run: true | The request is valid but was not persisted | Use for validation tooling or preflight checks |
400 | Your request was rejected or invalid | Fix the payload or source data before retrying |
401 | Authentication failed | Rotate or correct the bearer token before retrying |
404 / 422 / 429 / 5xx | Upstream or platform-level failure | Handle 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:
404when the upstream system cannot find a referenced resource422when the upstream system rejects the submitted payload as unprocessable429when the upstream system rate-limits your requests500for internal proxy failures502for bad gateway or malformed upstream failures503when the upstream service is unavailable504when the upstream service times out
Recommended Implementation Flow
- Resolve the canonical WPPR
club_id. - Build stable string
source_player_idvalues for all four players. - Include
wppr_idonly for players that already have one. - Build the payload with only the sets that were actually played.
- Validate optional set pairing rules before making the API request.
- Send the request with bearer authentication from environment variables and remember that the token determines your partner
source. - Treat HTTP
200 OKas success, and note that the response body may reportstatus: "created"; treat400as 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_nameandsource_player_id, and includeslast_namewhen available - your
source_player_idvalues are stable strings from your own system, such as emails or internal IDs wppr_idis included only when known- names are never used to auto-link an existing player in your own integration logic
club_idcomes from the WPPR clubs API or a trusted stored mapping- duplicate source matches are handled as
400 Bad Request 400validation errors are shown as actionable integration errors401is 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