{"openapi":"3.1.0","info":{"title":"Beeble Developer API","description":"API for SwitchX video-to-video compositing and media uploads.","version":"1.0.0"},"paths":{"/v1/account/billing":{"get":{"tags":["account"],"summary":"Get Billing Info","description":"Get billing period details and per-meter usage breakdown.","operationId":"get_account_billing_v1_account_billing_get","parameters":[],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountBillingResponse"}}}}}}},"/v1/account/info":{"get":{"tags":["account"],"summary":"Get Account Info","description":"Get account metadata and current rate limit usage.","operationId":"get_account_info_v1_account_info_get","parameters":[],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInfoResponse"}}}}}}},"/v1/admin/accounts":{"get":{"tags":["admin"],"summary":"Admin: List developer API accounts","operationId":"list_accounts_v1_admin_accounts_get","parameters":[{"name":"email_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Email Contains"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"User Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Cursor"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountListResponse"}}}}}}},"/v1/admin/accounts/{user_id}":{"get":{"tags":["admin"],"summary":"Get Account","description":"View full account configuration.","operationId":"get_account_v1_admin_accounts__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountResponse"}}}}}}},"/v1/admin/accounts/{user_id}/auto-charge":{"put":{"tags":["admin"],"summary":"Update Auto Charge","description":"Update a user's auto-charge settings.","operationId":"update_auto_charge_v1_admin_accounts__user_id__auto_charge_put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAutoChargeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountResponse"}}}}}}},"/v1/admin/accounts/{user_id}/billing":{"get":{"tags":["admin"],"summary":"Admin: Get account billing usage","description":"Admin variant of /account/billing — fetches Stripe meter usage for\nany user_id. Slow path (Stripe round-trip).","operationId":"get_account_billing_admin_v1_admin_accounts__user_id__billing_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountBillingResponse"}}}}}}},"/v1/admin/accounts/{user_id}/billing-type":{"put":{"tags":["admin"],"summary":"Update Billing Type","description":"Flip a user's BillingType column.\n\nOnly mutates the DynamoDB field. Stripe subscription state, BalanceCents,\nand auto-charge settings are NOT touched — the operator handles any\nStripe-side cleanup separately.","operationId":"update_billing_type_v1_admin_accounts__user_id__billing_type_put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillingTypeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountResponse"}}}}}}},"/v1/admin/accounts/{user_id}/rate-limits":{"put":{"tags":["admin"],"summary":"Update Rate Limits","description":"Update a user's rate limits.\n\nDistinguishes \"field not in request\" from \"explicit null\":\n- field absent → leave the stored value untouched\n- field present and null → reset to type defaults (clear the stored value)\n- field present and numeric → set to that number","operationId":"update_rate_limits_v1_admin_accounts__user_id__rate_limits_put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRateLimitsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountResponse"}}}}}}},"/v1/admin/accounts/{user_id}/spending-limit":{"put":{"tags":["admin"],"summary":"Update Spending Limit","description":"Update a user's per-period spending limit.\n\n- field absent → no-op\n- field null → reset to billing-type default\n- field number → set to that dollar amount","operationId":"update_spending_limit_v1_admin_accounts__user_id__spending_limit_put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSpendingLimitRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountResponse"}}}}}}},"/v1/api-keys":{"get":{"tags":["api-keys"],"summary":"List Api Keys","description":"List all API keys for the authenticated user.","operationId":"list_api_keys_v1_api_keys_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}}}},"post":{"tags":["api-keys"],"summary":"Create Api Key","description":"Create a new API key for the authenticated user.","operationId":"create_api_key_v1_api_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}}}}},"/v1/api-keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke Api Key","description":"Revoke an API key by its ID.","operationId":"revoke_api_key_v1_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRevokeResponse"}}}}}}},"/v1/billing/accept-terms":{"post":{"tags":["billing"],"summary":"Accept Terms","description":"Re-accept updated Terms of Service for an existing developer account.\n\nLightweight endpoint — updates only TosAcceptedAt and TosVersion.\nDoes NOT touch Stripe or billing configuration.\nIdempotent — no-op if TosVersion already matches current version.","operationId":"accept_terms_v1_billing_accept_terms_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsResponse"}}}}}}},"/v1/billing/account-status":{"get":{"tags":["billing"],"summary":"Get Account Status","description":"Check if the authenticated user has a developer account with accepted Terms of Service.","operationId":"get_account_status_v1_billing_account_status_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountStatusResponse"}}}}}}},"/v1/billing/auto-recharge":{"get":{"tags":["billing"],"summary":"Get Auto Recharge Settings","description":"Get current auto-recharge configuration.","operationId":"get_auto_recharge_settings_v1_billing_auto_recharge_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRechargeSettingsResponse"}}}}}},"put":{"tags":["billing"],"summary":"Update Auto Recharge Settings","description":"Update auto-recharge settings.\n\nWhen enabling, threshold_cents and amount_cents are required.\npayment_method_id is optional — auto-selects default if omitted.\nRejects postpaid users.","operationId":"update_auto_recharge_settings_v1_billing_auto_recharge_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRechargeUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRechargeSettingsResponse"}}}}}}},"/v1/billing/credit-balance":{"get":{"tags":["billing"],"summary":"Get Credit Balance","description":"Get real-time credit balance for the authenticated user.","operationId":"get_credit_balance_v1_billing_credit_balance_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalanceResponse"}}}}}}},"/v1/billing/credit-purchase":{"post":{"tags":["billing"],"summary":"Create Credit Purchase","description":"Create a checkout session for purchasing API credits.","operationId":"create_credit_purchase_v1_billing_credit_purchase_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditPurchaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditPurchaseResponse"}}}}}}},"/v1/billing/credit-purchase/fulfill":{"post":{"tags":["billing"],"summary":"Fulfill Credit Purchase","description":"Fulfill a completed credit purchase and add credits to your balance.\n\nIdempotent — safe to call multiple times for the same session.","operationId":"fulfill_credit_purchase_v1_billing_credit_purchase_fulfill_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditFulfillRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditFulfillResponse"}}}}}}},"/v1/billing/payment-methods":{"get":{"tags":["billing"],"summary":"Get Payment Methods","description":"List payment methods for the developer's Stripe customer.","operationId":"get_payment_methods_v1_billing_payment_methods_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodsResponse"}}}}}}},"/v1/billing/signup":{"post":{"tags":["billing"],"summary":"Signup","description":"Create a developer account after accepting Terms of Service.\n\nSets up billing and initializes your account.\nIdempotent — returns existing account if already created.","operationId":"signup_v1_billing_signup_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSignupRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSignupResponse"}}}}}}},"/v1/billing/subscription/reactivate":{"post":{"tags":["billing"],"summary":"Reactivate Subscription","description":"Reactivate a fully canceled metered subscription by creating a new one.\n\nOnly applies when the subscription is fully canceled or no subscription exists.\nIf an active subscription exists (including scheduled cancellation), returns 409.","operationId":"reactivate_subscription_v1_billing_subscription_reactivate_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionActionResponse"}}}}}}},"/v1/billing/subscription/undo-cancel":{"post":{"tags":["billing"],"summary":"Undo Subscription Cancellation","description":"Remove scheduled cancellation from an active metered subscription.\n\nOnly applies when the subscription is active with cancel_at_period_end=True.","operationId":"undo_subscription_cancellation_v1_billing_subscription_undo_cancel_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionActionResponse"}}}}}}},"/v1/billing/usage-summary":{"get":{"tags":["billing"],"summary":"Get Usage Summary","description":"Get usage summary with per-meter and daily breakdowns.\n\nIf start_date/end_date are provided (ISO format 'YYYY-MM-DD'), returns usage\nfor that specific range. Otherwise, defaults to the current calendar month.","operationId":"get_usage_summary_v1_billing_usage_summary_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Date"}},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"End Date"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummaryResponse"}}}}}}},"/v1/switchx/generations":{"get":{"tags":["switchx"],"summary":"List Jobs","description":"List your SwitchX jobs with cursor-based pagination.","operationId":"list_switchx_jobs_v1_switchx_generations_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of items per page","default":20,"title":"Limit"},"description":"Number of items per page"},{"name":"page_token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pagination token","title":"Page Token"},"description":"Pagination token"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchXListResponse"}}}}}},"post":{"tags":["switchx"],"summary":"Start Generation","description":"Start a SwitchX compositing job.","operationId":"create_switchx_job_v1_switchx_generations_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSwitchXRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchXStatusResponse"}}}}}}},"/v1/switchx/generations/{job_id}":{"get":{"tags":["switchx"],"summary":"Get Job Status","description":"Poll the status of a SwitchX job.","operationId":"get_switchx_status_v1_switchx_generations__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchXStatusResponse"}}}}}}},"/v1/uploads":{"post":{"tags":["uploads"],"summary":"Create Upload URL","description":"Create a presigned upload URL for a media file.","operationId":"create_upload_v1_uploads_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResponse"}}}}}}}},"components":{"schemas":{"AcceptTermsRequest":{"properties":{"tos_accepted":{"type":"boolean","title":"Tos Accepted","description":"Must be True to accept terms"}},"type":"object","required":["tos_accepted"],"title":"AcceptTermsRequest","description":"Request to re-accept updated Terms of Service."},"AcceptTermsResponse":{"properties":{"status":{"type":"string","title":"Status"},"tos_version":{"type":"string","title":"Tos Version"}},"type":"object","required":["status","tos_version"],"title":"AcceptTermsResponse","description":"Response from terms acceptance."},"AccountBillingResponse":{"properties":{"billing_period_start":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Billing Period Start","description":"Billing period start (Unix timestamp)","examples":[1711929600]},"billing_period_end":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Billing Period End","description":"Billing period end (Unix timestamp)","examples":[1714521600]},"prepaid_balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prepaid Balance","description":"Prepaid balance in dollars","examples":[247.5]},"current_period_usage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Period Usage","description":"Total usage cost in current period in dollars","examples":[89.4]},"meters":{"items":{"$ref":"#/components/schemas/models__account__MeterUsage"},"type":"array","title":"Meters","description":"Per-meter usage breakdown"}},"type":"object","title":"AccountBillingResponse","description":"Current billing period details including usage breakdown and balance."},"AccountInfoResponse":{"properties":{"email":{"type":"string","title":"Email","description":"Account email address"},"billing_type":{"type":"string","title":"Billing Type","description":"'prepaid' or 'postpaid'","default":"prepaid"},"spending_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spending Limit","description":"Spending limit per billing period in dollars","examples":[5000]},"rate_limits":{"$ref":"#/components/schemas/AccountRateLimits","description":"Rate limits and current usage"}},"type":"object","required":["email"],"title":"AccountInfoResponse","description":"Account metadata including billing type, spending limits, and real-time rate limit usage."},"AccountRateLimits":{"properties":{"rpm":{"$ref":"#/components/schemas/RateLimitInfo","description":"Requests per minute"},"concurrency":{"$ref":"#/components/schemas/RateLimitInfo","description":"Concurrent requests"}},"type":"object","title":"AccountRateLimits","description":"Current rate limits and real-time usage counters."},"AccountSignupRequest":{"properties":{"tos_accepted":{"type":"boolean","title":"Tos Accepted","description":"Must be True to create account"}},"type":"object","required":["tos_accepted"],"title":"AccountSignupRequest","description":"Request to create a developer account after accepting Terms of Service."},"AccountSignupResponse":{"properties":{"status":{"type":"string","title":"Status"},"billing_type":{"type":"string","title":"Billing Type"},"balance_cents":{"type":"integer","title":"Balance Cents","examples":[0]}},"type":"object","required":["status","billing_type","balance_cents"],"title":"AccountSignupResponse"},"AccountStatusResponse":{"properties":{"has_account":{"type":"boolean","title":"Has Account"},"tos_accepted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tos Accepted At"},"tos_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tos Version"},"tos_current":{"type":"boolean","title":"Tos Current","description":"True when accepted terms match current version","default":false},"billing_type":{"type":"string","enum":["prepaid","postpaid"],"title":"Billing Type","description":"Billing type","default":"prepaid"},"spending_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spending Limit","description":"Spending limit per billing period in dollars","examples":[5000]},"subscription_status":{"type":"string","enum":["active","scheduled_cancel","canceled","none"],"title":"Subscription Status","description":"Metered subscription status","default":"none"},"cancel_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancel At","description":"ISO 8601 date when subscription will be canceled (scheduled_cancel only)"}},"type":"object","required":["has_account"],"title":"AccountStatusResponse","description":"Whether the user has a developer account with accepted ToS."},"AdminAccountListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AdminAccountSummary"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque cursor; pass to next call as `cursor=...`"}},"type":"object","title":"AdminAccountListResponse","description":"Paginated response for `GET /admin/accounts`."},"AdminAccountResponse":{"properties":{"user_id":{"type":"string","title":"User Id","description":"User ID"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"Account email"},"billing_type":{"type":"string","title":"Billing Type","description":"'prepaid' or 'postpaid'","default":"prepaid"},"spending_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spending Limit","description":"Spending limit per period in dollars"},"balance_dollars":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Balance Dollars","description":"Prepaid shadow balance (dollars)"},"rate_limits":{"$ref":"#/components/schemas/AccountRateLimits"},"auto_charge":{"$ref":"#/components/schemas/AutoChargeInfo"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At","description":"Account creation timestamp"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"Last update timestamp"}},"type":"object","required":["user_id"],"title":"AdminAccountResponse","description":"Full account info for admin view."},"AdminAccountSummary":{"properties":{"user_id":{"type":"string","title":"User Id","description":"User ID (Firebase UID or Clerk sub)"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"Account email"},"billing_type":{"type":"string","title":"Billing Type","description":"'prepaid' or 'postpaid'","default":"prepaid"},"spending_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spending Limit","description":"Spending limit per period in dollars"},"balance_dollars":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Balance Dollars","description":"Prepaid shadow balance (dollars)"},"rpm_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rpm Limit","description":"RPM limit"},"concurrency_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Concurrency Limit","description":"Concurrency limit"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At","description":"Account creation timestamp"}},"type":"object","required":["user_id"],"title":"AdminAccountSummary","description":"Compact account row for the admin list view (no Stripe call)."},"AlphaMode":{"type":"string","enum":["auto","fill","custom","select"],"title":"AlphaMode"},"ApiKeyCreateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Optional display name for the key"}},"type":"object","title":"ApiKeyCreateRequest","description":"Request to create a new API key."},"ApiKeyCreateResponse":{"properties":{"key_id":{"type":"string","title":"Key Id"},"api_key":{"type":"string","title":"Api Key","description":"Full API key, shown only once at creation"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["key_id","api_key","name","created_at"],"title":"ApiKeyCreateResponse","description":"Response after creating an API key. Full key shown only once."},"ApiKeyItem":{"properties":{"key_id":{"type":"string","title":"Key Id"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","title":"Created At"},"hint":{"type":"string","title":"Hint","description":"Last 4 chars of the key"}},"type":"object","required":["key_id","name","created_at","hint"],"title":"ApiKeyItem","description":"API key metadata (never includes the full key or hash)."},"ApiKeyListResponse":{"properties":{"keys":{"items":{"$ref":"#/components/schemas/ApiKeyItem"},"type":"array","title":"Keys"}},"type":"object","required":["keys"],"title":"ApiKeyListResponse","description":"List of API keys for the user."},"ApiKeyRevokeResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"ApiKeyRevokeResponse","description":"Response after revoking an API key."},"AutoChargeInfo":{"properties":{"enabled":{"type":"boolean","title":"Enabled","description":"Whether auto-charge is enabled","default":false},"threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Threshold","description":"Balance threshold"},"amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount","description":"Top-up amount"}},"type":"object","title":"AutoChargeInfo","description":"Auto-charge configuration."},"AutoRechargeSettingsResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"threshold_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Threshold Cents","examples":[1000]},"amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Cents","examples":[5000]},"payment_method_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Method Id"},"consecutive_failures":{"type":"integer","title":"Consecutive Failures","default":0,"examples":[0]},"last_failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Failure Reason"}},"type":"object","title":"AutoRechargeSettingsResponse","description":"Current auto-recharge configuration."},"AutoRechargeUpdateRequest":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"threshold_cents":{"anyOf":[{"type":"integer","maximum":500000.0,"minimum":500.0},{"type":"null"}],"title":"Threshold Cents","examples":[1000]},"amount_cents":{"anyOf":[{"type":"integer","maximum":500000.0,"minimum":1000.0},{"type":"null"}],"title":"Amount Cents","examples":[5000]},"payment_method_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Method Id"}},"type":"object","title":"AutoRechargeUpdateRequest","description":"Request to update auto-recharge settings."},"CreateSwitchXRequest":{"properties":{"generation_type":{"$ref":"#/components/schemas/GenerationType","description":"Output type: 'image' or 'video'","examples":["video"]},"source_uri":{"type":"string","title":"Source Uri","description":"URI of the source image or video.\n\n**Accepted URI types:**\n\n| Scheme | Description |\n|--------|-------------|\n| `beeble://uploads/{id}/{filename}` | From the [Uploads endpoint](/api-reference/uploads/create-upload-url) |\n| `https://...` | External URL |\n| `data:{mime};base64,...` | Inline base64 (max 50 MB) |\n\n**Accepted formats:**\n\n| Generation type | Formats |\n|-----------------|----------|\n| `image` | PNG, JPEG, WebP |\n| `video` | MP4, MOV (H.264 or HEVC). Max 240 frames. |\n\n**Resolution:** The source must not exceed 2,770,000 total pixels (width x height). Sources with extreme aspect ratios may be rejected."},"prompt":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Prompt","description":"Text description of desired output (max 2,000 chars).\n\nAt least one of `prompt` or `reference_image_uri` is required. You can provide both for more control over the output."},"reference_image_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Image Uri","description":"URI of the reference image for style transfer. Accepts the same [URI types](#body-source-uri) as `source_uri`.\n\nAt least one of `reference_image_uri` or `prompt` is required. You can provide both for more control over the output."},"alpha_mode":{"$ref":"#/components/schemas/AlphaMode","description":"'auto', 'fill', 'custom', or 'select'","examples":["select"]},"alpha_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alpha Uri","description":"URI of a custom alpha matte. Accepts the same [URI types](#body-source-uri) as `source_uri`.\n\nRequired when `alpha_mode` is `\"custom\"` or `\"select\"`.\n\n- **`select`**: Provide an alpha keyframe image (PNG/JPG grayscale) for a single reference frame. The AI propagates it across the video. By default the keyframe describes the first frame; set `alpha_keyframe_index` to use a different reference frame.\n- **`custom`**: Provide a full alpha matte matching the `generation_type` (image alpha for image generation, video alpha for video generation).\n\nWhen using `\"auto\"` or `\"fill\"`, the alpha is handled automatically and this field is ignored."},"alpha_keyframe_index":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Alpha Keyframe Index","description":"0-based index of the reference frame for alpha propagation when `alpha_mode` is `\"select\"` on a video.\n\nThe alpha keyframe supplied via `alpha_uri` describes the subject at this frame, and the AI propagates the matte across the rest of the video. Defaults to the first frame (`0`) when omitted.\n\nMust be between `0` and `frame_count - 1`. Ignored for image generation and for the `auto`, `fill`, and `custom` modes.","examples":[12]},"seed":{"anyOf":[{"type":"integer","maximum":4294967295.0,"minimum":0.0},{"type":"null"}],"title":"Seed","description":"Random seed for reproducibility (0–4,294,967,295).\n\nWhen omitted, a random seed is generated automatically so that identical requests produce different outputs. To reproduce an earlier result, pass the same seed value.\n\nThe seed used is always returned in the response.\n\n**Reproducibility note:** Using the same seed with identical inputs produces visually consistent results suitable for iterative workflows and A/B comparisons. Due to the nature of GPU computation, outputs are near-identical rather than bit-for-bit exact — differences are imperceptible to the human eye."},"max_resolution":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Resolution","description":"Maximum output resolution: 720 or 1080 (default: 1080)","default":1080,"examples":[720]},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url","description":"HTTPS URL for webhook notification on completion or failure. See [Webhooks](/api/webhooks) for payload details."},"idempotency_key":{"anyOf":[{"type":"string","maxLength":256,"minLength":1},{"type":"null"}],"title":"Idempotency Key","description":"Idempotency key for safe retries.\n\nIf a job with the same key already exists for your account, the API returns the existing job's status instead of creating a duplicate.\n\nUse a unique, deterministic key per logical request (e.g., your internal order ID). This prevents double-charges if your client retries due to network timeouts."}},"type":"object","required":["generation_type","source_uri","alpha_mode"],"title":"CreateSwitchXRequest","description":"Request to create and start a SwitchX generation job.","examples":[{"alpha_mode":"auto","generation_type":"video","max_resolution":1080,"prompt":"cinematic relight, warm golden-hour key light","source_uri":"beeble://uploads/abc123/input.mp4"},{"alpha_keyframe_index":12,"alpha_mode":"select","alpha_uri":"beeble://uploads/def456/keyframe.png","generation_type":"video","prompt":"studio softbox lighting","source_uri":"beeble://uploads/abc123/input.mp4"}]},"CreditBalanceResponse":{"properties":{"balance_cents":{"type":"integer","title":"Balance Cents","description":"Available balance in cents","examples":[24750]},"currency":{"type":"string","title":"Currency","default":"usd"}},"type":"object","required":["balance_cents"],"title":"CreditBalanceResponse","description":"Current credit balance for the authenticated user."},"CreditFulfillRequest":{"properties":{"session_id":{"type":"string","title":"Session Id"}},"type":"object","required":["session_id"],"title":"CreditFulfillRequest"},"CreditFulfillResponse":{"properties":{"status":{"type":"string","title":"Status"},"balance_cents":{"type":"integer","title":"Balance Cents","examples":[29750]}},"type":"object","required":["status","balance_cents"],"title":"CreditFulfillResponse"},"CreditPurchaseRequest":{"properties":{"amount_cents":{"type":"integer","maximum":500000.0,"minimum":1000.0,"title":"Amount Cents","description":"Amount in cents ($10-$5000)","examples":[5000]},"success_url":{"type":"string","title":"Success Url"},"cancel_url":{"type":"string","title":"Cancel Url"}},"type":"object","required":["amount_cents","success_url","cancel_url"],"title":"CreditPurchaseRequest","description":"Request to purchase API credits."},"CreditPurchaseResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"},"session_id":{"type":"string","title":"Session Id"}},"type":"object","required":["checkout_url","session_id"],"title":"CreditPurchaseResponse"},"DailyUsage":{"properties":{"date":{"type":"string","title":"Date"},"api_video_1080p":{"type":"integer","title":"Api Video 1080P","default":0,"examples":[24]},"api_video_720p":{"type":"integer","title":"Api Video 720P","default":0,"examples":[18]},"api_image_1080p":{"type":"integer","title":"Api Image 1080P","default":0,"examples":[45]},"api_image_720p":{"type":"integer","title":"Api Image 720P","default":0,"examples":[30]}},"type":"object","required":["date"],"title":"DailyUsage"},"GenerationType":{"type":"string","enum":["image","video"],"title":"GenerationType"},"PaymentMethodItem":{"properties":{"id":{"type":"string","title":"Id"},"brand":{"type":"string","title":"Brand"},"last4":{"type":"string","title":"Last4"},"exp_month":{"type":"integer","title":"Exp Month","examples":[9]},"exp_year":{"type":"integer","title":"Exp Year","examples":[2028]},"is_default":{"type":"boolean","title":"Is Default"}},"type":"object","required":["id","brand","last4","exp_month","exp_year","is_default"],"title":"PaymentMethodItem"},"PaymentMethodsResponse":{"properties":{"payment_methods":{"items":{"$ref":"#/components/schemas/PaymentMethodItem"},"type":"array","title":"Payment Methods"}},"type":"object","required":["payment_methods"],"title":"PaymentMethodsResponse"},"RateLimitInfo":{"properties":{"usage":{"type":"integer","title":"Usage","description":"Current usage in this window","default":0,"examples":[12]},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Limit","description":"Maximum allowed (null = default/unlimited)","examples":[100]}},"type":"object","title":"RateLimitInfo","description":"Rate limit for a single dimension (e.g. rpm, concurrency)."},"SubscriptionActionResponse":{"properties":{"status":{"type":"string","title":"Status"},"subscription_status":{"type":"string","title":"Subscription Status"}},"type":"object","required":["status","subscription_status"],"title":"SubscriptionActionResponse","description":"Response from subscription undo-cancel or reactivate actions."},"SwitchXListResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/SwitchXStatusResponse"},"type":"array","title":"Jobs"},"next_page_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Page Token","description":"Pass as page_token to fetch the next page. Null when no more results."}},"type":"object","title":"SwitchXListResponse","description":"Paginated list of SwitchX jobs."},"SwitchXOutputUrls":{"properties":{"render":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Render","description":"Composited output URL"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Preprocessed source URL"},"alpha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alpha","description":"Alpha matte URL"}},"type":"object","title":"SwitchXOutputUrls","description":"Signed URLs for SwitchX job outputs."},"SwitchXStatusResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Job identifier (swx_...)"},"status":{"type":"string","title":"Status","description":"in_queue, processing, completed, or failed"},"progress":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Progress","description":"Progress percentage (0-100)","examples":[72]},"generation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Type","description":"'image' or 'video'"},"alpha_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alpha Mode","description":"'auto', 'fill', 'custom', or 'select'"},"output":{"anyOf":[{"$ref":"#/components/schemas/SwitchXOutputUrls"},{"type":"null"}],"description":"Output URLs (present when status is completed). URLs are signed and expire after **72 hours**. Each call to this endpoint generates fresh signed URLs, so you can always re-fetch if a URL has expired."},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Random seed used for this generation (always present after job creation)"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message (present when status is failed)"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At","description":"ISO 8601 timestamp when the job was created"},"modified_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Modified At","description":"ISO 8601 timestamp of the last status change"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At","description":"ISO 8601 timestamp when the job completed or failed"},"webhook":{"anyOf":[{"$ref":"#/components/schemas/WebhookStatus"},{"type":"null"}],"description":"Webhook delivery status (present only when a callback_url was provided)"}},"type":"object","required":["id","status"],"title":"SwitchXStatusResponse","description":"Status response for a SwitchX job."},"UpdateAutoChargeRequest":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled","description":"Enable/disable auto-charge"},"threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Threshold","description":"Balance threshold to trigger auto-charge"},"amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount","description":"Top-up amount"}},"type":"object","title":"UpdateAutoChargeRequest","description":"Request to update a user's auto-charge settings."},"UpdateBillingTypeRequest":{"properties":{"billing_type":{"type":"string","enum":["prepaid","postpaid"],"title":"Billing Type","description":"'prepaid' or 'postpaid'"}},"type":"object","required":["billing_type"],"title":"UpdateBillingTypeRequest","description":"Request to flip a user's billing type.\n\nOnly toggles the BillingType column on DeveloperApiAccount. Does NOT\ntouch Stripe subscription state, BalanceCents, or auto-charge — the\noperator is responsible for any Stripe-side cleanup that follows."},"UpdateRateLimitsRequest":{"properties":{"rpm_limit":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Rpm Limit","description":"Requests per minute limit"},"concurrency_limit":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Concurrency Limit","description":"Max concurrent generation jobs"}},"type":"object","title":"UpdateRateLimitsRequest","description":"Request to update a user's rate limits.\n\nBoth fields accept null (meaning \"use type defaults\"). When a numeric\nvalue is provided it must fall within the safe operating range:\n1 ≤ rpm ≤ 10000, 1 ≤ concurrency ≤ 100. Existing rows storing values\noutside the range continue to read normally; the constraint applies\nonly on new writes."},"UpdateSpendingLimitRequest":{"properties":{"spending_limit":{"anyOf":[{"type":"integer","maximum":10000000.0,"minimum":0.0},{"type":"null"}],"title":"Spending Limit","description":"Per billing period in dollars; null = use type default"}},"type":"object","title":"UpdateSpendingLimitRequest","description":"Request to update a user's per-period spending limit (in dollars).\n\n`null` resets to the billing-type default (see `BILLING_TYPE_DEFAULTS`).\nThe constraint applies on input parsing only — existing rows storing\nout-of-range values continue to read normally."},"UploadRequest":{"properties":{"filename":{"type":"string","title":"Filename","description":"Filename with extension (3-255 chars). Accepted: .mp4, .mov, .png, .jpg, .jpeg, .webp"}},"type":"object","required":["filename"],"title":"UploadRequest","description":"Request to create a presigned upload URL."},"UploadResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Upload ID (upload_...)"},"upload_url":{"type":"string","title":"Upload Url","description":"Presigned PUT URL for uploading your file. Expires after 1 hour."},"beeble_uri":{"type":"string","title":"Beeble Uri","description":"beeble:// URI to reference this file in SwitchX generation calls (source_uri, reference_image_uri, or alpha_uri)."}},"type":"object","required":["id","upload_url","beeble_uri"],"title":"UploadResponse","description":"Response with presigned upload URL and beeble:// URI."},"UsageSummaryResponse":{"properties":{"billing_period_start":{"type":"integer","title":"Billing Period Start","examples":[1711929600]},"billing_period_end":{"type":"integer","title":"Billing Period End","examples":[1714521600]},"meters":{"items":{"$ref":"#/components/schemas/models__billing__MeterUsage"},"type":"array","title":"Meters"},"daily_usage":{"items":{"$ref":"#/components/schemas/DailyUsage"},"type":"array","title":"Daily Usage"},"estimated_cost_cents":{"type":"integer","title":"Estimated Cost Cents","examples":[2670]}},"type":"object","required":["billing_period_start","billing_period_end","meters","daily_usage","estimated_cost_cents"],"title":"UsageSummaryResponse"},"WebhookStatus":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"'pending', 'delivered', or 'failed'"},"attempts":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Attempts","description":"Number of delivery attempts so far","examples":[1]},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error","description":"Error message from the last failed delivery attempt"}},"type":"object","title":"WebhookStatus","description":"Webhook delivery status for a generation job."},"models__account__MeterUsage":{"properties":{"id":{"type":"string","title":"Id","description":"Meter identifier (e.g. 'api_video_1080p')"},"label":{"type":"string","title":"Label","description":"Human-readable label"},"unit":{"type":"string","title":"Unit","description":"Unit type ('steps' or 'images')"},"total_usage":{"type":"integer","title":"Total Usage","description":"Total usage in current billing period","examples":[150]}},"type":"object","required":["id","label","unit","total_usage"],"title":"MeterUsage","description":"Usage for a single billing meter in the current period."},"models__billing__MeterUsage":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"unit":{"type":"string","title":"Unit"},"total_usage":{"type":"integer","title":"Total Usage","examples":[150]},"unit_price_cents":{"type":"integer","title":"Unit Price Cents","examples":[10]}},"type":"object","required":["id","label","unit","total_usage","unit_price_cents"],"title":"MeterUsage"}},"securitySchemes":{"apiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your [Developer API key](/api/authentication)."}}},"servers":[{"url":"https://api.beeble.ai","description":"Production"}],"security":[{"apiKeyAuth":[]}]}