# Match recap API: get a World Cup 2026 match report from Machina

Machina Sports's match recap API returns finished, ready-written copy for one FIFA World Cup 2026 fixture. Each recap includes the date the copy was generated and a warning that claims beyond the fixture identity and the final score were not revalidated. Each recap costs $0.40. Send `POST https://agents.machina.gg/zcj/7fx1qd4w4r7s/world-cup/v1/skills/match-recap` with a fixture selector, pay the 402 price quote, and retry the same request.

## At a glance

- **Endpoint:** `POST https://agents.machina.gg/zcj/7fx1qd4w4r7s/world-cup/v1/skills/match-recap`. Each request returns one fixture.
- **Body:** at least one of `event`, `event_urn`, `provider_event_id` or `team`. `opponent` and `date` narrow the match. `force_regen` is ignored.
- **Price:** $0.40. A player spotlight is $0.40.
- **Payment:** a 402 price quote you pay over x402 or MPP and retry. A recap is under the $0.50 card floor, so card pays only through prepaid Credits. Pay-as-you-go needs no account.
- **Response:** the copy in `skill_card`, the generation date in `archive.content_created_at`, the event references, and `warnings` with caveats.
- **Scope:** the completed FIFA World Cup 2026 archive only. Responses carry `"live": false`.
- **Full purchase flow:** [the buyer skill](https://agents.machina.gg/zcj/7fx1qd4w4r7s/SKILL.md)

## Pick the fixture selector

The selector has to resolve to exactly one fixture. When you send several selectors, a fixture must match all of them.

| You know | Send |
| --- | --- |
| The fixture label | `{"event": "Brazil vs Morocco"}` |
| Machina's canonical id | `{"event_urn": "<event_urn>"}` |
| The API-Football fixture id | `{"provider_event_id": "<api_football fixture id>"}` |
| One team, and the opponent or the date | `{"team": "Brazil", "opponent": "Morocco"}` or `{"team": "Brazil", "date": "YYYY-MM-DD"}` |

A selector that matches more than one fixture returns `candidates` instead of a recap. Each candidate carries its `event_urn`, which you can resend as the selector.

## Get the recap

1. Send the request without payment:

   ```bash
   curl -sS -X POST https://agents.machina.gg/zcj/7fx1qd4w4r7s/world-cup/v1/skills/match-recap \
     -H 'Content-Type: application/json' \
     -d '{"event": "Brazil vs Morocco"}'
   ```

   The storefront answers with a 402 that quotes $0.40 and lists each rail it accepts. Nothing is charged at this point, so you can stop here.

2. Pay the 402 on one rail and retry the same request with the proof attached. An x402 or MPP client does both steps for you. [The buyer skill](https://agents.machina.gg/zcj/7fx1qd4w4r7s/SKILL.md) covers each rail.

3. Read the response. A paid request with this body cost $0.40 and returned a JSON object of this shape:

   ```json
   {
     "status": "success",
     "meta": {"code": 200},
     "data": {
       "served_from": "final_archive",
       "event_urn": "<event_urn>",
       "resolved_fixture": {"name": "<fixture>", "start_date": "<date>", "venue": "<venue>", "teams": [{"name": "<team>", "crest": "<url>", "team_urn": "<team_urn>", "qualifier": "<qualifier>"}, {"name": "<team>", "crest": "<url>", "team_urn": "<team_urn>", "qualifier": "<qualifier>"}], "result_details": {"status": "<FT|AET|PEN>", "regulation_time_score": {"home": "<goals>", "away": "<goals>"}}},
       "skill_card": {
         "headline": "<headline>",
         "summary": "<recap copy>",
         "what_it_means": "<copy>",
         "turning_points": ["<copy>"],
         "standout_players": ["<copy>"],
         "final_score": "<score>",
         "historical_perspective": "<annotation>",
         "sources": [{"source": "<source>", "subject_urn": "<event_urn>", "generated_at": "<timestamp>"}],
         "grounding": {"final_score_verified": "<boolean>", "narrative_details_revalidated": "<boolean>", "claims_scope": "<scope>"},
         "content_depth": {"tier": "<tier>", "narrative_verification": "<status>", "unsupported_narrative": ["<field>"], "observed_player_records": ["<record>"]},
         "archive_caveats": ["<caveat>"],
         "disclaimer": "<disclaimer>"
       },
       "archive": {"mode": "final_archive", "live": false, "status": "hit", "content_created_at": "<timestamp>", "timestamp_semantics": "<meaning>", "notes": ["<note>"], "provenance": ["<source>"]},
       "coverage": {"status": "<status>", "reason": "<reason>", "unsupported_fields": ["<field>"]},
       "warnings": ["<warning>"]
     }
   }
   ```

   That response carried one warning in `warnings`, one entry in `skill_card.archive_caveats`, one note in `archive.notes`, and the two `skill_card.grounding` flags `final_score_verified` and `narrative_details_revalidated`.

## Check what you are publishing

The recap is the original archived copy, dated by `archive.content_created_at`. The archive verifies the fixture identity and the final score. It did not independently revalidate the narrative for this archive release, and the response says so.

| To find | Read |
| --- | --- |
| The copy | `skill_card.headline`, `summary`, `what_it_means`, `turning_points`, `standout_players` |
| When it was generated | `archive.content_created_at`, with `archive.timestamp_semantics` stating what the timestamp means, and `skill_card.sources[].generated_at` |
| The historical-perspective annotation | `skill_card.historical_perspective` |
| The event references | `event_urn`, `resolved_fixture`, `skill_card.sources` |
| What was verified | `skill_card.grounding.final_score_verified` and `narrative_details_revalidated`, and `content_depth.narrative_verification` |
| The caveats | `warnings`, `skill_card.archive_caveats`, `archive.notes` |
| What the archive does not support | `coverage.unsupported_fields` and `content_depth.unsupported_narrative`, which can include fields such as quotes and scorers |

Treat any claim beyond the fixture and the final score as unverified until you check it.

## Get a player spotlight

`POST https://agents.machina.gg/zcj/7fx1qd4w4r7s/world-cup/v1/skills/player-spotlight` costs $0.40 and is paid the same way as a recap. Identify the player with one of these fields:

- `player_urn`
- `player_id`, which is the exact API-Football player id
- `player`, which is the player's name

You can add `team` or `team_id` to narrow the match:

```json
{"team": "<team name>", "player": "<player name>"}
```

The API reference describes the response as follows:

- A `structured_retrospective` built from archived tournament observations, together with `player_overview` and `resolved_player`.
- An `original_editorial` card where one exists. `content_type` tells you whether one is present.
- `served_from` set to `final_archive`, and a `coverage.unsupported_fields` list.

`force_regen` is ignored on this endpoint too.

## Limits

- Each request returns one fixture or one player. There is no batch call.
- The archive holds only the completed FIFA World Cup 2026. It has no live, current or upcoming matches.
- `force_regen` cannot replace archived copy. Every call returns the original copy.
- An unserved answer is never billed. Unserved answers include a missing or ambiguous selector, an unknown fixture, an unsupported parameter and an archive error, and they carry `"billed": false`.

## Errors

| Status | `reason_code` | Action |
| --- | --- | --- |
| `402` | (none) | This is the price quote. Pay and retry, or stop. |
| `400` | `fixture_selector_required`, `fixture_ambiguous`, `unsupported_parameter` | Add a selector, pick from `candidates`, or use only the fields in `accepted_fields`. |
| `404` | `fixture_not_found` | Check the label or id against the fixture. |
| `503` | `archive_row_missing` | Retry later. |
| `502` | `archive_error` | Nothing was served. Retry later. |

The player spotlight returns the `player_*` codes instead of the `fixture_*` codes. [The error reference](https://agents.machina.gg/zcj/7fx1qd4w4r7s/errors.md) lists the payment errors.

## Frequently asked questions

### Does the match recap API cover live or upcoming matches?

No. It serves recaps from the completed FIFA World Cup 2026 archive, and every response carries `"live": false` and `"mode": "final_archive"`.

### Can I get new or rewritten copy for a match?

No. The `force_regen` field is deprecated and ignored. Every call returns the original archived copy with its generation date.

### How much does a match recap cost?

$0.40 per recap, paid per call. You can also buy prepaid Credits, from $0.50, and calls then draw down the balance. Buying Credits needs an agent credential, which you register through [auth.md](https://agents.machina.gg/zcj/7fx1qd4w4r7s/auth.md).

### How long does a recap request take?

The example recap returned in 3.6 seconds. Every endpoint answers synchronously, so there is no job to poll.

### Am I charged if the fixture is not found?

No. Selector, not-found and archive errors are never billed, and an unpaid 402 charges nothing.

## Keep reading

- [Buyer skill](https://agents.machina.gg/zcj/7fx1qd4w4r7s/SKILL.md): the full purchase flow
- [Finished Content API reference](https://agents.machina.gg/zcj/7fx1qd4w4r7s/services/finished-content/openapi.json): request and response schemas for both endpoints
- [How to pay](https://agents.machina.gg/zcj/7fx1qd4w4r7s/payment.md): the payment rails and Credits
- [Error reference](https://agents.machina.gg/zcj/7fx1qd4w4r7s/errors.md): payment and access errors

---

Updated 2026-10-20. All Machina Sports guides: https://agents.machina.gg/guides.md. Storefront: https://agents.machina.gg/zcj/7fx1qd4w4r7s/llms.txt.
