football-docs 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -111,23 +111,23 @@ Add to `claude_desktop_config.json`:
111
111
 
112
112
  | Provider | Chunks | Categories |
113
113
  |----------|--------|------------|
114
- | StatsBomb | 150 | event-types, data-model, coordinate-system, api-access, xg-model, identity-surfaces |
114
+ | StatsBomb | 231 | event-types, data-model, coordinate-system, api-access, api-endpoints, xg-model, iq-metrics, player/team stats, player-mapping, identity-surfaces |
115
+ | Wyscout | 157 | event-types, data-model, coordinate-system, api-access, api-endpoints, glossary, identity-surfaces |
115
116
  | kloppy | 100 | data-model, usage, provider-mapping |
116
117
  | SportMonks | 78 | event-types, data-model, api-access, identity-surfaces |
117
118
  | databallpy | 63 | data-model, overview, usage |
118
119
  | mplsoccer | 62 | overview, pitch-types, visualizations |
119
- | Wyscout | 68 | event-types, data-model, coordinate-system, api-access, identity-surfaces |
120
+ | Impect | 58 | api-access, api-endpoints, data-model, event-types, coordinate-system, concepts, identity-surfaces |
121
+ | SkillCorner | 51 | api-access, api-endpoints, data-model, physical-data, coordinate-system, concepts, identity-surfaces |
120
122
  | Free sources | 45 | overview, fbref, understat |
121
123
  | soccerdata | 40 | overview, data-sources, usage |
122
124
  | Opta | 36 | event-types, qualifiers, coordinate-system, api-access, identity-surfaces |
123
125
  | socceraction | 26 | SPADL format, VAEP, Expected Threat |
124
126
  | FotMob | 7 | identity-surfaces |
125
- | Impect | 7 | identity-surfaces |
126
- | SkillCorner | 7 | identity-surfaces |
127
127
  | Soccerdonna | 7 | identity-surfaces |
128
128
  | Transfermarkt | 7 | identity-surfaces |
129
129
 
130
- **703 searchable chunks** across 15 providers.
130
+ **968 searchable chunks** across 15 providers.
131
131
 
132
132
  ## Contributing
133
133
 
package/data/docs.db CHANGED
Binary file
package/dist/ingest.js CHANGED
@@ -18,7 +18,7 @@
18
18
  * npm run ingest # ingest all providers
19
19
  * npm run ingest -- --provider opta # ingest one provider
20
20
  */
21
- import { existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
21
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from "node:fs";
22
22
  import { basename, dirname, resolve } from "node:path";
23
23
  import { fileURLToPath } from "node:url";
24
24
  import Database from "better-sqlite3";
@@ -184,7 +184,10 @@ function main() {
184
184
  }
185
185
  const providers = readdirSync(DOCS_DIR).filter((d) => {
186
186
  const full = resolve(DOCS_DIR, d);
187
- return existsSync(full) && readdirSync(full).some((f) => f.endsWith(".md"));
187
+ // Skip non-directory entries (e.g. macOS .DS_Store) so listing can't throw ENOTDIR.
188
+ return (existsSync(full) &&
189
+ statSync(full).isDirectory() &&
190
+ readdirSync(full).some((f) => f.endsWith(".md")));
188
191
  });
189
192
  let total = 0;
190
193
  for (const provider of providers) {
@@ -0,0 +1,78 @@
1
+ ---
2
+ source_url: https://api.impect.com
3
+ source_type: crawled
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # Impect API Access
9
+
10
+ ## Overview
11
+
12
+ Impect is a **commercial football data provider** known for its *Packing* and *pxT* (packing expected threat) metrics, KPI/score framework and detailed set-piece data. Access is via the **Impect Customer API (v5)**, a REST/JSON API. This document is sourced from the v5 OpenAPI spec (`specs/impect/impect_openapi_docs.yml`).
13
+
14
+ - Base URL: `https://api.impect.com`
15
+ - Swagger: `https://api.impect.com/v3/api-docs/CustomerAPI`
16
+ - All endpoints are `GET` and namespaced under `/v5/customerapi/...`.
17
+ - Endpoint inventory: [api-endpoints.md](api-endpoints.md) · data model: [data-model.md](data-model.md) · metrics: [concepts.md](concepts.md).
18
+
19
+ ## Authentication
20
+
21
+ **Bearer token** obtained via Keycloak (`https://login.impect.com/`). Pass it as `Authorization: Bearer <token>`. Every endpoint is protected by `hasRole('API')`.
22
+
23
+ The official **`impectPy`** Python client handles the token exchange — get a token from your username/password, then pass it to each call:
24
+
25
+ ```python
26
+ import impectPy as ip
27
+
28
+ token = ip.getAccessToken(username="you@club.com", password="...")
29
+ iterations = ip.getIterations(token=token)
30
+ events = ip.getEvents(matches=[match_id], token=token)
31
+ ```
32
+
33
+ (There is also an R client, `impectR`.) If calling the REST API directly, exchange credentials for a token at the Keycloak token endpoint, then send `Authorization: Bearer <token>` on each request.
34
+
35
+ ## Rate limiting
36
+
37
+ **10 requests per second per user.** `impectPy` implements client-side token-bucket throttling to stay under it. The API also returns `RateLimit-Policy` and `RateLimit-Remaining` headers; on a `429`, wait for the `Retry-After` header duration before retrying.
38
+
39
+ ## Request correlation
40
+
41
+ Every endpoint accepts an optional **`X-Request-ID`** header (ideally a UUID) to correlate client and server logs when raising support issues.
42
+
43
+ ## Response envelope
44
+
45
+ All responses share an envelope:
46
+
47
+ ```json
48
+ {
49
+ "data": [ /* the payload — usually a List<...Dto> */ ],
50
+ "status": 200,
51
+ "message": null
52
+ }
53
+ ```
54
+
55
+ `data` holds the typed payload; `status` mirrors the HTTP status; `message` carries error/info text. Errors use `ErrorResponseObject`.
56
+
57
+ ## Core concepts (how the API is organised)
58
+
59
+ | Term | Meaning |
60
+ |---|---|
61
+ | **Iteration** | A season × competition instance (e.g. "Premier League 2024/25"). The primary unit for aggregated data. `iterationId` keys most master-data and iteration-level endpoints. |
62
+ | **Match** | A single game, keyed by `matchId`. The unit for event-level data, KPIs, scores and set-pieces. |
63
+ | **Squad** | A team (club or national team), keyed by `squadId`. |
64
+ | **KPI** | A countable/valued key performance indicator computed per event/player/squad. See [concepts.md](concepts.md). |
65
+ | **Score** | A 0–100-style standardised rating derived from KPIs, at player/squad/profile level. |
66
+ | **Profile** | A weighted bundle of KPIs/scores defining a player archetype, position-scoped. |
67
+
68
+ ## Update & delete feeds
69
+
70
+ For keeping a local mirror in sync, the API exposes incremental **update** and **delete** feeds per entity type. Both take a required **`since`** query param (ISO 8601 timestamp) and return only records changed/deleted after it. See the Update Feed / Delete Feed sections of [api-endpoints.md](api-endpoints.md).
71
+
72
+ ## Cross-provider IDs
73
+
74
+ Master-data objects (iterations, players, squads, matches, coaches, stadiums) carry an **`idMappings`** field — provider name → array of that provider's IDs — so you can bridge Impect entities to other providers directly. See [identity-surfaces.md](identity-surfaces.md).
75
+
76
+ ## SkillCorner integration
77
+
78
+ Impect aligns its events to **SkillCorner** tracking frames. `GET /v5/customerapi/matches/{matchId}/skillcorner-frame-mappings` returns frame ↔ event-index mappings (with an `isMatched` flag), letting you join Impect event data to SkillCorner tracking. See [skillcorner](../skillcorner/api-access.md).
@@ -0,0 +1,97 @@
1
+ ---
2
+ source_url: https://api.impect.com
3
+ source_type: crawled
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # Impect API Endpoints (Customer API v5)
9
+
10
+ 44 `GET` endpoints under base `https://api.impect.com`, all prefixed `/v5/customerapi/`. Paths below omit that prefix. All require `Authorization: Bearer <token>` (see [api-access.md](api-access.md)); responses use the `{data, status, message}` envelope. Common path params: `{iterationId}`, `{matchId}`, `{squadId}`, `{positions}` (comma-separated `Position` values).
11
+
12
+ ## Master Data
13
+
14
+ | Endpoint | Returns |
15
+ |---|---|
16
+ | `GET /countries` | All countries |
17
+ | `GET /iterations` | All iterations (season × competition) |
18
+ | `GET /iterations/{iterationId}/matches` | Matches in an iteration |
19
+ | `GET /iterations/{iterationId}/squads` | Squads in an iteration |
20
+ | `GET /iterations/{iterationId}/players` | Players in an iteration |
21
+ | `GET /iterations/{iterationId}/coaches` | Coaches in an iteration |
22
+ | `GET /iterations/{iterationId}/stadiums` | Stadiums in an iteration |
23
+ | `GET /matches/{matchId}` | Match line-ups, formations & substitutions (`data` is a `MatchDto`, wrapped in `ResponseObject_MatchInfoDto`) |
24
+
25
+ ## Match Level Data
26
+
27
+ | Endpoint | Returns |
28
+ |---|---|
29
+ | `GET /matches/{matchId}/events` | Full event feed (`EventDto`) — packing zones, lanes, pxT, phases |
30
+ | `GET /matches/{matchId}/event-kpis` | Per-event KPI values (`ScoringDto`: position, playerId, eventId, kpiId, value) |
31
+ | `GET /matches/{matchId}/player-kpis` | Per-player KPI sums for the match |
32
+ | `GET /matches/{matchId}/squad-kpis` | Per-squad KPI sums for the match |
33
+ | `GET /matches/{matchId}/player-scores` | Per-player standardised scores |
34
+ | `GET /matches/{matchId}/positions/{positions}/player-scores` | Per-player scores for given positions |
35
+ | `GET /matches/{matchId}/squad-scores` | Per-squad scores |
36
+ | `GET /matches/{matchId}/set-pieces` | Set-piece sub-phases (`SetPieceDto`) |
37
+ | `GET /matches/{matchId}/skillcorner-frame-mappings` | SkillCorner frame ↔ event-index mappings |
38
+
39
+ ## Iteration Level Data (aggregates)
40
+
41
+ | Endpoint | Returns |
42
+ |---|---|
43
+ | `GET /iterations/{iterationId}/squad-kpis` | Squad average KPIs across the iteration |
44
+ | `GET /iterations/{iterationId}/squad-scores` | Squad scores across the iteration |
45
+ | `GET /iterations/{iterationId}/squads/{squadId}/player-kpis` | Player average KPIs (one squad) |
46
+ | `GET /iterations/{iterationId}/squads/{squadId}/player-scores` | Player scores (one squad) |
47
+ | `GET /iterations/{iterationId}/squads/{squadId}/positions/{positions}/player-scores` | Player scores by position |
48
+ | `GET /iterations/{iterationId}/squads/{squadId}/positions/{positions}/player-profile-scores` | Player profile scores by position |
49
+
50
+ ## Definitions
51
+
52
+ | Endpoint | Returns |
53
+ |---|---|
54
+ | `GET /kpis` | All KPI definitions |
55
+ | `GET /kpis/event` | Event-level KPI definitions |
56
+ | `GET /player-scores` | All player score definitions (`ScoreDto`: id, name, details{label, definition, meaning}, inverted) |
57
+ | `GET /squad-scores` | All squad score definitions |
58
+ | `GET /player-profiles` | All profile definitions (`ProfileDto`: name, weighted factors, positions) |
59
+
60
+ Definitions endpoints accept an optional **`language`** query param for translated labels/definitions.
61
+
62
+ ## Squad Ratings & Predictions
63
+
64
+ | Endpoint | Returns |
65
+ |---|---|
66
+ | `GET /iterations/{iterationId}/squads/ratings` | Squad ratings over the iteration (`SquadRatingsForIterationDto` → dated entries) |
67
+ | `GET /iterations/{iterationId}/predictions/model-coefficients` | Prediction model coefficients |
68
+
69
+ ## Update Feed (incremental sync)
70
+
71
+ All take a required **`since`** (ISO 8601) query param; return records changed after it.
72
+
73
+ | Endpoint | Entity |
74
+ |---|---|
75
+ | `GET /update/iterations` | Iterations |
76
+ | `GET /update/matches` | Matches |
77
+ | `GET /update/matchdata` | Match data (events/KPIs/scores recalculated) |
78
+ | `GET /update/squads` | Squads |
79
+ | `GET /update/players` | Players |
80
+ | `GET /update/coaches` | Coaches |
81
+ | `GET /update/stadiums` | Stadiums |
82
+ | `GET /update/skillcorner-frame-mappings` | SkillCorner frame mappings |
83
+
84
+ ## Delete Feed (incremental sync)
85
+
86
+ All take a required **`since`** (ISO 8601) query param; return `DeletedDto` records (with `DeleteType` = `DELETED` or `MERGED`).
87
+
88
+ | Endpoint | Entity |
89
+ |---|---|
90
+ | `GET /delete/iterations` | Iterations |
91
+ | `GET /delete/matches` | Matches |
92
+ | `GET /delete/squads` | Squads |
93
+ | `GET /delete/players` | Players |
94
+ | `GET /delete/coaches` | Coaches |
95
+ | `GET /delete/stadiums` | Stadiums |
96
+
97
+ Note: a `MERGED` delete means the entity was merged into another (follow up via the update feed to find the survivor).
@@ -0,0 +1,58 @@
1
+ ---
2
+ source_url: https://api.impect.com
3
+ source_type: crawled
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # Impect Concepts: Packing, pxT, KPIs, Scores
9
+
10
+ Impect's analytics are built on a few signature concepts. The API exposes them as fields and as queryable definitions; the framing below is grounded in the v5 schema (exact field names in [data-model.md](data-model.md)). For canonical formulas, consult the Definitions endpoints (which return each KPI/score's `label`, `definition`, `meaning`) and Impect's own glossary.
11
+
12
+ ## Packing
13
+
14
+ **Packing** counts the opponents a pass or dribble *bypasses* (outplays) — i.e. how many defenders are taken out of the game by moving the ball past them. In the event model this surfaces as `PassDto.opponents` (opponents bypassed) together with the start/end `packingZone`. Bypassing defenders closer to goal is worth more, which is why the longitudinal `PackingZone` bands (`FIRST_THIRD` → `BOX`) matter. Impect popularised Packing as an alternative to possession/pass-count metrics.
15
+
16
+ ## pxT — packing expected threat
17
+
18
+ **pxT** assigns a *threat value* to ball progression rather than just counting bypassed opponents. On each pass, `PassDto.pxT` is `{team, opponent}`:
19
+
20
+ - **`team`** — expected threat added *for* the attacking team by the action.
21
+ - **`opponent`** — expected threat conceded *to* the opponent (the risk/cost component, e.g. if the ball is lost).
22
+
23
+ Net value is the team gain weighed against the opponent risk. pxT is Impect's possession-value layer over the Packing/zone framework.
24
+
25
+ ## KPIs
26
+
27
+ A **KPI** is a single valued metric computed at event, player or squad level. In data, a KPI value is `{kpiId, value}` (`KpiDto`); at event level it is `{position, playerId, eventId, kpiId, value}` (`ScoringDto`). Resolve `kpiId` to its meaning via:
28
+
29
+ - `GET /kpis` — all KPI definitions
30
+ - `GET /kpis/event` — event-level KPI definitions
31
+
32
+ Each definition (`KpiDetailsDto`) carries `label`, `definition`, `meaning`, an optional `parentKpi`, a `context`, and an `inverted` flag (true where a lower raw value is better). Pass `language` for translated text.
33
+
34
+ ## Scores
35
+
36
+ A **score** is a standardised rating derived from KPIs (so different metrics are comparable on a common scale; `inverted` marks lower-is-better inputs). Scores are exposed at several granularities:
37
+
38
+ | Level | Endpoints |
39
+ |---|---|
40
+ | Player (match) | `/matches/{matchId}/player-scores`, `.../positions/{positions}/player-scores` |
41
+ | Player (iteration avg) | `/iterations/{id}/squads/{squadId}/player-scores`, `.../positions/{positions}/player-scores` |
42
+ | Squad | `/matches/{matchId}/squad-scores`, `/iterations/{id}/squad-scores` |
43
+ | Profile | `/iterations/{id}/squads/{squadId}/positions/{positions}/player-profile-scores` |
44
+
45
+ Definitions: `GET /player-scores`, `GET /squad-scores` (`ScoreDto = {id, name, details{label, definition, meaning}, inverted}`).
46
+
47
+ ## Profiles
48
+
49
+ A **profile** (`ProfileDto`) is a weighted bundle defining a player archetype, scoped to positions: `{name, factors:[{name, type(KPI|SCORE), weight, inverted}], positions:[{name}]}`. Profile scores rate how well a player fits an archetype in given positions. Definitions: `GET /player-profiles`.
50
+
51
+ ## Squad ratings & predictions
52
+
53
+ - **Squad ratings** — a time series of squad strength across an iteration (`GET /iterations/{id}/squads/ratings` → dated `{squadId, value}` entries).
54
+ - **Prediction model coefficients** — the coefficients behind Impect's match-outcome predictions (`GET /iterations/{id}/predictions/model-coefficients`).
55
+
56
+ ## Set-piece sub-phases
57
+
58
+ Impect breaks each set-piece into ordered **sub-phases** (delivery → first touch → second touch …), each with its own end zone, delivery type, touch players/outcomes and aggregates. This makes set-pieces analysable as structured sequences rather than single events. See `SetPieceDto` in [data-model.md](data-model.md).
@@ -0,0 +1,49 @@
1
+ ---
2
+ source_url: https://api.impect.com
3
+ source_type: crawled
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # Impect Coordinate System & Spatial Zones
9
+
10
+ Impect locates events with both **continuous coordinates** and a set of **categorical zone descriptors**. The categorical descriptors (packing zone, lane, pitch position) are central to Impect's analytics and are attached to the start and end of every event.
11
+
12
+ ## Coordinates
13
+
14
+ Each `EventPositionDto` carries two coordinate pairs (`CoordinateDto = {x, y}`):
15
+
16
+ - **`coordinates`** — raw pitch coordinates.
17
+ - **`adjCoordinates`** — **direction-adjusted** coordinates, normalised so a squad's attacking direction is consistent regardless of which way it physically plays. Use these to compare/aggregate across halves and teams without flipping.
18
+
19
+ The OpenAPI spec types `x`/`y` as numbers but does not pin the numeric range, so treat the scale as provider-defined and prefer the categorical zones below for portable logic; use `adjCoordinates` for any direction-sensitive computation. Shots also expose a goal-plane aim point via `ShotDto.targetPoint = {y, z}` and the goalkeeper position/`divePoint`.
20
+
21
+ ## Packing zone (`PackingZone`)
22
+
23
+ Longitudinal bands up the pitch, used in Packing/pxT metrics:
24
+
25
+ `GKR` → `FIRST_THIRD` → `SECOND_THIRD` → `FINAL_THIRD` → `BOX`
26
+
27
+ (`GKR` = goalkeeper/restart zone behind the first third; `BOX` = opponent penalty area.)
28
+
29
+ ## Lane (`Lane`)
30
+
31
+ Lateral channels across the pitch (the half-space framework):
32
+
33
+ `LEFT_WING` · `LEFT_HALF_SPACE` · `CENTER` · `RIGHT_HALF_SPACE` · `RIGHT_WING`
34
+
35
+ ## Pitch position (`PitchPosition`)
36
+
37
+ Coarse thirds-by-box location:
38
+
39
+ `OWN_BOX` · `OWN_HALF` · `OPPONENT_HALF` · `OPPONENT_BOX`
40
+
41
+ ## Set-piece end zones (`EndZone`)
42
+
43
+ Target zones used in set-piece sub-phases (corners, free-kicks, goal-kicks, throw-ins, second deliveries):
44
+
45
+ `FAR_LEFT`, `FAR_RIGHT`, `NEAR_POST`, `FAR_POST`, `OPPOSITE_SIDE_1`, `OPPOSITE_SIDE_2`, `SAME_SIDE_1`, `SAME_SIDE_2`, `SIX_YARD_BOX`, `INSIDE_OWN_BOX`, `INSIDE_OPPONENT_BOX`, `OUTSIDE_BOX`, `LEFT_GOAL_KICK_ZONE`, `RIGHT_GOAL_KICK_ZONE`, `CENTER`
46
+
47
+ ## Putting it together
48
+
49
+ A single event therefore carries, at both `start` and `end`: continuous `coordinates` + `adjCoordinates`, plus the `packingZone` (longitudinal band), `lane` (lateral channel) and `pitchPosition` (coarse box/half). The packing zone and lane together give a grid Impect uses to define line-breaking passes and the threat models in [concepts.md](concepts.md).
@@ -0,0 +1,123 @@
1
+ ---
2
+ source_url: https://api.impect.com
3
+ source_type: crawled
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # Impect Data Model
9
+
10
+ Payload structures returned by the Customer API v5, from the OpenAPI spec. Every response is wrapped in `{data, status, message}` (see [api-access.md](api-access.md)). For the spatial/categorical enums see [coordinate-system.md](coordinate-system.md) and [event-types.md](event-types.md); for KPI/score semantics see [concepts.md](concepts.md).
11
+
12
+ ## Event (`EventDto`)
13
+
14
+ `GET /matches/{matchId}/events` returns a list of `EventDto`. Each event is heavily annotated with Impect's spatial framework (packing zone, lane, pitch position) and metric payloads.
15
+
16
+ | Field | Type | Notes |
17
+ |---|---|---|
18
+ | `index` | integer | Event order within the match |
19
+ | `id` | integer | Event id |
20
+ | `sequenceIndex` | integer | Index within the possession sequence |
21
+ | `gameTime` | `GameTimeDto` | `{gameTime (mm:ss), gameTimeInSec}` |
22
+ | `periodId` | integer | Match period |
23
+ | `squadId` | integer | Acting squad |
24
+ | `player` | `EventPlayerDto` | `{id, position, positionSide}` |
25
+ | `actionType` | `ActionType` | SHOT, PASS, DRIBBLE, TACKLE, INTERCEPTION, CLEARANCE, CROSS, FOUL, OFFSIDE |
26
+ | `action` | `Action` | LOW_PASS, HIGH_PASS, GROUND_DUEL, AIR_DUEL, SHOT, CROSS, CLEARANCE, INTERCEPTION, TACKLE, FOUL, OFFSIDE |
27
+ | `result` | `EventResult` | SUCCESS / FAIL |
28
+ | `phase` | `Phase` | SECOND_BALL, BUILD_UP, COUNTER_ATTACK, SET_PIECE |
29
+ | `pressure` | number | Pressure on the acting player |
30
+ | `distanceToOpponent` | `DistanceToOpponent` | LESS_THAN_ONE_METER, ONE_TO_THREE_METERS, MORE_THAN_THREE_METERS |
31
+ | `start` / `end` | `EventPositionDto` | Location + zone/lane/pitch-position at start and end (see below) |
32
+ | `opponent` | `EventOpponentPositionDto` | Nearest opponent's `coordinates` / `adjCoordinates` |
33
+ | `formation` | `FormationsDto` | `{team, opponent}` formation strings |
34
+ | `pass` | `PassDto` | Present for passes (see below) |
35
+ | `shot` | `ShotDto` | Present for shots |
36
+ | `dribble` | `DribbleDto` | `{distance, type, result, playerId}` |
37
+ | `duel` | `DuelDto` | `{duelType, playerId}` |
38
+ | `setPiece` | `EventSetPieceDto` | `{id, subPhaseId, mainEvent}` — links event to a set-piece sub-phase |
39
+ | `inferredSetPiece` | boolean | Set-piece inferred rather than tagged |
40
+ | `pressingPlayerId` | integer | |
41
+ | `fouledPlayerId` | integer | |
42
+
43
+ ### `EventPositionDto` (start / end)
44
+
45
+ | Field | Type | Notes |
46
+ |---|---|---|
47
+ | `coordinates` | `CoordinateDto` | `{x, y}` raw pitch coordinates |
48
+ | `adjCoordinates` | `CoordinateDto` | Direction-adjusted coordinates (attack normalised one way) |
49
+ | `packingZone` | `PackingZone` | GKR, FIRST_THIRD, SECOND_THIRD, FINAL_THIRD, BOX |
50
+ | `pitchPosition` | `PitchPosition` | OWN_BOX, OWN_HALF, OPPONENT_HALF, OPPONENT_BOX |
51
+ | `lane` | `Lane` | LEFT_WING, LEFT_HALF_SPACE, CENTER, RIGHT_HALF_SPACE, RIGHT_WING |
52
+
53
+ ### `PassDto`
54
+
55
+ | Field | Type | Notes |
56
+ |---|---|---|
57
+ | `distance` | number | |
58
+ | `angle` | number | |
59
+ | `distanceToGoal` | number | |
60
+ | `duration` | number | |
61
+ | `opponents` | integer | Opponents bypassed (packing count) |
62
+ | `receiver` | `PassReceiverDto` | `{playerId, type}` — `type` = TEAMMATE / OPPONENT |
63
+ | `currentAttackingSquadId` | integer | |
64
+ | `bodyPart` | `BodyPart` | FOOT / HEAD / OTHER (+ `bodyPartExtended` string) |
65
+ | `previousPassHeight` | `PassHeight` | LOW / MEDIUM / HIGH |
66
+ | `pxT` | `PxTDto` | `{team, opponent}` — packing expected threat added for/against (see [concepts.md](concepts.md)) |
67
+
68
+ ### `ShotDto`
69
+
70
+ | Field | Type | Notes |
71
+ |---|---|---|
72
+ | `distance` | number | |
73
+ | `angle` | number | |
74
+ | `targetPoint` | `TargetPointDto` | `{y, z}` — aim point in the goal plane |
75
+ | `gk` | `ShotGoalkeeperDto` | `{coordinates, adjCoordinates, divePoint, woodwork}` — `woodwork` = LEFT_POST / RIGHT_POST / CROSSBAR |
76
+
77
+ ## KPIs and scoring
78
+
79
+ KPIs are valued metrics referenced by `kpiId`; their human definitions come from the Definitions endpoints.
80
+
81
+ | Schema | Shape | From |
82
+ |---|---|---|
83
+ | `KpiDto` | `{kpiId, value}` | player/squad/iteration KPI endpoints |
84
+ | `ScoringDto` | `{position, playerId, eventId, kpiId, value}` | `GET /matches/{matchId}/event-kpis` |
85
+ | `KpiDetailsDto` | `{id, name, details, parentKpi, context, inverted}` | KPI definitions |
86
+ | `KpiBasicDetailsDto` | `{label, definition, meaning}` | nested in definitions/scores |
87
+
88
+ `ScoreDto` (score definitions): `{id, name, details:{label, definition, meaning}, inverted}`. Player/squad scores are standardised ratings derived from KPIs (player-scores, squad-scores, profile-scores endpoints). `ProfileDto`: `{name, factors:[{name, type(KPI|SCORE), weight, inverted}], positions:[{name}]}`.
89
+
90
+ ## Set-pieces (`SetPieceDto`)
91
+
92
+ Impect models set-pieces as a sequence of **sub-phases**:
93
+
94
+ | Field | Type | Notes |
95
+ |---|---|---|
96
+ | `id`, `matchId`, `squadId` | integer | |
97
+ | `startTime`/`endTime` (+ `*InSec`) | string/number | |
98
+ | `phaseIndex` | integer | |
99
+ | `setPieceCategory` / `adjSetPieceCategory` | `SetPieceCategory` | FREE_KICK, CORNER, GOAL_KICK, THROW_IN, PENALTY |
100
+ | `setPieceExecutionType` | `SetPieceExecutionType` | DIRECT / INDIRECT |
101
+ | `setPieceSubPhase` | `[SetPieceSubPhaseDto]` | per-category end zones (`cornerEndZone`, `freeKickEndZone`, …), delivery types, first/second-touch players & outcomes, `passReceiverId`, `ballTrajectory`, `aggregates` |
102
+
103
+ End zones use the `EndZone` enum (NEAR_POST, FAR_POST, SIX_YARD_BOX, etc. — see [coordinate-system.md](coordinate-system.md)).
104
+
105
+ ## Squad ratings & predictions
106
+
107
+ - `GET /iterations/{iterationId}/squads/ratings` → `SquadRatingsForIterationDto` = `{iterationId, squadRatingsEntries:[SquadRatingsForDateDto]}`; each dated entry holds `SquadRatingDto` = `{squadId, value}`. Ratings are a time series across the iteration.
108
+ - `GET /iterations/{iterationId}/predictions/model-coefficients` → model coefficients (`ModelCoefficientDto`) used in Impect's match-prediction model.
109
+
110
+ ## Master data
111
+
112
+ | Schema | Key fields |
113
+ |---|---|
114
+ | `IterationDto` | `id`, `season`, `competition{name, id, type, countryId, gender}`, `dataVersion`, `lastChangeTimestamp`, `idMappings` |
115
+ | `MatchDto` (single match, from `GET /matches/{matchId}`) | `id`, `dateTime`, `lastCalculationDate`, `iterationId`, `stadiumId`, `squadHome`/`squadAway` (`MatchSquadInfoDto`: `id` (squadId), players, startingPositions, substitutions, startingFormation, formations, coachId). **No `idMappings`.** |
116
+ | `MatchInfoDto` (list item, from `GET /iterations/{id}/matches`) | `iterationId`, `id`, `homeSquadId`, `awaySquadId`, `scheduledDate`, `lastCalculationDate`, `matchDay`, `available`, `idMappings` |
117
+ | `PlayerDto` | `id`, `firstname`, `lastname`, `commonname`, `birthdate`, `birthplace`, `leg` (LEFT/RIGHT/BOTH), `countryIds`, `gender`, `currentSquadId`, `idMappings` |
118
+ | `SquadDto` | `id`, `name`, `countryId`, `type` (NATIONAL_TEAM/CLUB), `gender`, `imageUrl`, `idMappings`, `access` |
119
+ | `CoachDto` (has `idMappings`) / `StadiumDto` (has `idMappings`) / `CountryDetailDto` | reference data |
120
+
121
+ > Note: `GET /matches/{matchId}` is wrapped in `ResponseObject_MatchInfoDto`, but its `data` payload is actually a **`MatchDto`** (with nested line-ups). The flat `MatchInfoDto` — the one that carries `idMappings` — is what the `/iterations/{id}/matches` list returns.
122
+
123
+ `idMappings` (`IdMappingDto`) is an **array of `{external provider name → string[]}` maps** and is present on `IterationDto`, `SquadDto`, `PlayerDto`, `MatchInfoDto`, `CoachDto` and `StadiumDto` — see [identity-surfaces.md](identity-surfaces.md).
@@ -0,0 +1,73 @@
1
+ ---
2
+ source_url: https://api.impect.com
3
+ source_type: crawled
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # Impect Event Types & Enums
9
+
10
+ Impect's `EventDto` does not use a free-form type string — it uses a small set of controlled enums. The two that classify an event are **`actionType`** (the broad category) and **`action`** (the specific action). These are the exact enum values from the v5 spec. See [data-model.md](data-model.md) for the full event payload.
11
+
12
+ ## `actionType` (9)
13
+
14
+ The broad event category:
15
+
16
+ `SHOT`, `PASS`, `DRIBBLE`, `TACKLE`, `INTERCEPTION`, `CLEARANCE`, `CROSS`, `FOUL`, `OFFSIDE`
17
+
18
+ ## `action` (11)
19
+
20
+ The specific action (note passes split by height, and duels are first-class):
21
+
22
+ `LOW_PASS`, `HIGH_PASS`, `GROUND_DUEL`, `AIR_DUEL`, `SHOT`, `CROSS`, `CLEARANCE`, `INTERCEPTION`, `TACKLE`, `FOUL`, `OFFSIDE`
23
+
24
+ ## `result`
25
+
26
+ `SUCCESS`, `FAIL`
27
+
28
+ ## `phase` — possession phase
29
+
30
+ `SECOND_BALL`, `BUILD_UP`, `COUNTER_ATTACK`, `SET_PIECE`
31
+
32
+ ## Contextual enums
33
+
34
+ | Enum | Values |
35
+ |---|---|
36
+ | `BodyPart` | `FOOT`, `HEAD`, `OTHER` |
37
+ | `PassHeight` | `LOW`, `MEDIUM`, `HIGH` |
38
+ | `ReceiverType` | `TEAMMATE`, `OPPONENT` |
39
+ | `DuelType` | `GROUND_DUEL`, `AIR_DUEL` |
40
+ | `DribbleType` | `ONE_VS_ONE`, `ONE_VS_MANY` |
41
+ | `DribbleResult` | `WINNER`, `LOSER` |
42
+ | `DistanceToOpponent` | `LESS_THAN_ONE_METER`, `ONE_TO_THREE_METERS`, `MORE_THAN_THREE_METERS` |
43
+ | `Woodwork` | `LEFT_POST`, `RIGHT_POST`, `CROSSBAR` |
44
+ | `Leg` | `LEFT`, `RIGHT`, `BOTH` |
45
+
46
+ ## Position enums
47
+
48
+ | Enum | Values |
49
+ |---|---|
50
+ | `Position` | `BANK` (bench), `GOALKEEPER`, `LEFT_BACK`, `RIGHT_BACK`, `CENTER_BACK`, `LEFT_MIDFIELD`, `RIGHT_MIDFIELD`, `CENTER_MIDFIELD`, `LEFT_WING`, `RIGHT_WING`, `CENTER_FORWARD` |
51
+ | `PositionSide` | `LEFT`, `RIGHT`, `CENTER` |
52
+
53
+ `{positions}` path params (e.g. on player-scores endpoints) take a comma-separated list of `Position` values.
54
+
55
+ ## Set-piece enums
56
+
57
+ | Enum | Values |
58
+ |---|---|
59
+ | `SetPieceCategory` | `FREE_KICK`, `CORNER`, `GOAL_KICK`, `THROW_IN`, `PENALTY` |
60
+ | `SetPieceExecutionType` | `DIRECT`, `INDIRECT` |
61
+
62
+ ## Other enums
63
+
64
+ | Enum | Values |
65
+ |---|---|
66
+ | `Gender` | `MALE`, `FEMALE` |
67
+ | `SquadType` | `NATIONAL_TEAM`, `CLUB` |
68
+ | `SubstitutionType` | `SUB_ON`, `SUB_OFF`, `TACTICAL_CHANGE` |
69
+ | `DeleteType` | `DELETED`, `MERGED` |
70
+ | `DataVersion` | `V1` |
71
+ | `ProfileFactorType` | `KPI`, `SCORE` |
72
+
73
+ Spatial enums (`PackingZone`, `Lane`, `PitchPosition`, `EndZone`) are documented in [coordinate-system.md](coordinate-system.md).
@@ -1,15 +1,40 @@
1
1
  ---
2
- source_type: curated
3
- source_url: null
4
- upstream_version: null
5
- crawled_at: null
2
+ source_type: crawled
3
+ source_url: https://api.impect.com
4
+ upstream_version: Customer API v5.0
5
+ crawled_at: 2026-06-03
6
6
  ---
7
7
 
8
8
  # Impect Identity Surfaces
9
9
 
10
- Impect is primarily useful as a commercial match and event data provider. Public
11
- documentation for identity surfaces is limited, so this page records cautious
12
- curated guidance for entity-resolution work that has legitimate data access.
10
+ Impect is primarily useful as a commercial match and event data provider. The
11
+ sections below combine **spec-confirmed** identity facts from the Customer API v5
12
+ with cautious curated guidance for entity-resolution work that has legitimate
13
+ data access.
14
+
15
+ ## ID Mappings (confirmed, v5 API)
16
+
17
+ The v5 API exposes a first-class **`idMappings`** field on master-data objects —
18
+ `IterationDto`, `SquadDto`, `PlayerDto`, `MatchInfoDto`, `CoachDto` and
19
+ `StadiumDto` all carry it (i.e. nearly every entity except the nested single-match
20
+ `MatchDto`). `IdMappingDto` is:
21
+
22
+ > "ID mappings to external systems. Keys are provider names, values are arrays of
23
+ > string identifiers." — i.e. each entry is a `map<providerName, string[]>`, and
24
+ > the field is an array of such maps.
25
+
26
+ This means Impect entities can be bridged to other providers **directly from the
27
+ feed**, without inference — read `idMappings` on the iteration/squad/player/match/
28
+ coach/stadium and match the external IDs to your register. An entity may map to
29
+ multiple IDs per provider (hence arrays). Note matches expose `idMappings` on the
30
+ flat list item (`MatchInfoDto`, from `GET /iterations/{id}/matches`), not on the
31
+ single-match `MatchDto` from `GET /matches/{matchId}`. Impect also aligns events
32
+ to **SkillCorner** frames via `GET /matches/{matchId}/skillcorner-frame-mappings`,
33
+ a separate frame↔event bridge (not part of `idMappings`).
34
+
35
+ Entity keys themselves are integer `id` fields: `iterationId`, `matchId`,
36
+ `squadId`, player `id`, `coachId`, `stadiumId`, `countryId`. Iterations are the
37
+ season×competition unit (`{season, competition{...}}`).
13
38
 
14
39
  ## Access Surface
15
40
 
@@ -0,0 +1,68 @@
1
+ ---
2
+ source_url: https://skillcorner.com/api/docs/
3
+ source_type: crawled
4
+ upstream_version: SkillCorner API (Swagger 2.0)
5
+ crawled_at: 2026-06-03
6
+ ---
7
+
8
+ # SkillCorner API Access
9
+
10
+ ## Overview
11
+
12
+ SkillCorner is a **commercial tracking-data provider** specialising in **broadcast (optical) tracking**, **physical data**, and **Game Intelligence** (off-ball runs, on-ball engagements, passing options, player possessions). The REST API is documented with Swagger (drf-yasg) at [skillcorner.com/api/docs/](https://skillcorner.com/api/docs/); this doc is sourced from its OpenAPI spec (`specs/skillcorner/skillcorner_openapi.json`).
13
+
14
+ - Base URL: `https://skillcorner.com/api`
15
+ - Glossary & material: <https://skillcorner.crunch.help/en>
16
+ - Endpoint inventory: [api-endpoints.md](api-endpoints.md) · data model: [data-model.md](data-model.md) · physical metrics: [physical-data.md](physical-data.md) · concepts: [concepts.md](concepts.md)
17
+
18
+ ## Authentication
19
+
20
+ Two schemes (either works):
21
+
22
+ - **Basic auth** — username/password.
23
+ - **API key** — pass `?token=<key>` as a query parameter.
24
+
25
+ The official **`skillcorner`** Python client wraps this:
26
+
27
+ ```python
28
+ from skillcorner.client import SkillcornerClient
29
+
30
+ client = SkillcornerClient(username="...", password="...")
31
+ teams = client.get_teams()
32
+ physical = client.get_physical(params={"competition_edition": [123], "group_by": ["player"]})
33
+ ```
34
+
35
+ (See also `skillcornerviz` and `skillcorner-toolkit`.) Docs: <https://skillcorner.readthedocs.io/>.
36
+
37
+ ## Multi-value parameters
38
+
39
+ Many filter params accept **multiple comma-separated values** in the URL (e.g. `?competition=1,2,3`). In Swagger UI you enter each ID as a separate value and they are combined into one parameter. With the Python client, pass a list.
40
+
41
+ ## Pagination
42
+
43
+ Two styles depending on endpoint:
44
+
45
+ - **`limit` / `offset`** — classic paging (master-data and list endpoints), often with a `count`/`next`/`previous` envelope.
46
+ - **`after`** cursor — some large endpoints (e.g. `/physical/`) return a `next` value; pass it back as `after` for the next page.
47
+
48
+ ## Rate limiting
49
+
50
+ Endpoints return `429 Too Many Requests` when exceeded; back off and retry. (No fixed per-second figure is published in the spec — the official client paces requests.)
51
+
52
+ ## Response formats
53
+
54
+ - **List/metric endpoints** return JSON. `/physical/` additionally accepts `response_format` ∈ `json`, `small_json`, `csv` (this toggle is `/physical/`-only; the GI-metric endpoints always return JSON).
55
+ - **Tracking** (`/match/{id}/tracking/`) returns a **downloadable file**: `file_format` ∈ `jsonl` (one JSON object per line), `fifa-xml`, or `fifa-data` (FIFA EPTS standard — a metadata `.xml` + data `.txt`). Current `data_version` is `3`.
56
+ - **Dynamic events** (`/match/{id}/dynamic_events/...`) return **CSV files** (`file_format`, `data_version`, `period_starts`).
57
+
58
+ ## Data versions
59
+
60
+ SkillCorner versions its data products independently. Current versions seen in the spec: **tracking v3**, **physical v3**, **dynamic events v2**, **GI metrics v2**. The `/matches/` endpoint exposes `*_last_modified__gte` filters per product (e.g. `tracking_last_modified__gte`, `physical_v3_last_modified__gte`, `dynamic_events_v2_last_modified__gte`) for incremental sync.
61
+
62
+ ## Custom feeds
63
+
64
+ Endpoints under `/match/{id}/custom/...`, `/matches/custom/` and `/data_collections/custom/` serve **customer-specific** computed feeds (the standard, non-custom endpoints serve SkillCorner's catalogue products). `/data_collections/` tells you which data products are available for which matches.
65
+
66
+ ## Deprecated
67
+
68
+ `/beta/out_of_possession/` and `/in_possession/{off_ball_runs,on_ball_pressures,passes}/` are **Game Intelligence V1 (deprecated)**. Use the `dynamic_events` and `metrics/game_intelligence` endpoints (V2) instead.