QDG Knowledge Base Read-only viewer QWebHub
general

API Reference

Version 1 · New dedicated API page with exact endpoint contracts (request/response DTOs) read directly from AdminEndpoints.cs, MeetingsEndpoint.cs, and the route table in Program.cs — supersedes the summary version in Quick Reference

GateKeeper — API Reference

GateKeeper exposes exactly two HTTP surfaces, both hosted by GateKeeper.Api (Program.cs). It calls no external/outbound APIs itself — it is only ever a callee. See Architecture for the middleware pipeline that sits in front of both, and Quick Reference for run commands and configuration.

Client-facing surface: /v1/*

Authenticated via X-Client-Guid + X-Api-Secret (ClientAuthenticationMiddleware), then scoped by the caller's EffectiveEntitlement (EntitlementResolutionMiddleware).

GET /v1/meetings

MeetingsEndpoint.Handle reads the EffectiveEntitlement that the pipeline already resolved into HttpContext.Items, filters a fixed in-memory sample set through entitlement.IsAllowed(...) on {country, discipline, data_type="meetings", venue}, and returns only what the caller is entitled to see.

200 { "data": [ { "venue": "Randwick", "country": "AU", "discipline": "thoroughbred" }, ... ] }
401   (EffectiveEntitlement missing from HttpContext.Items — auth/entitlement resolution didn't run or failed upstream)

Sample set is fixed: Randwick/AU/thoroughbred, Wentworth Park/AU/greyhound, Addington/NZ/harness, Riccarton/NZ/thoroughbred — deliberately illustrative so the pipeline is runnable without a real racing-data backend. /v1/racecards and /v1/speedmaps are not implemented; they'd follow the same Handle(HttpContext) + entitlement-filter shape.

Admin surface: /admin/*

Authenticated only by an exact-match X-Admin-Key header (AdminAuthMiddleware) — bypasses ClientAuthenticationMiddleware/EntitlementResolutionMiddleware entirely, since these calls configure the customers that surface authenticates, not a customer themselves. Every handler in AdminEndpoints.cs is a thin wrapper over GateKeeperAdminService — no business logic in the endpoint layer itself.

Route Method Request body (AdminEndpoints record) Response
/admin/customers POST CreateCustomerRequest(string Name, string ContactEmail) 201 → { id, clientGuid }
/admin/customers/{id:long} DELETE — 200
/admin/packages POST CreatePackageRequest(string Code, string Name, List<EntitlementScope> Rules) 201 → { id }
/admin/packages/{id:long} POST UpdatePackageRequest(string Name, List<EntitlementScope> Rules, bool IsActive) 200
/admin/customers/{id:long}/tokens POST IssueTokenRequest(string Label, DateTime? ExpiresAt) 201 → { tokenId, secret } (secret shown once, never retrievable again)
/admin/tokens/{id:long}/revoke POST — 200
/admin/customers/{id:long}/subscriptions POST AssignPackageRequest(string PackageCode, DateOnly StartDate, DateOnly? EndDate) 201 → { subscriptionId }
/admin/subscriptions/{id:long}/cancel POST — 200
/admin/customers/{id:long}/overrides POST AddOverrideRequest(OverrideEffect Effect, Dictionary<string,List<string>> Constraints, DateOnly StartDate, DateOnly? EndDate, string? Note, string? CreatedBy) 201 → { overrideId }
/admin/overrides/{id:long}/revoke POST — 200 (sets EndDate to today rather than deleting — preserves history)

EntitlementScope is Dictionary<string, List<string>> keyed by dimension (country, discipline, data_type, venue); a key absent from the dictionary is a wildcard. OverrideEffect is Grant or Revoke.

Confirmed gap: three admin operations have no HTTP route

GateKeeperAdminService also implements CreateDataTypeAsync, UpdateDataTypeAsync, DeleteDataTypeAsync, UpdateSubscriptionDatesAsync, and UpdateApiHitLimitAsync — all called by the Blazor AdminUI in-process — but none of the five appear in Program.cs's route table. There is currently no way to manage Data Types, edit subscription dates, or set a customer's monthly hit limit except through the AdminUI. Adding routes for these would follow the exact pattern already used in AdminEndpoints.cs (thin wrapper + Results.Ok()/Results.Created(...)). Tracked in Known Issues.

No outbound APIs

GateKeeper's own code makes no HttpClient/REST calls to other services — it depends only on MySQL (via EF Core/Pomelo) and Redis (via StackExchange.Redis). The Admin UI talks to GateKeeperAdminService in-process, not over HTTP. Downstream racing-data APIs (meetings, racecards, speed maps) are expected to sit behind GateKeeper as separate services that call into it or consult its cache — not the other way around.

Updated by Claude on Aug. 11, 2026, 11:13 a.m. · Task: create related apis document using in gatekeeper and update API in qdgwiki