> ## Documentation Index
> Fetch the complete documentation index at: https://playbook.smedleygroup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The API Surface

> What GKL API exposes, controller by controller: who calls each area, what it expects, and the handful of endpoints worth knowing individually.

GKL API is one Lambda serving one ASP.NET application, so its whole surface is a set of controllers under `api/v1`. This page is the map at controller level. It does not list every endpoint, because there are 88 of them and the code is the only listing that stays true. What it does list is who calls each area, what that area expects, and the endpoints that carry more weight than their neighbours.

For how a caller proves who it is, see [Authentication and Authorisation](/software/developer/estate/systems/gkl/auth).

## The Public Controllers

| Controller | Route | What it is for | Called by |
| - | - | - | - |
| `Checkouts` | `api/v1/checkouts` | The sale. Creating and aborting a checkout, discount lookup, and the eligibility tree | Booking website, Vivenu |
| `Tickets` | `api/v1/tickets` | A user's tickets, filtered by driver or event | Booking website, Vivenu |
| `Transactions` | `api/v1/transactions` | Payment transactions arriving from Vivenu | Vivenu |
| `Events` | `api/v1/events` | Event listing, availability, and whether a date is a race day | Booking website, Telemetry |
| `Drivers` | `api/v1/drivers`, `api/v2/drivers` | A user's drivers, and updating one | Booking website |
| `Credentials` | `api/v1/credentials` | Register, log in, change or reset a password, confirm an email | Booking website |
| `Jwt` | `api/v1/jwt` | Minting and validating tokens | The notification Lambda |
| `Configurations` | `api/v1/configurations` | The region list, and per region configuration | Booking website, Operator Dashboard |
| `BigQuery` | `api/v1/bigquery` | Exporting data as JSON for analytics | An operator holding `BIGQUERY_ADMIN` |
| `Health` | `api/v1/health` | Liveness | Infrastructure |

## The Admin Controllers

Everything under `api/v1/admin/` backs the Operator Dashboard, and with one exception every endpoint expects a signed in `SUPER_ADMIN` or an internal service.

| Controller | Route | What it is for |
| - | - | - |
| `AdminAuth` | `api/v1/admin/auth` | Operator login, and creating and listing admin accounts |
| `AdminUsers` | `api/v1/admin/users` | Finding users, their change history, and resending their confirmation or password emails |
| `AdminDrivers` | `api/v1/admin/drivers` | Finding drivers, their history, and lookups by user or by GKL driver ID |
| `AdminTickets` | `api/v1/admin/tickets` | Finding tickets, their history, reassigning them, and the spreadsheet exports |
| `AdminEvents` | `api/v1/admin/events` | Event listing for the dashboard |

> [!NOTE]
>
> The split is by audience, not by entity. `Drivers` and `AdminDrivers` both exist, and the difference is that the public one only ever answers about the calling user's own drivers while the admin one answers about anyone's. The same pattern holds for tickets and users.

## Endpoints Worth Knowing Individually

### The Money Path

| Endpoint | Why it matters |
| - | - |
| `POST /api/v1/checkouts` | Creates the checkout on Vivenu. This is the endpoint the whole business runs through. See [How A Sale Happens](/software/developer/estate/systems/gkl/how-a-sale-happens) |
| `GET /api/v1/checkouts/availableTicketsTree/{eventId}/{userId}` | Answers what this user's drivers may buy for this event. The whole of [Ticket Eligibility](/software/developer/estate/systems/gkl/ticket-eligibility) is behind this one call |

### The Four Webhooks

Vivenu calls four endpoints, all authenticated by signature rather than key, and all requiring a `hubRegion` query parameter:

| Endpoint | Carries |
| - | - |
| `POST /api/v1/events/webhook` | Event created, updated or deleted. This is how an event exists here at all |
| `POST /api/v1/checkouts/webhook` | Checkout lifecycle |
| `POST /api/v1/tickets/webhook` | Ticket creation and changes |
| `POST /api/v1/transactions/webhook` | Payment transactions |

> [!NOTE]
>
> The events webhook is the one that mirrors Vivenu's event catalogue into our database, switching on the webhook type to create, update or remove the event document for that region. Every other event endpoint on this page reads what it wrote, so if it stops arriving the whole booking flow is working from a stale catalogue. An unrecognised webhook type throws rather than being ignored.

