Files
galaxy-game/user/openapi.yaml
T
2026-04-09 09:00:06 +02:00

1377 lines
40 KiB
YAML

openapi: 3.0.3
info:
title: Galaxy User Service Internal REST API
version: v1
description: |
This specification documents the planned trusted internal REST contract of
`galaxy/user`.
Scope:
- auth-facing user resolution, ensure, existence, and subject blocking
- gateway-facing authenticated account reads and self-service mutations
- lobby-facing eligibility snapshots
- geo-facing declared-country synchronization
- admin/internal reads, filtered listing, and explicit mutation commands
This specification is internal REST only. It intentionally does not
describe public edge transport, gateway gRPC, or any future asynchronous
event payloads.
servers:
- url: http://localhost:8091
description: Example local internal listener for User Service.
tags:
- name: AuthIntegration
description: Trusted auth-facing user ownership and block-policy endpoints.
- name: MyAccount
description: Gateway-facing authenticated account queries and self-service mutations.
- name: LobbyIntegration
description: Trusted lobby-facing synchronous eligibility reads.
- name: GeoIntegration
description: Trusted geo-facing declared-country synchronization.
- name: AdminUsers
description: Trusted administrative lookup, listing, and explicit mutation commands.
paths:
/api/v1/internal/user-resolutions/by-email:
post:
tags:
- AuthIntegration
operationId: resolveUserByEmail
summary: Resolve one e-mail address without creating a user
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UserResolutionByEmailRequest"
responses:
"200":
description: Current coarse user-resolution state for the e-mail subject.
content:
application/json:
schema:
$ref: "#/components/schemas/UserResolutionByEmailResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/exists:
get:
tags:
- AuthIntegration
operationId: userExistsByID
summary: Check whether a stable user identifier exists
parameters:
- $ref: "#/components/parameters/UserIDPath"
responses:
"200":
description: Existence check result for the supplied `user_id`.
content:
application/json:
schema:
$ref: "#/components/schemas/UserExistsResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/ensure-by-email:
post:
tags:
- AuthIntegration
operationId: ensureUserByEmail
summary: Resolve, create, or block one e-mail subject
description: |
Returns an existing user for `email`, creates a new regular platform
user when registration is allowed, or returns a blocked outcome when
policy denies the flow.
`registration_context` is create-only. Implementations must ignore it
for existing users and must not overwrite settings of an already
existing account.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/EnsureByEmailRequest"
responses:
"200":
description: Ensure-user outcome for the supplied `email`.
content:
application/json:
schema:
$ref: "#/components/schemas/EnsureByEmailResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/block:
post:
tags:
- AuthIntegration
operationId: blockUserByID
summary: Block one user by stable user identifier
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BlockUserByIDRequest"
responses:
"200":
description: The block mutation applied or the subject was already blocked.
content:
application/json:
schema:
$ref: "#/components/schemas/BlockMutationResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/user-blocks/by-email:
post:
tags:
- AuthIntegration
operationId: blockUserByEmail
summary: Block one e-mail subject even when no user exists yet
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BlockUserByEmailRequest"
responses:
"200":
description: The block mutation applied or the subject was already blocked.
content:
application/json:
schema:
$ref: "#/components/schemas/BlockMutationResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/account:
get:
tags:
- MyAccount
operationId: getMyAccount
summary: Read one authenticated regular-user account aggregate
parameters:
- $ref: "#/components/parameters/UserIDPath"
responses:
"200":
description: Read-optimized account aggregate for the supplied `user_id`.
content:
application/json:
schema:
$ref: "#/components/schemas/GetMyAccountResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/profile:
post:
tags:
- MyAccount
operationId: updateMyProfile
summary: Update self-service profile fields
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateMyProfileRequest"
responses:
"200":
description: Updated account aggregate after the profile mutation commits.
content:
application/json:
schema:
$ref: "#/components/schemas/GetMyAccountResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/settings:
post:
tags:
- MyAccount
operationId: updateMySettings
summary: Update self-service settings fields
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateMySettingsRequest"
responses:
"200":
description: Updated account aggregate after the settings mutation commits.
content:
application/json:
schema:
$ref: "#/components/schemas/GetMyAccountResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/eligibility:
get:
tags:
- LobbyIntegration
operationId: getUserEligibility
summary: Read one synchronous lobby-facing eligibility snapshot
description: |
Returns a read-optimized snapshot for lobby decisions. Unknown users are
represented as `exists=false` instead of `404`.
parameters:
- $ref: "#/components/parameters/UserIDPath"
responses:
"200":
description: Eligibility snapshot for the supplied `user_id`.
content:
application/json:
schema:
$ref: "#/components/schemas/UserEligibilityResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/declared-country/sync:
post:
tags:
- GeoIntegration
operationId: syncDeclaredCountry
summary: Synchronize the current effective declared country
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SyncDeclaredCountryRequest"
responses:
"200":
description: Declared-country synchronization applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/DeclaredCountrySyncResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}:
get:
tags:
- AdminUsers
operationId: getUserByID
summary: Read one user by stable user identifier
parameters:
- $ref: "#/components/parameters/UserIDPath"
responses:
"200":
description: Exact user lookup result for the supplied `user_id`.
content:
application/json:
schema:
$ref: "#/components/schemas/UserLookupResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/user-lookups/by-email:
post:
tags:
- AdminUsers
operationId: getUserByEmail
summary: Read one user by normalized e-mail
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UserLookupByEmailRequest"
responses:
"200":
description: Exact user lookup result for the supplied `email`.
content:
application/json:
schema:
$ref: "#/components/schemas/UserLookupResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/user-lookups/by-race-name:
post:
tags:
- AdminUsers
operationId: getUserByRaceName
summary: Read one user by exact race name
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UserLookupByRaceNameRequest"
responses:
"200":
description: Exact user lookup result for the supplied `race_name`.
content:
application/json:
schema:
$ref: "#/components/schemas/UserLookupResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users:
get:
tags:
- AdminUsers
operationId: listUsers
summary: List users with deterministic pagination and rich filters
parameters:
- $ref: "#/components/parameters/PageSize"
- $ref: "#/components/parameters/PageToken"
- name: paid_state
in: query
description: Filter by current free or paid state.
schema:
type: string
enum:
- free
- paid
- name: paid_expires_before
in: query
description: Filter to users whose paid entitlement expires before this RFC 3339 timestamp.
schema:
type: string
format: date-time
- name: paid_expires_after
in: query
description: Filter to users whose paid entitlement expires after this RFC 3339 timestamp.
schema:
type: string
format: date-time
- name: declared_country
in: query
description: Filter by the current effective declared country.
schema:
$ref: "#/components/schemas/CountryCode"
- name: sanction_code
in: query
description: Filter by one active sanction code.
schema:
$ref: "#/components/schemas/SanctionCode"
- name: limit_code
in: query
description: Filter by one active limit code.
schema:
$ref: "#/components/schemas/LimitCode"
- name: can_login
in: query
description: Filter by the derived login eligibility marker.
schema:
type: boolean
- name: can_create_private_game
in: query
description: Filter by the derived private-game creation eligibility marker.
schema:
type: boolean
- name: can_join_game
in: query
description: Filter by the derived game-join eligibility marker.
schema:
type: boolean
responses:
"200":
description: Deterministically ordered page of users.
content:
application/json:
schema:
$ref: "#/components/schemas/UserListResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/entitlements/grant:
post:
tags:
- AdminUsers
operationId: grantEntitlement
summary: Grant a new entitlement period
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/GrantEntitlementRequest"
responses:
"200":
description: Entitlement grant applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/EntitlementCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/entitlements/extend:
post:
tags:
- AdminUsers
operationId: extendEntitlement
summary: Extend the current entitlement period
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ExtendEntitlementRequest"
responses:
"200":
description: Entitlement extension applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/EntitlementCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/entitlements/revoke:
post:
tags:
- AdminUsers
operationId: revokeEntitlement
summary: Revoke the effective paid entitlement
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RevokeEntitlementRequest"
responses:
"200":
description: Entitlement revocation applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/EntitlementCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/sanctions/apply:
post:
tags:
- AdminUsers
operationId: applySanction
summary: Apply one sanction record
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ApplySanctionRequest"
responses:
"200":
description: Sanction application applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/SanctionCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/sanctions/remove:
post:
tags:
- AdminUsers
operationId: removeSanction
summary: Remove one active sanction record
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RemoveSanctionRequest"
responses:
"200":
description: Sanction removal applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/SanctionCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/limits/set:
post:
tags:
- AdminUsers
operationId: setLimit
summary: Set one active user-specific limit record
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SetLimitRequest"
responses:
"200":
description: User-specific limit set successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/LimitCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
/api/v1/internal/users/{user_id}/limits/remove:
post:
tags:
- AdminUsers
operationId: removeLimit
summary: Remove one active user-specific limit record
parameters:
- $ref: "#/components/parameters/UserIDPath"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RemoveLimitRequest"
responses:
"200":
description: User-specific limit removal applied successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/LimitCommandResponse"
"400":
$ref: "#/components/responses/InvalidRequestError"
"404":
$ref: "#/components/responses/SubjectNotFoundError"
"409":
$ref: "#/components/responses/ConflictError"
"500":
$ref: "#/components/responses/InternalError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
components:
parameters:
UserIDPath:
name: user_id
in: path
required: true
description: Stable regular-user identifier owned by User Service.
schema:
$ref: "#/components/schemas/UserID"
PageSize:
name: page_size
in: query
description: Maximum number of users returned in one page.
schema:
type: integer
minimum: 1
maximum: 200
default: 50
PageToken:
name: page_token
in: query
description: Opaque deterministic pagination cursor returned by the previous page.
schema:
type: string
schemas:
UserID:
type: string
description: Stable regular-user identifier.
minLength: 1
Email:
type: string
format: email
description: Normalized login and contact e-mail address.
RaceName:
type: string
description: |
Stored race name preserving the user-selected casing after successful
uniqueness checks.
minLength: 1
maxLength: 64
LanguageTag:
type: string
description: BCP 47 language tag.
minLength: 1
maxLength: 32
TimeZoneName:
type: string
description: IANA time zone name.
minLength: 1
maxLength: 128
CountryCode:
type: string
description: ISO 3166-1 alpha-2 country code.
pattern: "^[A-Z]{2}$"
UserResolutionKind:
type: string
enum:
- existing
- creatable
- blocked
EnsureUserOutcome:
type: string
enum:
- existing
- created
- blocked
BlockUserOutcome:
type: string
enum:
- blocked
- already_blocked
PlanCode:
type: string
enum:
- free
- paid_monthly
- paid_yearly
- paid_lifetime
SanctionCode:
type: string
enum:
- login_block
- private_game_create_block
- private_game_manage_block
- game_join_block
- profile_update_block
LimitCode:
type: string
enum:
- max_owned_private_games
- max_active_private_games
- max_pending_public_applications
- max_pending_private_join_requests
- max_pending_private_invites_sent
- max_active_game_memberships
ActorRef:
type: object
additionalProperties: false
required:
- type
properties:
type:
type: string
description: Machine-readable actor type such as `admin`, `service`, or `billing`.
id:
type: string
description: Optional stable actor identifier.
RegistrationContext:
type: object
additionalProperties: false
required:
- preferred_language
- time_zone
properties:
preferred_language:
$ref: "#/components/schemas/LanguageTag"
description: |
Create-only initial preferred language. During the current rollout
phase `Auth / Session Service` sends a temporary `"en"` default
until gateway geoip-based language derivation is deployed.
time_zone:
$ref: "#/components/schemas/TimeZoneName"
description: Create-only initial IANA time zone name.
UserResolutionByEmailRequest:
type: object
additionalProperties: false
required:
- email
properties:
email:
$ref: "#/components/schemas/Email"
UserResolutionByEmailResponse:
type: object
additionalProperties: false
required:
- kind
properties:
kind:
$ref: "#/components/schemas/UserResolutionKind"
user_id:
$ref: "#/components/schemas/UserID"
block_reason_code:
type: string
description: Present only for `kind=blocked`.
UserExistsResponse:
type: object
additionalProperties: false
required:
- exists
properties:
exists:
type: boolean
EnsureByEmailRequest:
type: object
additionalProperties: false
required:
- email
properties:
email:
$ref: "#/components/schemas/Email"
registration_context:
$ref: "#/components/schemas/RegistrationContext"
EnsureByEmailResponse:
type: object
additionalProperties: false
required:
- outcome
properties:
outcome:
$ref: "#/components/schemas/EnsureUserOutcome"
user_id:
$ref: "#/components/schemas/UserID"
block_reason_code:
type: string
description: Present only for `outcome=blocked`.
BlockUserByIDRequest:
type: object
additionalProperties: false
required:
- reason_code
properties:
reason_code:
type: string
BlockUserByEmailRequest:
type: object
additionalProperties: false
required:
- email
- reason_code
properties:
email:
$ref: "#/components/schemas/Email"
reason_code:
type: string
BlockMutationResponse:
type: object
additionalProperties: false
required:
- outcome
properties:
outcome:
$ref: "#/components/schemas/BlockUserOutcome"
user_id:
$ref: "#/components/schemas/UserID"
EntitlementSnapshot:
type: object
additionalProperties: false
required:
- plan_code
- is_paid
- source
- starts_at
- updated_at
properties:
plan_code:
$ref: "#/components/schemas/PlanCode"
is_paid:
type: boolean
source:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
reason_code:
type: string
starts_at:
type: string
format: date-time
ends_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ActiveSanction:
type: object
additionalProperties: false
required:
- sanction_code
- scope
- reason_code
- applied_at
properties:
sanction_code:
$ref: "#/components/schemas/SanctionCode"
scope:
type: string
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
applied_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
ActiveLimit:
type: object
additionalProperties: false
required:
- limit_code
- value
- reason_code
- applied_at
properties:
limit_code:
$ref: "#/components/schemas/LimitCode"
value:
type: integer
minimum: 0
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
applied_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
AccountView:
type: object
additionalProperties: false
required:
- user_id
- email
- race_name
- preferred_language
- time_zone
- entitlement
- active_sanctions
- active_limits
- created_at
- updated_at
properties:
user_id:
$ref: "#/components/schemas/UserID"
email:
$ref: "#/components/schemas/Email"
race_name:
$ref: "#/components/schemas/RaceName"
preferred_language:
$ref: "#/components/schemas/LanguageTag"
time_zone:
$ref: "#/components/schemas/TimeZoneName"
declared_country:
$ref: "#/components/schemas/CountryCode"
entitlement:
$ref: "#/components/schemas/EntitlementSnapshot"
active_sanctions:
type: array
items:
$ref: "#/components/schemas/ActiveSanction"
active_limits:
type: array
items:
$ref: "#/components/schemas/ActiveLimit"
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
GetMyAccountResponse:
type: object
additionalProperties: false
required:
- account
properties:
account:
$ref: "#/components/schemas/AccountView"
UpdateMyProfileRequest:
type: object
additionalProperties: false
required:
- race_name
properties:
race_name:
$ref: "#/components/schemas/RaceName"
UpdateMySettingsRequest:
type: object
additionalProperties: false
required:
- preferred_language
- time_zone
properties:
preferred_language:
$ref: "#/components/schemas/LanguageTag"
time_zone:
$ref: "#/components/schemas/TimeZoneName"
EligibilityMarkers:
type: object
additionalProperties: false
required:
- can_login
- can_create_private_game
- can_manage_private_game
- can_join_game
- can_update_profile
properties:
can_login:
type: boolean
can_create_private_game:
type: boolean
can_manage_private_game:
type: boolean
can_join_game:
type: boolean
can_update_profile:
type: boolean
UserEligibilityResponse:
type: object
additionalProperties: false
required:
- exists
- user_id
- markers
properties:
exists:
type: boolean
user_id:
$ref: "#/components/schemas/UserID"
entitlement:
$ref: "#/components/schemas/EntitlementSnapshot"
active_sanctions:
type: array
items:
$ref: "#/components/schemas/ActiveSanction"
effective_limits:
type: array
items:
$ref: "#/components/schemas/ActiveLimit"
markers:
$ref: "#/components/schemas/EligibilityMarkers"
SyncDeclaredCountryRequest:
type: object
additionalProperties: false
required:
- declared_country
properties:
declared_country:
$ref: "#/components/schemas/CountryCode"
DeclaredCountrySyncResponse:
type: object
additionalProperties: false
required:
- user_id
- declared_country
- updated_at
properties:
user_id:
$ref: "#/components/schemas/UserID"
declared_country:
$ref: "#/components/schemas/CountryCode"
updated_at:
type: string
format: date-time
UserAdminView:
allOf:
- $ref: "#/components/schemas/AccountView"
UserLookupByEmailRequest:
type: object
additionalProperties: false
required:
- email
properties:
email:
$ref: "#/components/schemas/Email"
UserLookupByRaceNameRequest:
type: object
additionalProperties: false
required:
- race_name
properties:
race_name:
$ref: "#/components/schemas/RaceName"
UserLookupResponse:
type: object
additionalProperties: false
required:
- user
properties:
user:
$ref: "#/components/schemas/UserAdminView"
UserListResponse:
type: object
additionalProperties: false
required:
- items
properties:
items:
type: array
items:
$ref: "#/components/schemas/UserAdminView"
next_page_token:
type: string
GrantEntitlementRequest:
type: object
additionalProperties: false
required:
- plan_code
- source
- reason_code
- actor
- starts_at
properties:
plan_code:
$ref: "#/components/schemas/PlanCode"
source:
type: string
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
starts_at:
type: string
format: date-time
ends_at:
type: string
format: date-time
ExtendEntitlementRequest:
type: object
additionalProperties: false
required:
- source
- reason_code
- actor
- ends_at
properties:
source:
type: string
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
ends_at:
type: string
format: date-time
RevokeEntitlementRequest:
type: object
additionalProperties: false
required:
- source
- reason_code
- actor
properties:
source:
type: string
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
EntitlementCommandResponse:
type: object
additionalProperties: false
required:
- user_id
- entitlement
properties:
user_id:
$ref: "#/components/schemas/UserID"
entitlement:
$ref: "#/components/schemas/EntitlementSnapshot"
ApplySanctionRequest:
type: object
additionalProperties: false
required:
- sanction_code
- scope
- reason_code
- actor
- applied_at
properties:
sanction_code:
$ref: "#/components/schemas/SanctionCode"
scope:
type: string
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
applied_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
RemoveSanctionRequest:
type: object
additionalProperties: false
required:
- sanction_code
- reason_code
- actor
properties:
sanction_code:
$ref: "#/components/schemas/SanctionCode"
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
SanctionCommandResponse:
type: object
additionalProperties: false
required:
- user_id
- active_sanctions
properties:
user_id:
$ref: "#/components/schemas/UserID"
active_sanctions:
type: array
items:
$ref: "#/components/schemas/ActiveSanction"
SetLimitRequest:
type: object
additionalProperties: false
required:
- limit_code
- value
- reason_code
- actor
- applied_at
properties:
limit_code:
$ref: "#/components/schemas/LimitCode"
value:
type: integer
minimum: 0
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
applied_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
RemoveLimitRequest:
type: object
additionalProperties: false
required:
- limit_code
- reason_code
- actor
properties:
limit_code:
$ref: "#/components/schemas/LimitCode"
reason_code:
type: string
actor:
$ref: "#/components/schemas/ActorRef"
LimitCommandResponse:
type: object
additionalProperties: false
required:
- user_id
- active_limits
properties:
user_id:
$ref: "#/components/schemas/UserID"
active_limits:
type: array
items:
$ref: "#/components/schemas/ActiveLimit"
ErrorResponse:
type: object
additionalProperties: false
required:
- error
properties:
error:
$ref: "#/components/schemas/ErrorBody"
ErrorBody:
type: object
additionalProperties: false
required:
- code
- message
properties:
code:
type: string
message:
type: string
responses:
InvalidRequestError:
description: Request body, path, or query fields are invalid.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
invalidRequest:
value:
error:
code: invalid_request
message: request is invalid
SubjectNotFoundError:
description: The referenced user or lookup subject does not exist.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
subjectNotFound:
value:
error:
code: subject_not_found
message: subject not found
ConflictError:
description: The requested mutation conflicts with current source-of-truth state.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
conflict:
value:
error:
code: conflict
message: request conflicts with current state
InternalError:
description: Internal User Service error.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
internalError:
value:
error:
code: internal_error
message: internal server error
ServiceUnavailableError:
description: User Service is temporarily unable to serve the request safely.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
unavailable:
value:
error:
code: service_unavailable
message: service is unavailable