{"openapi":"3.0.2","info":{"title":"Morpheus API Gateway","description":"API Gateway connecting Web2 clients to the Morpheus-Lumerin AI Marketplace","version":"v1.22.0"},"paths":{"/api/v1/auth/me":{"get":{"tags":["Auth"],"summary":"Get Current User Info","description":"Get current user information.\n\nEmail and name are fetched live from Cognito (not stored in DB).\nUses the caller's own access token — same pattern as the frontend.","operationId":"get_current_user_info_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Current User Info Api V1 Auth Me Get"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/verify-age":{"post":{"tags":["Auth"],"summary":"Verify Age","description":"Submit age verification consent (18+).\n\nThe user must send `{\"age_verified\": true}` to confirm they are 18 or older.\nThe confirmation and the timestamp are stored as evidence of consent.\n\nRequires JWT Bearer authentication with Cognito token.","operationId":"verify_age_api_v1_auth_verify_age_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgeVerificationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Verify Age Api V1 Auth Verify Age Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/keys":{"get":{"tags":["Auth"],"summary":"Get Api Keys","description":"Get all API keys for the current user.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"get_api_keys_api_v1_auth_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/APIKeyDB"},"type":"array","title":"Response Get Api Keys Api V1 Auth Keys Get"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]},"post":{"tags":["Auth"],"summary":"Create Api Key","description":"Create a new API key for the current user.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"create_api_key_api_v1_auth_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/keys/{key_id}":{"delete":{"tags":["Auth"],"summary":"Delete Api Key","description":"Deactivate an API key.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"delete_api_key_api_v1_auth_keys__key_id__delete","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyDB"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/register":{"delete":{"tags":["Auth"],"summary":"Delete User Account","description":"Delete the current user's account and all associated data.\n\nAlways: deletes API keys, user record (cascades: wallet_links, chats, etc.).\nCognito: only in production (ENVIRONMENT in production|prod|prd) do we delete\nthe Cognito user. In dev/test/non-prod we leave the Cognito identity intact so\n\"Delete account\" in TEST cannot accidentally nuke the user's real identity.\n\nRequires JWT Bearer authentication.","operationId":"delete_user_account_api_v1_auth_register_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDeletionResponse"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/keys/first":{"get":{"tags":["Auth"],"summary":"Get First Api Key","description":"Get the first (oldest) active API key for the current user.\nThis is used for automatic API key selection on login.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"get_first_api_key_api_v1_auth_keys_first_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/APIKeyDB"},{"type":"null"}],"title":"Response Get First Api Key Api V1 Auth Keys First Get"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/keys/default":{"get":{"tags":["Auth"],"summary":"Get Default Api Key","description":"Get the user's default API key. If no default is set, returns the first (oldest) active API key.\nThis respects user preference for default key selection.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"get_default_api_key_api_v1_auth_keys_default_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/APIKeyDB"},{"type":"null"}],"title":"Response Get Default Api Key Api V1 Auth Keys Default Get"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/keys/{key_id}/default":{"put":{"tags":["Auth"],"summary":"Set Default Api Key","description":"Set an API key as the user's default. Clears any existing default.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"set_default_api_key_api_v1_auth_keys__key_id__default_put","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyDB"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/keys/default/decrypted":{"get":{"tags":["Auth"],"summary":"Get Default Api Key Decrypted","description":"Get the user's default API key with the full decrypted key for auto-selection.\n\nThis endpoint returns the full API key to enable seamless Chat/Test access.\nThe key is decrypted using the user's Cognito data for security.\n\nRequires JWT Bearer authentication with the token received from the login endpoint.","operationId":"get_default_api_key_decrypted_api_v1_auth_keys_default_decrypted_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/models":{"get":{"tags":["Models"],"summary":"List Models","description":"Get a list of active models.\n\nResponse is in OpenAI API format with selected fields from the blockchain data.\nOnly returns active models with available providers.","operationId":"list_models_api_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/models/allmodels":{"get":{"tags":["Models"],"summary":"List All Models","description":"Get a list of all available models.\n\nResponse is in OpenAI API format with selected fields from the blockchain data.\nOnly returns non-deleted models.","operationId":"list_all_models_api_v1_models_allmodels_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/models/ratedbids":{"get":{"tags":["Models"],"summary":"Get Rated Bids","description":"Get rated bids for a specific model.\n\nConnects to the proxy-router's /blockchain/models/{id}/bids/rated endpoint.\nNote: Use the blockchain model ID (hex) not the name.","operationId":"get_rated_bids_api_v1_models_ratedbids_get","parameters":[{"name":"model_id","in":"query","required":true,"schema":{"type":"string","description":"The blockchain ID (hex) of the model to get rated bids for, e.g. 0x1234...","title":"Model Id"},"description":"The blockchain ID (hex) of the model to get rated bids for, e.g. 0x1234..."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat/completions":{"post":{"tags":["Chat"],"summary":"Create Chat Completion","description":"Create a chat completion with automatic session creation if enabled.\n\nSupports both streaming and non-streaming responses based on the 'stream' parameter.\nTool calling is supported but may work better with streaming enabled.\n\nBilling is applied to both streaming and non-streaming requests:\n- Balance is checked before the request starts\n- 402 Payment Required is returned if insufficient credits\n- Usage is finalized after completion with actual token counts\n- Holds are voided on failures or disconnects","operationId":"create_chat_completion_api_v1_chat_completions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyAuth":[]}]}},"/api/v1/chat-history/chats":{"post":{"summary":"Create Chat","description":"Create a new chat conversation.","operationId":"create_chat_api_v1_chat_history_chats_post","security":[{"APIKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Get User Chats","description":"Get all chats for the current user.","operationId":"get_user_chats_api_v1_chat_history_chats_get","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Skip"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChatResponse"},"title":"Response Get User Chats Api V1 Chat History Chats Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat-history/chats/{chat_id}":{"get":{"summary":"Get Chat","description":"Get a specific chat with all messages.","operationId":"get_chat_api_v1_chat_history_chats__chat_id__get","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"chat_id","in":"path","required":true,"schema":{"type":"string","title":"Chat Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"summary":"Update Chat","description":"Update chat title.","operationId":"update_chat_api_v1_chat_history_chats__chat_id__put","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"chat_id","in":"path","required":true,"schema":{"type":"string","title":"Chat Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Chat","description":"Delete or archive a chat.","operationId":"delete_chat_api_v1_chat_history_chats__chat_id__delete","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"chat_id","in":"path","required":true,"schema":{"type":"string","title":"Chat Id"}},{"name":"archive_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Archive Only"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat-history/chats/{chat_id}/messages":{"post":{"summary":"Create Message","description":"Add a message to a chat.","operationId":"create_message_api_v1_chat_history_chats__chat_id__messages_post","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"chat_id","in":"path","required":true,"schema":{"type":"string","title":"Chat Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Get Chat Messages","description":"Get messages for a specific chat.","operationId":"get_chat_messages_api_v1_chat_history_chats__chat_id__messages_get","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"chat_id","in":"path","required":true,"schema":{"type":"string","title":"Chat Id"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Skip"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MessageResponse"},"title":"Response Get Chat Messages Api V1 Chat History Chats  Chat Id  Messages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat-history/messages/{message_id}":{"delete":{"summary":"Delete Message","description":"Delete a specific message.","operationId":"delete_message_api_v1_chat_history_messages__message_id__delete","security":[{"APIKeyAuth":[]}],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/embeddings":{"post":{"tags":["Embeddings"],"summary":"Create Embeddings","description":"Create embeddings for the given input text(s).\n\nThis endpoint creates embeddings using the Morpheus Network providers.\nIt automatically manages sessions and routes requests to the appropriate embedding model.\n\nBilling is applied to all requests:\n- Balance is checked before the request starts\n- 402 Payment Required is returned if insufficient credits\n- Usage is finalized after completion with actual token counts\n- Holds are voided on failures","operationId":"create_embeddings_api_v1_embeddings_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyAuth":[]}]}},"/api/v1/audio/transcriptions":{"post":{"tags":["Audio"],"summary":"Create Audio Transcription","description":"Transcribe audio file to text.\n\nThis endpoint transcribes audio files using the Morpheus Network providers.\nIt automatically manages sessions and routes requests to the appropriate transcription model.\n\nSupports both file upload and S3 pre-signed URLs.\nReturns JSON or plain text responses based on response_format parameter.","operationId":"create_audio_transcription_api_v1_audio_transcriptions_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_audio_transcription_api_v1_audio_transcriptions_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyAuth":[]}]}},"/api/v1/audio/speech":{"post":{"tags":["Audio"],"summary":"Create Audio Speech","description":"Generate audio speech from text.\n\nThis endpoint converts text to speech using the Morpheus Network providers.\nIt automatically manages sessions and routes requests to the appropriate TTS model.\n\nReturns binary audio data in the specified format.\n\n**Note:** Swagger UI may not be able to play the audio directly. \nTo test, click \"Download\" and play the file in your media player, \nor use curl to save the audio file.","operationId":"create_audio_speech_api_v1_audio_speech_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioSpeechRequest"}}},"required":true},"responses":{"200":{"description":"Binary audio file","content":{"application/json":{"schema":{}},"audio/mpeg":{"schema":{"type":"string","format":"binary"}},"audio/opus":{"schema":{"type":"string","format":"binary"}},"audio/aac":{"schema":{"type":"string","format":"binary"}},"audio/flac":{"schema":{"type":"string","format":"binary"}},"audio/wav":{"schema":{"type":"string","format":"binary"}},"audio/pcm":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyAuth":[]}]}},"/api/v1/billing/balance":{"get":{"tags":["Billing"],"summary":"Get Balance","description":"Get current credit balance for the authenticated user.\n\nReturns:\n- paid: Paid bucket balance (posted, holds, available)\n- staking: Staking bucket balance (daily amount, refresh date, available)\n- total_available: Sum of all available credits","operationId":"get_balance_api_v1_billing_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/billing/settings/overage":{"put":{"tags":["Billing"],"summary":"Update Overage Setting","description":"Toggle the \"Allow Overages\" setting for the authenticated user.\n\nWhen **enabled** (`allow_overage: true`):\n- If your Daily Staking Allowance is exhausted, the system automatically\n  deducts from your paid Credit Balance to prevent service interruption.\n\nWhen **disabled** (`allow_overage: false`, default):\n- Requests will fail with an `insufficient_balance` error once your\n  Daily Staking Allowance is depleted. Your paid Credit Balance is not touched.","operationId":"update_overage_setting_api_v1_billing_settings_overage_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverageSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverageSettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/billing/transactions":{"get":{"tags":["Billing"],"summary":"List Transactions","description":"Get paginated list of credit transactions (ledger entries).\n\nParameters:\n- limit: Maximum number of items to return (1-∞)\n- offset: Number of items to skip\n- type: Filter by entry type (purchase, usage_charge, refund, etc.)\n- from: Filter entries created after this datetime\n- to: Filter entries created before this datetime\n\nReturns newest entries first.","operationId":"list_transactions_api_v1_billing_transactions_get","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"entry_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/LedgerEntryTypeEnum"},{"type":"null"}],"title":"Entry Type"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LedgerListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/spending":{"get":{"tags":["Billing"],"summary":"Get Monthly Spending","description":"Get monthly spending metrics for a year.\n\nParameters:\n- year: Year to get spending for (defaults to current year)\n- mode: \n  - gross: Only count usage charges\n  - net: Include refunds in calculation\n\nReturns 12 months of data including months with zero spending.","operationId":"get_monthly_spending_api_v1_billing_spending_get","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"year","in":"query","required":false,"schema":{"type":"integer","description":"Year for spending data (defaults to current year)","title":"Year"},"description":"Year for spending data (defaults to current year)"},{"name":"mode","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SpendingModeEnum","default":"gross"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonthlySpendingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/usage":{"get":{"tags":["Billing"],"summary":"List Usage","description":"Get paginated list of usage entries (posted usage charges only).\n\nParameters:\n- limit: Maximum number of items to return (1-∞)\n- offset: Number of items to skip\n- from: Filter entries created after this datetime\n- to: Filter entries created before this datetime\n- model: Filter by model name\n\nReturns newest entries first.","operationId":"list_usage_api_v1_billing_usage_get","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/usage/month":{"get":{"tags":["Billing"],"summary":"List Usage For Month","description":"Get paginated list of usage entries for a specific month.\n\nParameters:\n- year: Year\n- month: Month (1-12)\n- limit: Maximum number of items to return (1-∞)\n- offset: Number of items to skip\n\nReturns newest entries first.","operationId":"list_usage_for_month_api_v1_billing_usage_month_get","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"year","in":"query","required":true,"schema":{"type":"integer","description":"Year","title":"Year"},"description":"Year"},{"name":"month","in":"query","required":true,"schema":{"type":"integer","maximum":12,"minimum":1,"description":"Month (1-12)","title":"Month"},"description":"Month (1-12)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/coinbase/payment-links":{"post":{"tags":["Coinbase Billing"],"summary":"Create Payment Link","description":"Create a Coinbase Business Payment Link for the authenticated user.\n\nCreates a USDC payment link via the Coinbase Business API.\nThe user_id is automatically added to metadata so the webhook\ncan credit the correct account.","operationId":"create_payment_link_api_v1_billing_coinbase_payment_links_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentLinkRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/billing/coinbase/payment-links/{payment_link_id}":{"get":{"tags":["Coinbase Billing"],"summary":"Get Payment Link","description":"Get a specific Coinbase Business Payment Link by ID.","operationId":"get_payment_link_api_v1_billing_coinbase_payment_links__payment_link_id__get","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"payment_link_id","in":"path","required":true,"schema":{"type":"string","title":"Payment Link Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/stripe":{"post":{"tags":["Webhooks"],"summary":"Handle Stripe Webhook","description":"Handle incoming Stripe webhook events.\n\nThis endpoint receives webhook events from Stripe for:\n- checkout.session.completed: Successful one-time payments\n- invoice.paid: Successful subscription/invoice payments\n- invoice.payment_failed: Failed payment attempts\n\nThe endpoint:\n1. Verifies the webhook signature to ensure authenticity\n2. Processes the event based on its type\n3. Stores changes in the database\n4. Returns 200 only AFTER database commit (per user requirement)\n\nNote: This endpoint is public but protected by Stripe signature verification.\nOnly requests signed with the correct webhook secret will be processed.","operationId":"handle_stripe_webhook_api_v1_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/webhooks/coinbase":{"post":{"tags":["Webhooks"],"summary":"Handle Coinbase Webhook","description":"Handle incoming Coinbase webhook events.\n\nSupports both Payment Link API (new) and legacy Commerce Charge API formats.\nAuto-detects the format based on the signature header:\n- X-Hook0-Signature  → Payment Link API (payment_link.payment.*)\n- X-CC-Webhook-Signature → Legacy Commerce (charge:*)\n\nPayment Link event types:\n- payment_link.payment.success: Payment completed successfully\n- payment_link.payment.failed: Payment failed\n- payment_link.payment.expired: Payment link expired\n\nLegacy event types (deprecated):\n- charge:confirmed: Payment confirmed","operationId":"handle_coinbase_webhook_api_v1_webhooks_coinbase_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/wallet/nonce/{wallet_address}":{"post":{"tags":["Auth - Wallet"],"summary":"Generate Wallet Nonce","description":"Generate a nonce for wallet signature verification.\n\nThe frontend should:\n1. Call this endpoint with the wallet address to get a nonce and message template\n2. Construct the message by filling in the template with wallet_address, nonce, and timestamp\n3. Request the user to sign the message with their Web3 wallet\n4. Submit the signature to POST /wallet/link\n\nNonces expire after 5 minutes and can only be used once.","operationId":"generate_wallet_nonce_api_v1_auth_wallet_nonce__wallet_address__post","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"wallet_address","in":"path","required":true,"schema":{"type":"string","description":"Ethereum wallet address to generate nonce for (0x prefixed, 40 hex characters)","title":"Wallet Address"},"description":"Ethereum wallet address to generate nonce for (0x prefixed, 40 hex characters)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NonceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/wallet/link":{"post":{"tags":["Auth - Wallet"],"summary":"Link Wallet","description":"Link a Web3 wallet to the authenticated user's account.\n\n**Requirements:**\n- Valid signature proving wallet ownership (EIP-191 personal_sign)\n- Wallet not already linked to any other account\n- Valid, unexpired nonce from POST /wallet/nonce\n\n**Note:** Users can link multiple wallets to their account.\nEach wallet can only be linked to ONE account in the entire system.","operationId":"link_wallet_api_v1_auth_wallet_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletLinkRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/wallet/":{"get":{"tags":["Auth - Wallet"],"summary":"Get Wallet Status","description":"Get the wallet linking status for the current user.\n\nReturns a list of all linked wallets with their addresses and staked amounts.","operationId":"get_wallet_status_api_v1_auth_wallet__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletStatusResponse"}}}}},"security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}]}},"/api/v1/auth/wallet/{wallet_address}":{"delete":{"tags":["Auth - Wallet"],"summary":"Unlink Wallet","description":"Unlink a wallet from the current user's account.\n\nThis allows the wallet to be linked to a different account.","operationId":"unlink_wallet_api_v1_auth_wallet__wallet_address__delete","security":[{"OAuth2":["aws.cognito.signin.user.admin","openid","email","profile"]},{"BearerAuth":[]}],"parameters":[{"name":"wallet_address","in":"path","required":true,"schema":{"type":"string","description":"Ethereum wallet address to unlink (0x prefixed, 40 hex characters)","title":"Wallet Address"},"description":"Ethereum wallet address to unlink (0x prefixed, 40 hex characters)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletUnlinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/wallet/check/{wallet_address}":{"get":{"tags":["Auth - Wallet"],"summary":"Check Wallet Availability","description":"Check if a wallet address is available to be linked.\n\nThis is a public endpoint that can be called before authentication\nto provide UX feedback to users attempting to link a specific wallet.\n\n**Note:** This endpoint does not require authentication.","operationId":"check_wallet_availability_api_v1_auth_wallet_check__wallet_address__get","parameters":[{"name":"wallet_address","in":"path","required":true,"schema":{"type":"string","description":"Ethereum wallet address to check (0x prefixed, 40 hex characters)","title":"Wallet Address"},"description":"Ethereum wallet address to check (0x prefixed, 40 hex characters)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletAvailabilityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","description":"Root endpoint returning basic API information.","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Health check endpoint with container diagnostics for deployment monitoring.\n\nReturns system health, uptime, and unique container identifier for support and log analysis.\nNote: No sensitive AWS or hostname information is exposed.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/models":{"get":{"summary":"Model Health Check","description":"Detailed model service health check for monitoring and debugging.\n\nReturns comprehensive information about the model fetching service,\ncache status, and available models for operational monitoring.","operationId":"model_health_check_health_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyAuth":[]}]}},"/cors-check":{"get":{"summary":"Cors Check","description":"CORS configuration test endpoint for ALB lb_cookie stickiness verification.\n\nThis endpoint helps verify that CORS is properly configured for cross-origin\nrequests with credentials, which is required for AWS ALB sticky sessions.\n\nReturns CORS configuration details and request information for debugging.","operationId":"cors_check_cors_check_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"APIKeyCreate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","title":"APIKeyCreate","description":"Schema for API key creation request."},"APIKeyDB":{"properties":{"id":{"type":"integer","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_active":{"type":"boolean","title":"Is Active"},"is_default":{"type":"boolean","title":"Is Default","default":false},"encrypted_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Encrypted Key"},"encryption_version":{"type":"integer","title":"Encryption Version","default":1}},"type":"object","required":["id","key_prefix","created_at","is_active"],"title":"APIKeyDB","description":"Schema for API key in database response."},"APIKeyResponse":{"properties":{"key":{"type":"string","title":"Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","required":["key","key_prefix"],"title":"APIKeyResponse","description":"Schema for API key response."},"AgeVerificationRequest":{"properties":{"age_verified":{"type":"boolean","title":"Age Verified","description":"User confirms they are 18 years or older"}},"type":"object","required":["age_verified"],"title":"AgeVerificationRequest","description":"Schema for age verification consent submission.","example":{"age_verified":true}},"AudioSpeechRequest":{"properties":{"input":{"type":"string","title":"Input","description":"Text to convert to speech"},"voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice","description":"Voice to use for speech generation","default":"af_alloy"},"response_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Format","description":"Audio format: mp3, opus, aac, flac, wav, pcm","default":"mp3"},"speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Speed","description":"Speech speed","default":1},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Session ID (auto-created if not provided)"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Model name"}},"type":"object","required":["input"],"title":"AudioSpeechRequest","description":"Request model for audio speech endpoint"},"BalanceResponse":{"properties":{"paid":{"$ref":"#/components/schemas/PaidBalanceInfo"},"staking":{"$ref":"#/components/schemas/StakingBalanceInfo"},"total_available":{"type":"string","title":"Total Available","description":"Total available credits (paid + staking)"},"is_staker":{"type":"boolean","title":"Is Staker","description":"True if user has linked wallets with active MOR stake.","default":false},"allow_overage":{"type":"boolean","title":"Allow Overage","description":"Stakers only. When enabled, the system automatically uses your paid Credit Balance after the Daily Staking Allowance is exhausted, preventing service interruption. When disabled, requests will fail once staking credits are depleted. This setting has no effect for non-stakers.","default":false},"currency":{"type":"string","title":"Currency","description":"Currency code","default":"USD"}},"type":"object","required":["paid","staking","total_available"],"title":"BalanceResponse","description":"Response for GET /billing/balance."},"Body_create_audio_transcription_api_v1_audio_transcriptions_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Audio file to transcribe"},"s3_presigned_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"S3 Presigned Url","description":"Pre-signed S3 URL as alternative to file upload"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"Optional text to guide transcription"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Sampling temperature (0.0-1.0)"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language","description":"Language code (e.g., 'en')"},"response_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Format","description":"Response format: json, text, srt, verbose_json, vtt"},"timestamp_granularities":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timestamp Granularities","description":"Comma-separated: word, segment"},"output_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Content","description":"Output content type"},"enable_diarization":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enable Diarization","description":"Enable speaker diarization","default":false},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Session ID (auto-created if not provided)"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Model name"}},"type":"object","title":"Body_create_audio_transcription_api_v1_audio_transcriptions_post"},"ChatCompletionRequest":{"properties":{"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Messages"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","default":1.0},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","default":1.0},"n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"N","default":1},"stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Stream","default":false},"stop":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stop"},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens"},"presence_penalty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Presence Penalty","default":0.0},"frequency_penalty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Frequency Penalty","default":0.0},"tools":{"anyOf":[{"items":{"$ref":"#/components/schemas/Tool"},"type":"array"},{"type":"null"}],"title":"Tools"},"tool_choice":{"anyOf":[{"type":"string"},{"$ref":"#/components/schemas/ToolChoice"},{"type":"null"}],"title":"Tool Choice"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Optional session ID to use for this request. If not provided, the system will use the session associated with the API key."}},"type":"object","required":["messages"],"title":"ChatCompletionRequest","description":"Request payload for chat completions.\n\nNote: Field defaults and names must remain unchanged for API parity."},"ChatCreate":{"properties":{"title":{"type":"string","maxLength":200,"title":"Title","description":"Chat title"}},"type":"object","required":["title"],"title":"ChatCreate"},"ChatDetailResponse":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"messages":{"items":{"$ref":"#/components/schemas/MessageResponse"},"type":"array","title":"Messages","default":[]}},"type":"object","required":["id","title","created_at","updated_at"],"title":"ChatDetailResponse"},"ChatMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"anyOf":[{"type":"string"},{"items":{"anyOf":[{"$ref":"#/components/schemas/ContentPartText"},{"$ref":"#/components/schemas/ContentPartImageUrl"},{"$ref":"#/components/schemas/ContentPartInputAudio"},{"$ref":"#/components/schemas/ContentPartFile"}]},"type":"array"},{"type":"null"}],"title":"Content"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"tool_calls":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Tool Calls"},"tool_call_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Call Id"}},"type":"object","required":["role"],"title":"ChatMessage","description":"Represents a single chat message in the OpenAI-compatible schema.\n\nContent can be either a string or a list of content parts (for multimodal inputs)."},"ChatResponse":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"message_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Message Count"}},"type":"object","required":["id","title","created_at","updated_at"],"title":"ChatResponse"},"ChatUpdate":{"properties":{"title":{"type":"string","maxLength":200,"title":"Title","description":"Updated chat title"}},"type":"object","required":["title"],"title":"ChatUpdate"},"ContentPartFile":{"properties":{"type":{"type":"string","title":"Type","default":"file"},"file":{"$ref":"#/components/schemas/FileData"}},"type":"object","required":["file"],"title":"ContentPartFile","description":"File content part for multimodal messages."},"ContentPartImageUrl":{"properties":{"type":{"type":"string","title":"Type","default":"image_url"},"image_url":{"$ref":"#/components/schemas/ImageUrl"}},"type":"object","required":["image_url"],"title":"ContentPartImageUrl","description":"Image URL content part for multimodal messages."},"ContentPartInputAudio":{"properties":{"type":{"type":"string","title":"Type","default":"input_audio"},"input_audio":{"$ref":"#/components/schemas/InputAudio"}},"type":"object","required":["input_audio"],"title":"ContentPartInputAudio","description":"Audio content part for multimodal messages."},"ContentPartText":{"properties":{"type":{"type":"string","title":"Type","default":"text"},"text":{"type":"string","title":"Text"}},"type":"object","required":["text"],"title":"ContentPartText","description":"Text content part for multimodal messages."},"CreatePaymentLinkRequest":{"properties":{"amount":{"type":"string","title":"Amount","description":"Payment amount (e.g., '100.00')"},"currency":{"type":"string","title":"Currency","description":"Currency code (currently only USDC)","default":"USDC"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Key-value pairs passed through the payment flow"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Description shown on the payment page"},"success_redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Success Redirect Url","description":"HTTPS URL to redirect on success"},"failure_redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Redirect Url","description":"HTTPS URL to redirect on failure"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At","description":"ISO 8601 timestamp when the link expires"}},"type":"object","required":["amount"],"title":"CreatePaymentLinkRequest","description":"Request to create a new Coinbase Payment Link."},"EmbeddingObject":{"properties":{"object":{"type":"string","title":"Object","default":"embedding"},"embedding":{"items":{"type":"number"},"type":"array","title":"Embedding"},"index":{"type":"integer","title":"Index"}},"type":"object","required":["embedding","index"],"title":"EmbeddingObject","description":"Individual embedding object"},"EmbeddingRequest":{"properties":{"input":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Input"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"encoding_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Encoding Format","default":"float"},"dimensions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dimensions"},"user":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"type":"object","required":["input"],"title":"EmbeddingRequest","description":"Request model for embeddings endpoint"},"EmbeddingResponse":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"data":{"items":{"$ref":"#/components/schemas/EmbeddingObject"},"type":"array","title":"Data"},"model":{"type":"string","title":"Model"},"usage":{"$ref":"#/components/schemas/EmbeddingUsage"}},"type":"object","required":["data","model","usage"],"title":"EmbeddingResponse","description":"Response model for embeddings endpoint"},"EmbeddingUsage":{"properties":{"prompt_tokens":{"type":"integer","title":"Prompt Tokens"},"total_tokens":{"type":"integer","title":"Total Tokens"}},"type":"object","required":["prompt_tokens","total_tokens"],"title":"EmbeddingUsage","description":"Usage statistics for embedding request"},"FileData":{"properties":{"file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Id"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"file_data":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Data"}},"type":"object","title":"FileData","description":"File reference for file content parts."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImageUrl":{"properties":{"url":{"type":"string","title":"Url"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["url"],"title":"ImageUrl","description":"Image URL for vision content parts."},"InputAudio":{"properties":{"data":{"type":"string","title":"Data"},"format":{"type":"string","title":"Format"}},"type":"object","required":["data","format"],"title":"InputAudio","description":"Audio data for input_audio content parts."},"LedgerEntryResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"integer","title":"User Id"},"currency":{"type":"string","title":"Currency"},"status":{"$ref":"#/components/schemas/LedgerStatusEnum"},"entry_type":{"$ref":"#/components/schemas/LedgerEntryTypeEnum"},"amount_paid":{"type":"string","title":"Amount Paid"},"amount_staking":{"type":"string","title":"Amount Staking"},"amount_total":{"type":"string","title":"Amount Total"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Key"},"related_entry_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Related Entry Id"},"payment_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Source"},"external_transaction_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Transaction Id"},"payment_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Payment Metadata"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id"},"api_key_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Api Key Id"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"model_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Id"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"tokens_input":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens Input"},"tokens_output":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens Output"},"tokens_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens Total"},"input_price_per_million":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Price Per Million"},"output_price_per_million":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Price Per Million"},"failure_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Code"},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","user_id","currency","status","entry_type","amount_paid","amount_staking","amount_total","created_at","updated_at"],"title":"LedgerEntryResponse","description":"Response for a single ledger entry."},"LedgerEntryTypeEnum":{"type":"string","enum":["purchase","staking_refresh","usage_hold","usage_charge","refund","adjustment"],"title":"LedgerEntryTypeEnum","description":"Ledger entry type."},"LedgerListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/LedgerEntryResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["items","total","limit","offset","has_more"],"title":"LedgerListResponse","description":"Paginated response for ledger entries."},"LedgerStatusEnum":{"type":"string","enum":["pending","posted","voided"],"title":"LedgerStatusEnum","description":"Ledger entry status."},"ManualTopupRequest":{"properties":{"amount_usd":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Amount Usd","description":"Amount to adjust in USD (positive to add, negative to subtract)"},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Description","description":"Optional description/reason for adjustment"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id","description":"Target user ID (database primary key). If not provided, adjusts current user's credits."},"cognito_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Cognito User Id","description":"Target Cognito user ID. Alternative to user_id."}},"type":"object","required":["amount_usd"],"title":"ManualTopupRequest","description":"Request for POST /billing/credits/adjust."},"ManualTopupResponse":{"properties":{"ledger_entry_id":{"type":"string","format":"uuid","title":"Ledger Entry Id"},"amount_added":{"type":"string","title":"Amount Added"},"new_paid_balance":{"type":"string","title":"New Paid Balance"},"message":{"type":"string","title":"Message","default":"Credits added successfully"}},"type":"object","required":["ledger_entry_id","amount_added","new_paid_balance"],"title":"ManualTopupResponse","description":"Response for manual credit top-up."},"MessageCreate":{"properties":{"role":{"type":"string","title":"Role","description":"Message role: 'user' or 'assistant'"},"content":{"type":"string","title":"Content","description":"Message content"},"tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens","description":"Token count for billing"}},"type":"object","required":["role","content"],"title":"MessageCreate"},"MessageResponse":{"properties":{"id":{"type":"string","title":"Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"sequence":{"type":"integer","title":"Sequence"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens"}},"type":"object","required":["id","role","content","sequence","created_at"],"title":"MessageResponse"},"MonthlySpending":{"properties":{"year":{"type":"integer","title":"Year"},"month":{"type":"integer","title":"Month"},"amount":{"type":"string","title":"Amount","description":"Spending amount (negative)"},"transaction_count":{"type":"integer","title":"Transaction Count","description":"Number of transactions","default":0}},"type":"object","required":["year","month","amount"],"title":"MonthlySpending","description":"Spending for a single month."},"MonthlySpendingResponse":{"properties":{"year":{"type":"integer","title":"Year"},"mode":{"$ref":"#/components/schemas/SpendingModeEnum"},"months":{"items":{"$ref":"#/components/schemas/MonthlySpending"},"type":"array","title":"Months","description":"12 months of spending data"},"total":{"type":"string","title":"Total","description":"Total spending for the year"},"currency":{"type":"string","title":"Currency","default":"USD"}},"type":"object","required":["year","mode","total"],"title":"MonthlySpendingResponse","description":"Response for GET /billing/spending."},"NonceResponse":{"properties":{"nonce":{"type":"string","maxLength":64,"minLength":64,"title":"Nonce","description":"Cryptographic nonce (64 hex characters)"},"message_template":{"type":"string","title":"Message Template","description":"Template for constructing the message to sign. Replace {wallet_address}, {nonce}, and {timestamp} with actual values."},"expires_in":{"type":"integer","title":"Expires In","description":"Number of seconds until the nonce expires","default":300}},"type":"object","required":["nonce","message_template"],"title":"NonceResponse","description":"Response containing a nonce for wallet signature verification."},"OverageSettingsRequest":{"properties":{"allow_overage":{"type":"boolean","title":"Allow Overage","description":"When enabled, the system automatically uses your paid Credit Balance after the Daily Staking Allowance is exhausted. When disabled, requests will fail once staking credits are depleted."}},"type":"object","required":["allow_overage"],"title":"OverageSettingsRequest","description":"Request for PUT /billing/settings/overage."},"OverageSettingsResponse":{"properties":{"allow_overage":{"type":"boolean","title":"Allow Overage"},"message":{"type":"string","title":"Message"}},"type":"object","required":["allow_overage","message"],"title":"OverageSettingsResponse","description":"Response for overage settings update."},"PaidBalanceInfo":{"properties":{"posted_balance":{"type":"string","title":"Posted Balance","description":"Posted paid credits balance"},"pending_holds":{"type":"string","title":"Pending Holds","description":"Pending holds (negative)"},"available":{"type":"string","title":"Available","description":"Available paid credits (posted + holds)"}},"type":"object","required":["posted_balance","pending_holds","available"],"title":"PaidBalanceInfo","description":"Paid bucket balance details."},"PaymentLinkListResponse":{"properties":{"paymentLinks":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Paymentlinks"},"nextPageToken":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextpagetoken"}},"type":"object","title":"PaymentLinkListResponse","description":"Paginated list of payment links."},"PaymentLinkResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Payment link ID (24-char hex)"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"Payment link URL"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"ACTIVE, COMPLETED, EXPIRED, or DEACTIVATED"},"amount":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amount"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"createdAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Createdat"},"updatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updatedat"},"expiresAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expiresat"}},"type":"object","required":["id"],"title":"PaymentLinkResponse","description":"Response from the Coinbase Payment Link API."},"RateLimitMultiplierRequest":{"properties":{"cognito_user_id":{"type":"string","title":"Cognito User Id","description":"Target user's Cognito ID (UUID)"},"multiplier":{"type":"number","maximum":100.0,"exclusiveMinimum":0.0,"title":"Multiplier","description":"Rate limit multiplier (1.0 = default, 2.0 = double limits, 0.5 = half limits)"}},"type":"object","required":["cognito_user_id","multiplier"],"title":"RateLimitMultiplierRequest","description":"Request for POST /billing/rate-limit/multiplier."},"RateLimitMultiplierResponse":{"properties":{"cognito_user_id":{"type":"string","title":"Cognito User Id"},"user_id":{"type":"integer","title":"User Id"},"multiplier":{"type":"number","title":"Multiplier"},"message":{"type":"string","title":"Message"}},"type":"object","required":["cognito_user_id","user_id","multiplier","message"],"title":"RateLimitMultiplierResponse","description":"Response for rate limit multiplier operations."},"SpendingModeEnum":{"type":"string","enum":["gross","net"],"title":"SpendingModeEnum","description":"Spending calculation mode."},"StakingBalanceInfo":{"properties":{"daily_amount":{"type":"string","title":"Daily Amount","description":"Configured daily staking allowance"},"refresh_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Refresh Date","description":"Last staking refresh date"},"available":{"type":"string","title":"Available","description":"Currently available staking credits"}},"type":"object","required":["daily_amount","available"],"title":"StakingBalanceInfo","description":"Staking bucket balance details."},"StakingRefreshResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether the sync completed successfully","default":true},"message":{"type":"string","title":"Message"},"stakers_fetched":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stakers Fetched","description":"Number of stakers fetched from Builders API"},"total_wallets":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Wallets","description":"Total linked wallets in system"},"wallets_updated":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wallets Updated","description":"Wallets with stake changes"},"users_processed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Users Processed","description":"Users with balance updated"},"users_skipped":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Users Skipped","description":"Users already refreshed today"},"users_failed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Users Failed","description":"Users that failed to sync"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds","description":"Sync duration in seconds"}},"type":"object","required":["message"],"title":"StakingRefreshResponse","description":"Response for POST /billing/staking/refresh."},"StakingSettingsRequest":{"properties":{"daily_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Daily Amount","description":"Daily staking allowance amount"}},"type":"object","required":["daily_amount"],"title":"StakingSettingsRequest","description":"Request for POST /billing/staking/settings."},"StakingSettingsResponse":{"properties":{"daily_amount":{"type":"string","title":"Daily Amount"},"message":{"type":"string","title":"Message","default":"Staking daily amount updated"}},"type":"object","required":["daily_amount"],"title":"StakingSettingsResponse","description":"Response for staking settings update."},"Tool":{"properties":{"type":{"type":"string","title":"Type","default":"function"},"function":{"$ref":"#/components/schemas/ToolFunction"}},"type":"object","required":["function"],"title":"Tool","description":"Tool wrapper for function-based tools (OpenAI-compatible)."},"ToolChoice":{"properties":{"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","default":"function"},"function":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Function"}},"type":"object","title":"ToolChoice","description":"Explicit tool selection for tool calling."},"ToolFunction":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters","default":{}}},"type":"object","required":["name"],"title":"ToolFunction","description":"Function definition for tool calling."},"UsageEntryResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"model_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Id"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"tokens_input":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens Input"},"tokens_output":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens Output"},"tokens_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tokens Total"},"amount_paid":{"type":"string","title":"Amount Paid"},"amount_staking":{"type":"string","title":"Amount Staking"},"amount_total":{"type":"string","title":"Amount Total"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id"},"api_key_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Api Key Id"}},"type":"object","required":["id","created_at","amount_paid","amount_staking","amount_total"],"title":"UsageEntryResponse","description":"Single usage entry for usage list."},"UsageListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/UsageEntryResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["items","total","limit","offset","has_more"],"title":"UsageListResponse","description":"Paginated response for usage entries."},"UserDeletionResponse":{"properties":{"message":{"type":"string","title":"Message"},"deleted_data":{"additionalProperties":true,"type":"object","title":"Deleted Data"},"cognito_deletion":{"additionalProperties":true,"type":"object","title":"Cognito Deletion"},"user_id":{"type":"integer","title":"User Id"},"deleted_at":{"type":"string","format":"date-time","title":"Deleted At"}},"type":"object","required":["message","deleted_data","cognito_deletion","user_id","deleted_at"],"title":"UserDeletionResponse","description":"Schema for user deletion response","example":{"cognito_deletion":{"cognito_user_id":"abc123-def456-ghi789","message":"User successfully deleted from Cognito","success":true},"deleted_at":"2024-01-01T12:00:00Z","deleted_data":{"api_keys":3,"automation_settings":true,"delegations":0,"private_key":true,"sessions":2},"message":"User account successfully deleted","user_id":123}},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WalletAvailabilityResponse":{"properties":{"wallet_address":{"type":"string","title":"Wallet Address","description":"The wallet address that was checked (checksummed)"},"is_available":{"type":"boolean","title":"Is Available","description":"Whether the wallet is available to be linked"}},"type":"object","required":["wallet_address","is_available"],"title":"WalletAvailabilityResponse","description":"Response indicating whether a wallet address is available."},"WalletLinkRequest":{"properties":{"wallet_address":{"type":"string","maxLength":42,"minLength":42,"title":"Wallet Address","description":"Ethereum wallet address (0x prefixed, 40 hex characters)"},"signature":{"type":"string","title":"Signature","description":"EIP-191 signature of the message (0x prefixed hex string)"},"message":{"type":"string","title":"Message","description":"The exact message that was signed"},"nonce":{"type":"string","maxLength":64,"minLength":64,"title":"Nonce","description":"The nonce received from POST /wallet/nonce"},"timestamp":{"type":"string","title":"Timestamp","description":"ISO 8601 timestamp when the message was constructed"}},"type":"object","required":["wallet_address","signature","message","nonce","timestamp"],"title":"WalletLinkRequest","description":"Request to link a Web3 wallet to the user's account."},"WalletLinkResponse":{"properties":{"id":{"type":"integer","title":"Id","description":"Wallet link ID"},"wallet_address":{"type":"string","title":"Wallet Address","description":"The linked wallet address (checksummed)"},"staked_amount":{"type":"string","title":"Staked Amount","description":"Staked MOR amount in wei (as string for precision)","default":"0"},"linked_at":{"type":"string","format":"date-time","title":"Linked At","description":"Timestamp when the wallet was linked"},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"Timestamp when the wallet was last updated"}},"type":"object","required":["id","wallet_address","linked_at","updated_at"],"title":"WalletLinkResponse","description":"Response after successfully linking a wallet."},"WalletStatusResponse":{"properties":{"has_wallets":{"type":"boolean","title":"Has Wallets","description":"Whether the user has any wallets linked"},"wallet_count":{"type":"integer","title":"Wallet Count","description":"Number of linked wallets"},"total_staked":{"type":"string","title":"Total Staked","description":"Total staked MOR amount across all wallets in wei (as string)","default":"0"},"wallets":{"items":{"$ref":"#/components/schemas/WalletLinkResponse"},"type":"array","title":"Wallets","description":"List of linked wallets"}},"type":"object","required":["has_wallets","wallet_count"],"title":"WalletStatusResponse","description":"Response containing the user's wallet linking status."},"WalletUnlinkResponse":{"properties":{"message":{"type":"string","title":"Message","description":"Success message"},"wallet_address":{"type":"string","title":"Wallet Address","description":"The unlinked wallet address"}},"type":"object","required":["message","wallet_address"],"title":"WalletUnlinkResponse","description":"Response after unlinking a wallet."}},"securitySchemes":{"OAuth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://auth.mor.org/oauth2/authorize","tokenUrl":"https://auth.mor.org/oauth2/token","scopes":{"aws.cognito.signin.user.admin":"Read own user attributes (GetUser)","openid":"OpenID Connect authentication","email":"Access to email address","profile":"Access to profile information"}}},"description":"🚀 OAuth2 authentication via secure identity provider"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"🎫 JWT Bearer token from OAuth2 login or direct token"},"APIKeyAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"🗝️ API key in format: 'Bearer sk-xxxxxx'"}}},"servers":[]}