> [!WARNING]
>
> These four are the only way Vivenu state becomes real in our database. If they stop arriving, the booking website keeps taking money on Vivenu and nothing appears against a driver. See [Authentication and Authorisation](/software/developer/estate/systems/gkl/auth#webhook-verification) for why a missing `hubRegion` shows up as a 500 rather than a 401.

### What Other Systems Depend On

Two endpoints exist mainly for Telemetry, and are the reason the `TELEMETRY` claim exists:

| Endpoint | Used for |
| - | - |
| `GET /api/v1/events/isRace/{dateTime}/{hubRegion}` | Deciding whether a converted run is filed under `Race` or `Test` |
| `GET /api/v1/admin/drivers/byGklDriverId/{gklDriver}` | Resolving a driver's power level during conversion |

> [!NOTE]
>
> Both accept `TELEMETRY` or `INTERNAL_SERVICE` as well as a signed in `SUPER_ADMIN`. They are a published contract with another system, so changing their shape breaks conversion at the tracks rather than anything visible here. See [The STL Database](/software/developer/estate/systems/telemetry/stl-database) for what the race day answer decides.

### Internal Only

| Endpoint | Why |
| - | - |
| `POST /api/v1/jwt` | Mints a token. Restricted to internal callers, because this is how the notification Lambda builds signed password reset and email confirmation links without holding the signing key |

### Operator Actions With Consequences

| Endpoint | Effect |
| - | - |
| `POST /api/v1/admin/tickets/update/{ticketId}/user/{userId}` | Moves a ticket to a different user account |
| `POST /api/v1/admin/tickets/update/{ticketId}/parentTicketId` | Clears a ticket's parent link |
| `POST /api/v1/admin/users/{userId}/resendSendConfirmEmail` | Sends the customer an email |
| `POST /api/v1/admin/users/{userId}/resendForgotPwdEmail` | Sends the customer an email |
| `POST /api/v1/configurations/{configId}` | Writes a configuration document. Refuses `REGION_CONFIGURATION` |

## Endpoints That Need No Credential

Eight endpoints are `[AllowAnonymous]`. This is the full list, and it is worth knowing because it is the API's entire unauthenticated attack surface:

| Endpoint | Why |
| - | - |
| `GET /api/v1/health` | Liveness checks |
| `POST /api/v1/credentials/login` | You cannot be signed in to sign in |
| `POST /api/v1/credentials/register` | As above |
| `POST /api/v1/credentials/forgotPassword` | As above |
| `POST /api/v1/admin/auth/login` | Operator sign in |
| `POST /api/v1/jwt` (validate) | Token validation, which needs no caller identity |
| `GET /api/v1/configurations/regions` | The hub picker, shown before sign in |
| `GET /api/v1/configurations/all` | Per region configuration for the front ends |

> [!WARNING]
>
> The last two return configuration straight from the database, and the region document also holds each region's webhook secret, Vivenu secret and Teams URL. What keeps those out of the response is a five field allowlist in one DTO mapper, and an explicit exclusion in the other endpoint. See [One Thing Not To Change](/software/developer/estate/systems/gkl/auth#one-thing-not-to-change).

## Two Things That Will Trip You Up

> [!NOTE]
>
> **`Drivers` is versioned and the others are not.** `DriversController` serves both `api/v1/drivers` and `api/v2/drivers`, with paired `...AsyncV1` and `...AsyncV2` methods on the same controller. Everything else in the API is v1 only, so the version number in a URL is not a reliable guide to anything.

> [!NOTE]
>
> **Many actions return `dynamic`.** Responses are shaped by DTO mapper extension methods rather than by declared response types, so the contract of an endpoint is whatever its mapper projects. That is also why the mappers are the place a field gets accidentally exposed or accidentally dropped.

## Key Files

All paths are under `GklPlatformAPI/GklPlatform/GklPlatform.API.Core/` in the GKL Platform repository.

| File | Role |
| - | - |
| `Controllers/` | Every controller listed above |
| `Controllers/Admin/` | The five admin controllers |
| `Utils/GklToDtoMapperExtensionMethods.cs` | Every response shape |
| `Utils/SecurityExtensionMethods.cs` | The guards each action calls |
| `Requests/` | The request bodies |

## Related Documentation

| Page | Relevance |
| - | - |
| [Authentication and Authorisation](/software/developer/estate/systems/gkl/auth) | How callers are identified and what each claim permits |
| [How A Sale Happens](/software/developer/estate/systems/gkl/how-a-sale-happens) | The checkout endpoints and webhooks in sequence |
| [Ticket Eligibility](/software/developer/estate/systems/gkl/ticket-eligibility) | What the availability tree endpoint computes |
| [Architecture](/software/developer/estate/systems/gkl/architecture) | Where this API sits, and the two gateways in front of it |
| [TalentID in GKL](/software/developer/estate/systems/gkl/talentid-in-gkl) | The other cross system contracts |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.