This commit is contained in:
2026-04-09 14:55:37 +02:00
parent 8be455ba98
commit 4a85efc270
30 changed files with 4895 additions and 1 deletions
+584
View File
@@ -0,0 +1,584 @@
openapi: 3.1.0
info:
title: Hermes API
version: 0.1.0
description: Native betting study prototype API.
servers:
- url: http://localhost:3000
paths:
/health:
get:
summary: Health check
responses:
'200':
description: Service health
content:
application/json:
schema:
$ref: '#/components/schemas/HealthResponse'
/api/v1/session/start:
post:
summary: Start a session
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SessionStartRequest'
responses:
'201':
description: Session started
content:
application/json:
schema:
$ref: '#/components/schemas/SessionResponse'
/api/v1/session/end:
post:
summary: End the current session
responses:
'200':
description: Session ended
content:
application/json:
schema:
$ref: '#/components/schemas/SessionResponse'
/api/v1/session/me:
get:
summary: Inspect the current session
responses:
'200':
description: Current session snapshot
content:
application/json:
schema:
$ref: '#/components/schemas/SessionResponse'
/api/v1/feed/next:
get:
summary: Fetch the next round
responses:
'200':
description: Next event payload
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
/api/v1/events/{event_id}:
get:
summary: Fetch an event
parameters:
- name: event_id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Event
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
/api/v1/events/{event_id}/manifest:
get:
summary: Fetch the event manifest
parameters:
- name: event_id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Manifest
content:
application/json:
schema:
$ref: '#/components/schemas/EventManifest'
/api/v1/events/{event_id}/markets:
get:
summary: List markets for an event
parameters:
- name: event_id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Markets
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Market'
/api/v1/markets/{market_id}/odds/current:
get:
summary: Fetch current odds for a market
parameters:
- name: market_id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Current odds
content:
application/json:
schema:
$ref: '#/components/schemas/OddsVersion'
/api/v1/stream:
get:
summary: Live odds and state stream
responses:
'200':
description: Server-sent events stream
content:
text/event-stream:
schema:
type: string
/api/v1/bets/intent:
post:
summary: Submit a bet intent
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BetIntentRequest'
responses:
'201':
description: Bet intent result
content:
application/json:
schema:
$ref: '#/components/schemas/BetIntentResponse'
/api/v1/bets/{bet_intent_id}:
get:
summary: Fetch a bet intent
parameters:
- name: bet_intent_id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Bet intent
content:
application/json:
schema:
$ref: '#/components/schemas/BetIntentResponse'
/api/v1/events/{event_id}/result:
get:
summary: Fetch event result
parameters:
- name: event_id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Result payload
content:
application/json:
schema:
$ref: '#/components/schemas/Settlement'
/api/v1/analytics/batch:
post:
summary: Ingest analytics batch
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AnalyticsBatchRequest'
responses:
'202':
description: Accepted
/api/v1/experiments/config:
get:
summary: Fetch experiment config
responses:
'200':
description: Experiment config
content:
application/json:
schema:
$ref: '#/components/schemas/ExperimentConfig'
/api/v1/localization/{locale_code}:
get:
summary: Fetch a localization bundle
parameters:
- name: locale_code
in: path
required: true
schema:
type: string
enum: [en, sv]
responses:
'200':
description: Localization bundle
content:
application/json:
schema:
$ref: '#/components/schemas/LocalizationBundle'
/api/v1/admin/events:
post:
summary: Create an event
responses:
'201':
description: Created
/api/v1/admin/markets:
post:
summary: Create a market
responses:
'201':
description: Created
/api/v1/admin/odds:
post:
summary: Publish odds
responses:
'201':
description: Created
/api/v1/admin/settlements:
post:
summary: Publish a settlement
responses:
'201':
description: Created
components:
schemas:
HealthResponse:
type: object
required: [status, service_name, environment, version, uptime_ms, database_ready, redis_ready]
properties:
status:
type: string
service_name:
type: string
environment:
type: string
version:
type: string
uptime_ms:
type: integer
database_ready:
type: boolean
redis_ready:
type: boolean
SessionStartRequest:
type: object
properties:
locale_code:
type: string
device_platform:
type: string
device_model:
type: string
os_version:
type: string
app_version:
type: string
SessionResponse:
type: object
required: [session_id, user_id, started_at, experiment_variant, app_version, locale_code, device_platform]
properties:
session_id:
type: string
format: uuid
user_id:
type: string
format: uuid
started_at:
type: string
format: date-time
ended_at:
type: string
format: date-time
nullable: true
experiment_variant:
type: string
app_version:
type: string
device_model:
type: string
nullable: true
os_version:
type: string
nullable: true
locale_code:
type: string
device_platform:
type: string
Event:
type: object
required: [id, sport_type, source_ref, title_en, title_sv, status, lock_at, settle_at]
properties:
id:
type: string
format: uuid
sport_type:
type: string
source_ref:
type: string
title_en:
type: string
title_sv:
type: string
status:
type: string
preview_start_ms:
type: integer
preview_end_ms:
type: integer
reveal_start_ms:
type: integer
reveal_end_ms:
type: integer
lock_at:
type: string
format: date-time
settle_at:
type: string
format: date-time
EventManifest:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
media:
type: array
items:
$ref: '#/components/schemas/EventMedia'
markets:
type: array
items:
$ref: '#/components/schemas/Market'
EventMedia:
type: object
required: [id, event_id, media_type, hls_master_url, duration_ms]
properties:
id:
type: string
format: uuid
event_id:
type: string
format: uuid
media_type:
type: string
hls_master_url:
type: string
poster_url:
type: string
nullable: true
duration_ms:
type: integer
preview_start_ms:
type: integer
preview_end_ms:
type: integer
reveal_start_ms:
type: integer
reveal_end_ms:
type: integer
Market:
type: object
required: [id, event_id, question_key, market_type, status, lock_at, settlement_rule_key]
properties:
id:
type: string
format: uuid
event_id:
type: string
format: uuid
question_key:
type: string
market_type:
type: string
status:
type: string
lock_at:
type: string
format: date-time
settlement_rule_key:
type: string
outcomes:
type: array
items:
$ref: '#/components/schemas/Outcome'
Outcome:
type: object
required: [id, market_id, outcome_code, label_key, sort_order]
properties:
id:
type: string
format: uuid
market_id:
type: string
format: uuid
outcome_code:
type: string
label_key:
type: string
sort_order:
type: integer
OddsVersion:
type: object
required: [id, market_id, version_no, created_at, is_current]
properties:
id:
type: string
format: uuid
market_id:
type: string
format: uuid
version_no:
type: integer
created_at:
type: string
format: date-time
is_current:
type: boolean
odds:
type: array
items:
$ref: '#/components/schemas/OutcomeOdds'
OutcomeOdds:
type: object
required: [id, odds_version_id, outcome_id, decimal_odds, fractional_num, fractional_den]
properties:
id:
type: string
format: uuid
odds_version_id:
type: string
format: uuid
outcome_id:
type: string
format: uuid
decimal_odds:
type: number
fractional_num:
type: integer
fractional_den:
type: integer
BetIntentRequest:
type: object
required: [session_id, event_id, market_id, outcome_id, idempotency_key, client_sent_at]
properties:
session_id:
type: string
format: uuid
event_id:
type: string
format: uuid
market_id:
type: string
format: uuid
outcome_id:
type: string
format: uuid
idempotency_key:
type: string
client_sent_at:
type: string
format: date-time
BetIntentResponse:
type: object
required: [id, accepted, acceptance_code, server_received_at]
properties:
id:
type: string
format: uuid
accepted:
type: boolean
acceptance_code:
type: string
accepted_odds_version_id:
type: string
format: uuid
nullable: true
server_received_at:
type: string
format: date-time
Settlement:
type: object
required: [id, market_id, settled_at, winning_outcome_id]
properties:
id:
type: string
format: uuid
market_id:
type: string
format: uuid
settled_at:
type: string
format: date-time
winning_outcome_id:
type: string
format: uuid
AnalyticsBatchRequest:
type: object
required: [events]
properties:
events:
type: array
items:
$ref: '#/components/schemas/AnalyticsEventInput'
AnalyticsEventInput:
type: object
required: [event_name, occurred_at]
properties:
event_name:
type: string
occurred_at:
type: string
format: date-time
attributes:
type: array
items:
$ref: '#/components/schemas/AttributeInput'
AttributeInput:
type: object
required: [key, value]
properties:
key:
type: string
value:
type: string
ExperimentConfig:
type: object
properties:
variant:
type: string
feature_flags:
type: object
additionalProperties:
type: boolean
LocalizationBundle:
type: object
required: [locale_code, values]
properties:
locale_code:
type: string
values:
type: object
additionalProperties:
type: string
ErrorResponse:
type: object
required: [code, message]
properties:
code:
type: string
message:
type: string