Skip to content

Instantly share code, notes, and snippets.

@bartoszmajsak
Last active September 16, 2025 20:11
Show Gist options
  • Save bartoszmajsak/35dcbb57ea8e20ca8db4f309931b4187 to your computer and use it in GitHub Desktop.
Save bartoszmajsak/35dcbb57ea8e20ca8db4f309931b4187 to your computer and use it in GitHub Desktop.
MaaS API schema. v0.0.1
openapi: 3.0.3
info:
title: MaaS Billing API
description: Model as a Service Billing and Management API
version: "1.0"
servers:
- url: http://localhost:8080
paths:
/health:
get:
tags:
- health
summary: Check the health status of the MaaS API service
description: Check if the API service is running and ready to handle requests. Used by load balancers and monitoring.
operationId: health#healthcheck
responses:
"200":
description: OK response.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthcheckResponseBody'
example:
status: Laborum fugiat omnis.
/keys:
get:
tags:
- keys
summary: Retrieve all API keys belonging to the authenticated user
description: List all API keys for the current user. Returns key names, creation dates, and total count.
operationId: keys#list_user_keys
responses:
"200":
description: OK response.
content:
application/json:
schema:
$ref: '#/components/schemas/ListUserKeysResponseBody'
example:
keys:
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
total_keys: 4702929515761424215
"500":
description: 'internal: Internal server error'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
post:
tags:
- keys
summary: Create a new API key for the authenticated user
description: Generate a new API key for programmatic access. Keys are long-lived. Users can have multiple keys with different names.
operationId: keys#create_user_key
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserKeyRequestBody'
example:
name: johns-personal-key
responses:
"200":
description: OK response.
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserKeyResponse'
example:
api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
"409":
description: 'conflict: API key for authenticated user already exists'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
"500":
description: 'internal: Internal server error'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
/keys/{name}:
delete:
tags:
- keys
summary: Delete an API key by name
description: Delete a specific API key by name for the authenticated user.
operationId: keys#delete_user_key
parameters:
- name: name
in: path
description: Key name
required: true
schema:
type: string
description: Key name
example: Praesentium saepe voluptatibus laudantium ut voluptatem veritatis.
example: Id veniam.
responses:
"200":
description: OK response.
"400":
description: 'bad_request: Invalid request'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
"404":
description: 'not_found: API key ''user-john-doe-key'' not found'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
"500":
description: 'internal: Internal server error'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
/tiers/lookup:
post:
tags:
- tiers
summary: Determine the highest subscription tier based on user group memberships
description: Find the highest subscription tier based on user groups. Checks group memberships against tier mappings and returns the best match.
operationId: tiers#lookup
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LookupRequestBody'
example:
groups:
- system:authenticated
- premium-users
responses:
"200":
description: OK response.
content:
application/json:
schema:
$ref: '#/components/schemas/TierLookupResponse'
example:
tier: premium
"400":
description: 'bad_request: Invalid request'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
"404":
description: 'not_found: No tier mapping found for groups: [''unknown-group'']'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
"500":
description: 'internal: Internal server error'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
/tokens:
delete:
tags:
- tokens
summary: Revoke all tokens for the authenticated user
description: Invalidate all tokens for the current user. This will break any applications currently using those tokens.
operationId: tokens#revoke_all
responses:
"204":
description: No Content response.
"500":
description: 'internal: Internal server error'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
post:
tags:
- tokens
summary: Issue a new ephemeral token with specified TTL
description: Create a JWT token with configurable TTL for API authentication. Default TTL is 4 hours.
operationId: tokens#issue
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TokenRequest'
example:
ttl: 4h
responses:
"201":
description: Created response.
content:
application/json:
schema:
$ref: '#/components/schemas/TokenResponse'
example:
expires_at: "2025-12-08T14:30:00Z"
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
"400":
description: 'bad_request: Invalid TTL format'
content:
application/json:
schema:
$ref: '#/components/schemas/TTLValidationError'
example:
fault: false
id: 3F1FKVRR
message: parameter 'ttl' must be a valid Go duration format (e.g., '1h', '30m', '45s'). Valid time units are "ms", "s", "m", "h", "d"
name: bad_request
temporary: false
timeout: false
"500":
description: 'internal: Internal server error'
content:
application/vnd.goa.error:
schema:
$ref: '#/components/schemas/Error'
/v1/models:
get:
tags:
- models
summary: List all available large language models in OpenAI-compatible format
description: List all available large language models in OpenAI-compatible format
operationId: models#list
responses:
"200":
description: OK response.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResponseBody'
example:
data:
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
object: Inventore dolorem molestiae voluptatibus nihil.
components:
schemas:
CreateUserKeyRequestBody:
type: object
properties:
name:
type: string
description: Key name
example: johns-personal-key
example:
name: johns-personal-key
CreateUserKeyResponse:
type: object
properties:
api_key:
type: string
description: Generated API key
example: maas_user_key_1234567890abcdef1234567890abcdef
created_at:
type: string
description: Creation timestamp (RFC3339)
example: "2023-12-01T10:30:00Z"
format: date-time
name:
type: string
description: Key name
example: johns-personal-key
example:
api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
required:
- name
- api_key
- created_at
Error:
type: object
properties:
fault:
type: boolean
description: Is the error a server-side fault?
example: true
id:
type: string
description: ID is a unique identifier for this particular occurrence of the problem.
example: 123abc
message:
type: string
description: Message is a human-readable explanation specific to this occurrence of the problem.
example: parameter 'p' must be an integer
name:
type: string
description: Name is the name of this class of errors.
example: bad_request
temporary:
type: boolean
description: Is the error temporary?
example: false
timeout:
type: boolean
description: Is the error a timeout?
example: false
description: Internal server error
example:
fault: false
id: 123abc
message: parameter 'p' must be an integer
name: bad_request
temporary: true
timeout: false
required:
- name
- id
- message
- temporary
- timeout
- fault
HealthcheckResponseBody:
type: object
properties:
status:
type: string
description: Health status
example: Minima suscipit ad omnis.
example:
status: Molestiae vero voluptatem voluptatem exercitationem praesentium labore.
required:
- status
ListResponseBody:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/OpenAIModel'
example:
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
object:
type: string
description: Object type
example: Exercitationem est repudiandae.
description: OpenAI API response
example:
data:
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
- created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
object: Suscipit illo quis aspernatur quam nemo omnis.
required:
- object
- data
ListUserKeysResponseBody:
type: object
properties:
keys:
type: array
items:
$ref: '#/components/schemas/CreateUserKeyResponse'
example:
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
total_keys:
type: integer
example: 1749273037853111742
format: int64
example:
keys:
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
- api_key: maas_user_key_1234567890abcdef1234567890abcdef
created_at: "2023-12-01T10:30:00Z"
name: johns-personal-key
total_keys: 3161653277572426158
required:
- keys
- total_keys
LookupRequestBody:
type: object
properties:
groups:
type: array
items:
type: string
example: Enim repudiandae officia.
description: User groups
example:
- system:authenticated
- premium-users
example:
groups:
- system:authenticated
- premium-users
required:
- groups
OpenAIModel:
type: object
properties:
created:
type: integer
description: Creation timestamp
example: 1672531200
format: int64
id:
type: string
description: Model ID
example: llama-2-7b-chat
object:
type: string
description: Object type
example: model
owned_by:
type: string
description: Owner
example: model-namespace
ready:
type: boolean
description: Model ready status (?)
example: true
url:
type: string
description: Model URL
example: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
example:
created: 1672531200
id: llama-2-7b-chat
object: model
owned_by: model-namespace
ready: true
url: http://llama-2-7b-chat.openshift-ai-inference-tier-premium.svc.cluster.local
required:
- id
- object
- created
- owned_by
TTLValidationError:
type: object
properties:
fault:
type: boolean
description: Is the error a server-side fault?
example: false
id:
type: string
description: ID of particular error occurrence
example: 3F1FKVRR
message:
type: string
description: Message describing error
example: parameter 'ttl' must be a valid Go duration format (e.g., '1h', '30m', '45s'). Valid time units are "ms", "s", "m", "h", "d"
name:
type: string
description: Name of error
example: bad_request
temporary:
type: boolean
description: Is the error temporary?
example: false
timeout:
type: boolean
description: Is the error a timeout?
example: false
description: Invalid TTL format
example:
fault: false
id: 3F1FKVRR
message: parameter 'ttl' must be a valid Go duration format (e.g., '1h', '30m', '45s'). Valid time units are "ms", "s", "m", "h", "d"
name: bad_request
temporary: false
timeout: false
required:
- name
- id
- message
- temporary
- timeout
- fault
TierLookupResponse:
type: object
properties:
tier:
type: string
description: Matched tier
example: premium
example:
tier: premium
required:
- tier
TokenRequest:
type: object
properties:
ttl:
type: string
description: Token time-to-live (Go duration format)
default: 4h
example: 4h
pattern: ^[0-9]+(ms|s|m|h|d)$
example:
ttl: 4h
TokenResponse:
type: object
properties:
expires_at:
type: string
description: Token expiration (RFC3339)
example: "2025-12-08T14:30:00Z"
format: date-time
token:
type: string
description: Generated token
example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
example:
expires_at: "2025-12-08T14:30:00Z"
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
required:
- token
- expires_at
tags:
- name: tokens
description: "\U0001F511 Ephemeral Token Management service. Uses user's access token to authenticate and refresh tokens."
- name: keys
description: "\U0001F5DD️ API key management service"
- name: models
description: "\U0001F916 Model management service"
- name: tiers
description: "\U0001F3F7️ Tier lookup service"
- name: health
description: ❤️ Health check service
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment