{"openapi":"3.0.3","info":{"title":"MMB API","version":"1.0.0","description":"Free catalog of curated AI agent use cases and bot templates. Browse without a key, or claim a key by email for account access. Sponsors fund website and YouTube partnerships."},"servers":[{"url":"https://mmb-blurware-alpha.vercel.app"}],"tags":[{"name":"auth","description":"Key lifecycle: mint, claim, device login, and legacy checkout settlement."},{"name":"catalog","description":"Use cases and bot templates."},{"name":"account","description":"Usage and limits."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"MMB API key from POST /api/v1/auth/agent, the dashboard, or `mmb login`. Send as `Authorization: Bearer <key>`."}},"schemas":{"InvalidRequestError":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"UnauthorizedError":{"type":"object","properties":{"error":{"type":"string","enum":["unauthorized"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"InvalidApiKeyError":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_api_key"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"KeyExpiredError":{"type":"object","properties":{"error":{"type":"string","enum":["key_expired"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"QuotaExhaustedError":{"type":"object","properties":{"error":{"type":"string","enum":["quota_exhausted"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"ClaimRequiredError":{"type":"object","properties":{"error":{"type":"string","enum":["claim_required"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"InvalidClaimError":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_claim"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"NotFoundError":{"type":"object","properties":{"error":{"type":"string","enum":["not_found"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"AlreadyUpgradedError":{"type":"object","properties":{"error":{"type":"string","enum":["already_upgraded"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"RateLimitedError":{"type":"object","properties":{"error":{"type":"string","enum":["rate_limited"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"ServiceUnavailableError":{"type":"object","properties":{"error":{"type":"string","enum":["service_unavailable"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},"DeviceTokenError":{"type":"object","properties":{"error":{"type":"string","enum":["authorization_pending","slow_down","expired_token","access_denied","invalid_code","unauthorized","service_unavailable"],"description":"authorization_pending: keep polling. slow_down: increase the polling interval. expired_token: restart the device flow. access_denied: the request was rejected."}},"required":["error"]},"Usage":{"type":"object","properties":{"tenantId":{"type":"string"},"status":{"type":"string","enum":["anonymous","claimed","upgraded"]},"keyPrefix":{"type":"string","description":"First characters of the API key, for display."},"requestsUsed":{"type":"number"},"requestLimit":{"type":"number","description":"Lifetime request cap for anonymous keys; tier cap otherwise."},"dailyRequestsUsed":{"type":"number"},"dailyRequestLimit":{"type":"number"},"expiresAt":{"type":"number","description":"Anonymous key expiry, Unix epoch milliseconds."},"email":{"type":"string","description":"Present once the key is claimed."}},"required":["tenantId","status","keyPrefix","requestsUsed","requestLimit","dailyRequestsUsed"]},"Usecase":{"type":"object","properties":{"slug":{"type":"string","description":"Stable identifier used in /api/v1/usecases/{slug}."},"guide":{"type":"object","properties":{"title":{"type":"string"},"category":{"type":"string"},"opportunity":{"type":"string"},"audience":{"type":"string"},"platforms":{"type":"array","items":{"type":"string"}},"botSlugs":{"type":"array","items":{"type":"string"}},"steps":{"type":"array","items":{"type":"string"}},"prompt":{"type":"string"},"value":{"type":"object","properties":{"amount":{"type":"string"},"label":{"type":"string"},"basis":{"type":"string"},"kind":{"type":"string","enum":["reported","illustrative"]}},"required":["amount","label","basis","kind"],"description":"USD inspiration value, explicitly labeled as a creator report or illustrative assumption; not promised earnings."}},"required":["title","category","opportunity","audience","platforms","botSlugs","steps","prompt"]},"title":{"type":"string"},"who":{"type":"string","description":"Who ran this use case."},"handle":{"type":"string","description":"Public handle of the operator."},"roi":{"type":"string","description":"Reported outcome or return."},"sourceUrl":{"type":"string","description":"Public source for the claim."},"addedAt":{"type":"number","description":"Unix epoch milliseconds."}},"required":["slug","title","who","handle","roi","sourceUrl","addedAt"]},"BotTemplate":{"type":"object","properties":{"slug":{"type":"string","description":"Stable identifier used in /api/v1/bots/{slug}."},"name":{"type":"string"},"category":{"type":"string","description":"Directory category."},"who":{"type":"string","description":"Who runs this bot."},"handle":{"type":"string","description":"Public handle of the operator."},"job":{"type":"string","description":"What the bot does."},"templateUrl":{"type":"string","description":"Public template link."},"addedAt":{"type":"number","description":"Unix epoch milliseconds."}},"required":["slug","name","who","handle","job","templateUrl","addedAt"]}},"parameters":{}},"paths":{"/api/v1/auth/agent":{"post":{"operationId":"mintAgentKey","summary":"Mint an anonymous API key","description":"Creates a new anonymous key with a lifetime request cap and an expiry. The key is returned once; store it. Claim it by email to remove the expiry and cap.","tags":["auth"],"responses":{"200":{"description":"Key minted.","content":{"application/json":{"schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Shown once. Store it."},"tenantId":{"type":"string"},"claimToken":{"type":"string","description":"Use with POST /api/v1/auth/claim."},"claimUrl":{"type":"string","description":"Human-readable claim instructions."},"expiresAt":{"type":"number","description":"Anonymous key expiry, Unix epoch milliseconds."}},"required":["apiKey","tenantId","claimToken","claimUrl","expiresAt"]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/auth/claim":{"post":{"operationId":"startClaim","summary":"Start an email claim","description":"Sends a 6-digit verification code to the email address for this claim token.","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claimToken":{"type":"string","minLength":8},"email":{"type":"string","format":"email"}},"required":["claimToken","email"]}}}},"responses":{"200":{"description":"Verification code sent.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"}},"required":["sent"]}}}},"400":{"description":"The body is invalid or the claim token is unknown.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["invalid_claim"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/auth/claim/complete":{"post":{"operationId":"completeClaim","summary":"Complete an email claim","description":"Verifies the emailed code. Claiming does not rotate the key; it removes the anonymous expiry and lifetime cap.","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claimToken":{"type":"string","minLength":8},"email":{"type":"string","format":"email"},"code":{"type":"string","minLength":4}},"required":["claimToken","email","code"]}}}},"responses":{"200":{"description":"Key claimed. Returns the key's usage summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"400":{"description":"The body is invalid, or the token/code pair is wrong or expired.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["invalid_claim"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/auth/upgrade":{"post":{"operationId":"createUpgrade","summary":"Legacy reader upgrade (disabled)","description":"The library is free. This legacy endpoint returns library_is_free; new reader checkout sessions are disabled.","deprecated":true,"tags":["auth"],"security":[{"bearerAuth":[]}],"responses":{"409":{"description":"The library is free.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["library_is_free"]}},"required":["error"]}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/auth/upgrade/claim":{"post":{"operationId":"claimUpgrade","summary":"Poll an upgrade checkout session","description":"Returns pending until the Stripe webhook lands, then completed with the updated usage summary.","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sessionId":{"type":"string","minLength":8}},"required":["sessionId"]}}}},"responses":{"200":{"description":"Current checkout status.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","completed"]},"usage":{"allOf":[{"$ref":"#/components/schemas/Usage"},{"description":"Present once status is completed."}]}},"required":["status"]}}}},"400":{"description":"The body or session ID is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidRequestError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/auth/device":{"post":{"operationId":"deviceStart","summary":"Start a device authorization (RFC 8628)","description":"Begins the CLI login flow. Show the user_code and verification_uri to the user, then poll POST /api/v1/auth/device/token.","tags":["auth"],"responses":{"200":{"description":"Device authorization created.","content":{"application/json":{"schema":{"type":"object","properties":{"device_code":{"type":"string","description":"Secret polling credential. Never display it."},"user_code":{"type":"string","description":"Short code the user enters at the verification URI."},"verification_uri":{"type":"string","description":"Absolute URL where the user approves the device."},"expires_in":{"type":"number","description":"Seconds until this authorization expires."},"interval":{"type":"number","description":"Minimum polling interval in seconds."}},"required":["device_code","user_code","verification_uri","expires_in","interval"]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/auth/device/token":{"post":{"operationId":"deviceToken","summary":"Poll for a device authorization key","description":"Exchanges an approved device_code for a fresh API key. While pending, responds 400 with authorization_pending.","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"device_code":{"type":"string","minLength":8}},"required":["device_code"]}}}},"responses":{"200":{"description":"The device was approved. The key is returned once.","content":{"application/json":{"schema":{"type":"object","properties":{"apiKey":{"type":"string"}},"required":["apiKey"]}}}},"400":{"description":"Not approved yet, expired, or denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenError"}}}}}}},"/api/v1/usage":{"get":{"operationId":"getUsage","summary":"Get usage for the calling key","tags":["account"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Usage summary for the key's tenant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"Missing bearer header or unknown key.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["unauthorized"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["invalid_api_key"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"403":{"description":"The anonymous key expired or exhausted its quota.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["key_expired"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["quota_exhausted"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/usecases":{"get":{"operationId":"searchUsecases","summary":"List or search use cases","description":"Public and free. An optional bearer key enables account usage tracking. With q set, returns full-text matches and no cursor.","tags":["catalog"],"security":[{"bearerAuth":[]},{}],"parameters":[{"schema":{"type":"string","description":"Full-text search. When set, pagination is disabled."},"required":false,"description":"Full-text search. When set, pagination is disabled.","name":"q","in":"query"},{"schema":{"type":"string","description":"Opaque cursor from a previous response."},"required":false,"description":"Opaque cursor from a previous response.","name":"cursor","in":"query"},{"schema":{"type":"number","nullable":true,"description":"Page size, 1-100. Defaults to 20."},"required":false,"description":"Page size, 1-100. Defaults to 20.","name":"limit","in":"query"}],"responses":{"200":{"description":"One page of use cases.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Usecase"}},"nextCursor":{"type":"string","nullable":true}},"required":["data","nextCursor"]}}}},"401":{"description":"An account API key is required.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["unauthorized"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["invalid_api_key"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"403":{"description":"Claim the key or check its quota.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["claim_required"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["key_expired"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["quota_exhausted"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/usecases/{slug}":{"get":{"operationId":"getUsecase","summary":"Get one use case","description":"Public and free. An optional bearer key enables account usage tracking.","tags":["catalog"],"security":[{"bearerAuth":[]},{}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"The use case.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usecase"}}}},"401":{"description":"An account API key is required.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["unauthorized"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["invalid_api_key"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"403":{"description":"Claim the key or check its quota.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["claim_required"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["key_expired"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["quota_exhausted"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"404":{"description":"No use case with this slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/bots":{"get":{"operationId":"searchBots","summary":"List or search bot templates","description":"Bearer auth is optional: keyless requests work at a lower rate limit. With q set, returns full-text matches and no cursor.","tags":["catalog"],"security":[{"bearerAuth":[]},{}],"parameters":[{"schema":{"type":"string","description":"Full-text search. When set, pagination is disabled."},"required":false,"description":"Full-text search. When set, pagination is disabled.","name":"q","in":"query"},{"schema":{"type":"string","description":"Opaque cursor from a previous response."},"required":false,"description":"Opaque cursor from a previous response.","name":"cursor","in":"query"},{"schema":{"type":"number","nullable":true,"description":"Page size, 1-100. Defaults to 20."},"required":false,"description":"Page size, 1-100. Defaults to 20.","name":"limit","in":"query"}],"responses":{"200":{"description":"One page of bot templates.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BotTemplate"}},"nextCursor":{"type":"string","nullable":true}},"required":["data","nextCursor"]}}}},"401":{"description":"The bearer key does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiKeyError"}}}},"403":{"description":"The anonymous key expired or exhausted its quota.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["key_expired"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["quota_exhausted"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/bots/{slug}":{"get":{"operationId":"getBot","summary":"Get one bot template","tags":["catalog"],"security":[{"bearerAuth":[]},{}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"The bot template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotTemplate"}}}},"401":{"description":"The bearer key does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiKeyError"}}}},"403":{"description":"The anonymous key expired or exhausted its quota.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"error":{"type":"string","enum":["key_expired"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]},{"type":"object","properties":{"error":{"type":"string","enum":["quota_exhausted"],"description":"Stable machine-readable error code."},"message":{"type":"string","description":"Human-readable summary."},"hint":{"type":"string","description":"Endpoint path that resolves this error, when one exists."}},"required":["error","message"]}]}}}},"404":{"description":"No bot template with this slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundError"}}}},"429":{"description":"Too many requests. Mirrors the Retry-After header.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"}}}},"503":{"description":"The gateway is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUnavailableError"}}}}}}},"/api/v1/sponsors/bookings/start":{"post":{"operationId":"sponsorship_bookings_start","summary":"Save brand details and reserve a sponsor package in one transaction","tags":["sponsors"],"description":"Requires both sponsor:write and billing:write. Requires billing:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"website":{"type":"string","maxLength":1500,"format":"uri"},"headline":{"type":"string","minLength":1,"maxLength":55},"body":{"type":"string","minLength":1,"maxLength":140},"slotId":{"type":"string","minLength":1,"maxLength":100},"weekStart":{"type":"integer"},"idempotencyKey":{"type":"string","format":"uuid"}},"required":["name","website","headline","body","slotId","weekStart","idempotencyKey"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"booking":{"type":"object","properties":{"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"packageDescription":{"type":"string"},"youtubeStatus":{"type":"string","enum":["planned","published"]},"youtubeUrl":{"type":"string"},"youtubeNotes":{"type":"string"},"demo":{"type":"boolean"},"id":{"type":"string"},"campaignId":{"type":"string"},"campaignName":{"type":"string"},"slotName":{"type":"string"},"weekStart":{"type":"number"},"weekEnd":{"type":"number"},"amountCents":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string","enum":["reserved","checkout","paid","expired","cancelled","refunding","refunded"]},"mode":{"type":"string","enum":["test","live"]},"createdAt":{"type":"number"},"receiptUrl":{"type":"string"},"refundedCents":{"type":"number"},"paymentIssue":{"type":"string"},"impressions":{"type":"number"},"clicks":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","campaignId","campaignName","slotName","weekStart","weekEnd","amountCents","currency","status","mode","createdAt","impressions","clicks"]}},"required":["booking"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/bookings/{id}/fulfillment":{"patch":{"operationId":"sponsorship_admin_fulfillment","summary":"Update YouTube integration delivery","tags":["sponsorship admin"],"description":"Requires admin:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"youtubeStatus":{"type":"string","enum":["planned","published"]},"youtubeUrl":{"type":"string","maxLength":1500,"format":"uri"},"youtubeNotes":{"type":"string","maxLength":500}},"required":["youtubeStatus","youtubeNotes"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"boolean"}},"required":["updated"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/inventory":{"get":{"operationId":"sponsorship_inventory","summary":"Read sponsorship inventory and availability","tags":["sponsors"],"description":"Public bounded endpoint. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{}],"parameters":[{"schema":{"type":"integer"},"required":false,"name":"weekStart","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"weekStart":{"type":"number"},"weekEnd":{"type":"number"},"billingMode":{"type":"string","enum":["test","live"]},"slots":{"type":"array","items":{"type":"object","properties":{"durationWeeks":{"type":"number"},"comingSoon":{"type":"boolean"},"offerEndsAt":{"type":"number"},"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"side":{"type":"string","enum":["left","right"]},"weekPriceCents":{"type":"number"},"active":{"type":"boolean"},"available":{"type":"boolean"}},"required":["id","name","side","weekPriceCents","active"]}}},"required":["weekStart","weekEnd","billingMode","slots"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/placements":{"get":{"operationId":"sponsorship_placements","summary":"Read active approved sponsor placements","tags":["sponsors"],"description":"Public bounded endpoint. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"placements":{"type":"array","items":{"type":"object","properties":{"headline":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"targetUrl":{"type":"string"},"logoText":{"type":"string"},"bookingId":{"type":"string"},"side":{"type":"string","enum":["left","right"]},"sponsorName":{"type":"string"},"demo":{"type":"boolean"}},"required":["headline","body","cta","targetUrl","logoText","bookingId","side","sponsorName","demo"]}}},"required":["placements"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/events":{"post":{"operationId":"sponsorship_event","summary":"Record a deduplicated placement event","tags":["sponsors"],"description":"Public bounded endpoint. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bookingId":{"type":"string","minLength":1,"maxLength":100},"kind":{"type":"string","enum":["impression","click"]},"visitorId":{"type":"string","format":"uuid"}},"required":["bookingId","kind","visitorId"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"recorded":{"type":"boolean"}},"required":["recorded"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/me":{"get":{"operationId":"sponsorship_me","summary":"Read sponsor profile and permissions","tags":["sponsors"],"description":"Requires sponsor:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"profile":{"type":"object","nullable":true,"properties":{"name":{"type":"string"},"website":{"type":"string"}},"required":["name","website"]},"email":{"type":"string"},"isAdmin":{"type":"boolean"},"isDemo":{"type":"boolean"},"scopes":{"type":"array","items":{"type":"string","enum":["library:read","sponsor:read","sponsor:write","billing:write","admin:read","admin:write","keys:manage"]}},"billingMode":{"type":"string","enum":["test","live"]}},"required":["profile","email","isAdmin","isDemo","scopes","billingMode"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/profile":{"patch":{"operationId":"sponsorship_profile_update","summary":"Update your sponsor profile","tags":["sponsors"],"description":"Requires sponsor:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"website":{"type":"string","maxLength":1500,"format":"uri"}},"required":["name","website"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"profile":{"type":"object","properties":{"name":{"type":"string"},"website":{"type":"string"}},"required":["name","website"]}},"required":["profile"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/campaigns":{"get":{"operationId":"sponsorship_campaigns_list","summary":"List your campaigns","tags":["sponsors"],"description":"Requires sponsor:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2000},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"headline":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"targetUrl":{"type":"string"},"logoText":{"type":"string"},"status":{"type":"string","enum":["draft","pending","approved","rejected","paused"]},"reviewNote":{"type":"string"},"createdAt":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","name","headline","body","cta","targetUrl","logoText","status","createdAt"]}},"cursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","cursor","hasMore"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}},"post":{"operationId":"sponsorship_campaigns_create","summary":"Create sponsor creative","tags":["sponsors"],"description":"Requires sponsor:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"headline":{"type":"string","minLength":1,"maxLength":55},"body":{"type":"string","minLength":1,"maxLength":140},"cta":{"type":"string","minLength":1,"maxLength":24},"targetUrl":{"type":"string","maxLength":1500,"format":"uri"},"logoText":{"type":"string","minLength":1,"maxLength":3}},"required":["name","headline","body","cta","targetUrl","logoText"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"headline":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"targetUrl":{"type":"string"},"logoText":{"type":"string"},"status":{"type":"string","enum":["draft","pending","approved","rejected","paused"]},"reviewNote":{"type":"string"},"createdAt":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","name","headline","body","cta","targetUrl","logoText","status","createdAt"]}},"required":["campaign"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/campaigns/{id}":{"patch":{"operationId":"sponsorship_campaigns_update","summary":"Edit draft creative","tags":["sponsors"],"description":"Requires sponsor:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"headline":{"type":"string","minLength":1,"maxLength":55},"body":{"type":"string","minLength":1,"maxLength":140},"cta":{"type":"string","minLength":1,"maxLength":24},"targetUrl":{"type":"string","maxLength":1500,"format":"uri"},"logoText":{"type":"string","minLength":1,"maxLength":3}},"required":["name","headline","body","cta","targetUrl","logoText"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"headline":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"targetUrl":{"type":"string"},"logoText":{"type":"string"},"status":{"type":"string","enum":["draft","pending","approved","rejected","paused"]},"reviewNote":{"type":"string"},"createdAt":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","name","headline","body","cta","targetUrl","logoText","status","createdAt"]}},"required":["campaign"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/campaigns/{id}/submit":{"post":{"operationId":"sponsorship_campaigns_submit","summary":"Submit creative for review","tags":["sponsors"],"description":"Requires sponsor:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"submitted":{"type":"boolean"}},"required":["submitted"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/bookings":{"get":{"operationId":"sponsorship_bookings_list","summary":"List your bookings and delivery metrics","tags":["sponsors"],"description":"Requires sponsor:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2000},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"packageDescription":{"type":"string"},"youtubeStatus":{"type":"string","enum":["planned","published"]},"youtubeUrl":{"type":"string"},"youtubeNotes":{"type":"string"},"demo":{"type":"boolean"},"id":{"type":"string"},"campaignId":{"type":"string"},"campaignName":{"type":"string"},"slotName":{"type":"string"},"weekStart":{"type":"number"},"weekEnd":{"type":"number"},"amountCents":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string","enum":["reserved","checkout","paid","expired","cancelled","refunding","refunded"]},"mode":{"type":"string","enum":["test","live"]},"createdAt":{"type":"number"},"receiptUrl":{"type":"string"},"refundedCents":{"type":"number"},"paymentIssue":{"type":"string"},"impressions":{"type":"number"},"clicks":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","campaignId","campaignName","slotName","weekStart","weekEnd","amountCents","currency","status","mode","createdAt","impressions","clicks"]}},"cursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","cursor","hasMore"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}},"post":{"operationId":"sponsorship_bookings_create","summary":"Reserve an available sponsorship week","tags":["sponsors"],"description":"Requires billing:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"campaignId":{"type":"string","minLength":1,"maxLength":100},"slotId":{"type":"string","minLength":1,"maxLength":100},"weekStart":{"type":"integer"},"idempotencyKey":{"type":"string","format":"uuid"}},"required":["campaignId","slotId","weekStart","idempotencyKey"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"booking":{"type":"object","properties":{"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"packageDescription":{"type":"string"},"youtubeStatus":{"type":"string","enum":["planned","published"]},"youtubeUrl":{"type":"string"},"youtubeNotes":{"type":"string"},"demo":{"type":"boolean"},"id":{"type":"string"},"campaignId":{"type":"string"},"campaignName":{"type":"string"},"slotName":{"type":"string"},"weekStart":{"type":"number"},"weekEnd":{"type":"number"},"amountCents":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string","enum":["reserved","checkout","paid","expired","cancelled","refunding","refunded"]},"mode":{"type":"string","enum":["test","live"]},"createdAt":{"type":"number"},"receiptUrl":{"type":"string"},"refundedCents":{"type":"number"},"paymentIssue":{"type":"string"},"impressions":{"type":"number"},"clicks":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","campaignId","campaignName","slotName","weekStart","weekEnd","amountCents","currency","status","mode","createdAt","impressions","clicks"]}},"required":["booking"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/bookings/{id}":{"get":{"operationId":"sponsorship_bookings_get","summary":"Read a booking and receipt","tags":["sponsors"],"description":"Requires sponsor:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"booking":{"type":"object","properties":{"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"packageDescription":{"type":"string"},"youtubeStatus":{"type":"string","enum":["planned","published"]},"youtubeUrl":{"type":"string"},"youtubeNotes":{"type":"string"},"demo":{"type":"boolean"},"id":{"type":"string"},"campaignId":{"type":"string"},"campaignName":{"type":"string"},"slotName":{"type":"string"},"weekStart":{"type":"number"},"weekEnd":{"type":"number"},"amountCents":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string","enum":["reserved","checkout","paid","expired","cancelled","refunding","refunded"]},"mode":{"type":"string","enum":["test","live"]},"createdAt":{"type":"number"},"receiptUrl":{"type":"string"},"refundedCents":{"type":"number"},"paymentIssue":{"type":"string"},"impressions":{"type":"number"},"clicks":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","campaignId","campaignName","slotName","weekStart","weekEnd","amountCents","currency","status","mode","createdAt","impressions","clicks"]}},"required":["booking"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/bookings/{id}/checkout":{"post":{"operationId":"sponsorship_bookings_checkout","summary":"Start or resume Stripe Checkout","tags":["sponsors"],"description":"Requires billing:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"mode":{"type":"string","enum":["test","live"]},"bookingId":{"type":"string"}},"required":["url","mode","bookingId"]},{"type":"object","properties":{"paid":{"type":"boolean"}},"required":["paid"]},{"type":"object","properties":{"pending":{"type":"boolean"}},"required":["pending"]},{"type":"object","properties":{"cancelled":{"type":"boolean"},"expired":{"type":"boolean"}},"required":["cancelled","expired"]}]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/bookings/{id}/cancel":{"post":{"operationId":"sponsorship_bookings_cancel","summary":"Cancel an unpaid booking","tags":["sponsors"],"description":"Requires billing:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"cancelled":{"type":"boolean"}},"required":["cancelled"]},{"type":"object","properties":{"url":{"type":"string"},"mode":{"type":"string","enum":["test","live"]},"bookingId":{"type":"string"}},"required":["url","mode","bookingId"]},{"type":"object","properties":{"paid":{"type":"boolean"}},"required":["paid"]},{"type":"object","properties":{"pending":{"type":"boolean"}},"required":["pending"]},{"type":"object","properties":{"cancelled":{"type":"boolean"},"expired":{"type":"boolean"}},"required":["cancelled","expired"]}]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/keys":{"get":{"operationId":"sponsorship_keys_list","summary":"List scoped API credentials","tags":["sponsors"],"description":"Requires keys:manage. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"keyPrefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"}},"required":["id","keyPrefix","scopes","createdAt"]}}},"required":["items"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}},"post":{"operationId":"sponsorship_keys_create","summary":"Create a narrowly scoped API credential","tags":["sponsors"],"description":"Requires keys:manage. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"scopes":{"type":"array","items":{"type":"string","enum":["library:read","sponsor:read","sponsor:write","billing:write","admin:read","admin:write","keys:manage"]},"minItems":1,"maxItems":7}},"required":["name","scopes"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"apiKey":{"type":"string"},"id":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["library:read","sponsor:read","sponsor:write","billing:write","admin:read","admin:write","keys:manage"]}}},"required":["apiKey","id","scopes"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/sponsors/keys/{id}":{"delete":{"operationId":"sponsorship_keys_revoke","summary":"Revoke a credential","tags":["sponsors"],"description":"Requires keys:manage. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean"}},"required":["revoked"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/overview":{"get":{"operationId":"sponsorship_admin_overview","summary":"Read sponsorship overview","tags":["sponsorship admin"],"description":"Requires admin:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"totals":{"type":"object","properties":{"sponsors":{"type":"number"},"campaigns":{"type":"number"},"bookings":{"type":"number"},"grossCents":{"type":"number"},"refundedCents":{"type":"number"}},"required":["sponsors","campaigns","bookings","grossCents","refundedCents"]},"pendingReviews":{"type":"number"},"moreReviews":{"type":"boolean"},"billingMode":{"type":"string","enum":["test","live"]}},"required":["totals","pendingReviews","moreReviews","billingMode"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/campaigns":{"get":{"operationId":"sponsorship_admin_campaigns","summary":"Read sponsorship campaigns","tags":["sponsorship admin"],"description":"Requires admin:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2000},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"headline":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"targetUrl":{"type":"string"},"logoText":{"type":"string"},"status":{"type":"string","enum":["draft","pending","approved","rejected","paused"]},"reviewNote":{"type":"string"},"createdAt":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","name","headline","body","cta","targetUrl","logoText","status","createdAt"]}},"cursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","cursor","hasMore"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/bookings":{"get":{"operationId":"sponsorship_admin_bookings","summary":"Read sponsorship bookings","tags":["sponsorship admin"],"description":"Requires admin:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2000},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"packageDescription":{"type":"string"},"youtubeStatus":{"type":"string","enum":["planned","published"]},"youtubeUrl":{"type":"string"},"youtubeNotes":{"type":"string"},"demo":{"type":"boolean"},"id":{"type":"string"},"campaignId":{"type":"string"},"campaignName":{"type":"string"},"slotName":{"type":"string"},"weekStart":{"type":"number"},"weekEnd":{"type":"number"},"amountCents":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string","enum":["reserved","checkout","paid","expired","cancelled","refunding","refunded"]},"mode":{"type":"string","enum":["test","live"]},"createdAt":{"type":"number"},"receiptUrl":{"type":"string"},"refundedCents":{"type":"number"},"paymentIssue":{"type":"string"},"impressions":{"type":"number"},"clicks":{"type":"number"},"sponsorName":{"type":"string"}},"required":["id","campaignId","campaignName","slotName","weekStart","weekEnd","amountCents","currency","status","mode","createdAt","impressions","clicks"]}},"cursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","cursor","hasMore"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/sponsors":{"get":{"operationId":"sponsorship_admin_sponsors","summary":"Read sponsorship sponsors","tags":["sponsorship admin"],"description":"Requires admin:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2000},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"website":{"type":"string"},"id":{"type":"string"},"createdAt":{"type":"number"}},"required":["name","website","id","createdAt"]}},"cursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","cursor","hasMore"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/audit":{"get":{"operationId":"sponsorship_admin_audit","summary":"Read sponsorship audit","tags":["sponsorship admin"],"description":"Requires admin:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2000},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"actor":{"type":"string"},"action":{"type":"string"},"subject":{"type":"string"},"detail":{"type":"string"},"createdAt":{"type":"number"}},"required":["id","actor","action","subject","detail","createdAt"]}},"cursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}},"required":["items","cursor","hasMore"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/slots":{"get":{"operationId":"sponsorship_admin_slots","summary":"Read sponsorship slots","tags":["sponsorship admin"],"description":"Requires admin:read. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"durationWeeks":{"type":"number"},"comingSoon":{"type":"boolean"},"offerEndsAt":{"type":"number"},"packageKind":{"type":"string","enum":["website","youtube","bundle"]},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"side":{"type":"string","enum":["left","right"]},"weekPriceCents":{"type":"number"},"active":{"type":"boolean"},"available":{"type":"boolean"}},"required":["id","name","side","weekPriceCents","active"]}}},"required":["items"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/slots/{id}":{"patch":{"operationId":"sponsorship_admin_slot_update","summary":"Change slot price or availability","tags":["sponsorship admin"],"description":"Requires admin:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"weekPriceCents":{"type":"integer","minimum":100,"maximum":10000000},"active":{"type":"boolean"}},"required":["weekPriceCents","active"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"boolean"}},"required":["updated"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/campaigns/{id}/review":{"post":{"operationId":"sponsorship_admin_review","summary":"Approve, reject, or pause creative","tags":["sponsorship admin"],"description":"Requires admin:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"decision":{"type":"string","enum":["approved","rejected","paused"]},"note":{"type":"string","minLength":1,"maxLength":500}},"required":["decision","note"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"reviewed":{"type":"boolean"}},"required":["reviewed"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/bookings/{id}/reconcile":{"post":{"operationId":"sponsorship_admin_reconcile","summary":"Reconcile a booking with the payment provider","tags":["sponsorship admin"],"description":"Requires admin:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"scheduled":{"type":"boolean"}},"required":["scheduled"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}},"/api/v1/admin/sponsorships/bookings/{id}/refund":{"post":{"operationId":"sponsorship_admin_refund","summary":"Refund a paid booking","tags":["sponsorship admin"],"description":"Requires admin:write. Account ownership and current admin membership are checked independently of key scopes. All times are UTC epoch milliseconds. List responses are cursor-paginated. Booking creation requires a UUID idempotencyKey; repeating it returns the same reservation. Browser sessions use the same service with same-origin mutation protection.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":500}},"required":["reason"],"additionalProperties":false}}}},"responses":{"200":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"refunded":{"type":"boolean"},"status":{"type":"string","nullable":true}},"required":["refunded"]}}}},"400":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"401":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"403":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"404":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"409":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"429":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}},"503":{"description":"Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retryAfter":{"type":"number"}},"required":["error","message"]}}}}}}}}}