{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.forage.bot"}],"components":{"schemas":{},"parameters":{},"securitySchemes":{"forageKey":{"type":"http","scheme":"bearer","bearerFormat":"fk_<key>"},"internalJwt":{"type":"http","scheme":"bearer","bearerFormat":"ik_<jwt>"}}},"paths":{"/api/v1/accounts":{"post":{"summary":"Create a new Platform API account (sends verification email)","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"_website":{"type":"string"}},"required":["email"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"account_id":{"type":"string"},"message":{"type":"string"}},"required":["account_id","message"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"upstream_failure","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/accounts/verify":{"get":{"summary":"Redirects (303) a signup or lost-key link to the /verify page. Never spends the link, because mail scanners fetch links.","security":[],"responses":{"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"post":{"summary":"Spend a signup or lost-key link and receive the plaintext API key. This response is the only time the key is available.","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"account_id":{"type":"string"},"status":{"type":"string","enum":["active"]},"key_id":{"type":"string"},"key":{"type":"string"}},"required":["account_id","status","key_id","key"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"410":{"description":"deprecated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"upstream_failure","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/accounts/recover":{"post":{"summary":"Email a replacement-key link to an active account. Answers the same for an address with no active account.","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"upstream_failure","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/me":{"get":{"summary":"Returns information about the authenticated caller","security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"kind":{"type":"string","enum":["customer","internal","anonymous"]},"balance_millicents":{"type":["number","null"]}},"required":["kind"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/services":{"get":{"summary":"List all services in the platform catalog","security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"base_url":{"type":"string"},"openapi_url":{"type":"string"},"stage":{"type":"string"}},"required":["slug","name","base_url","openapi_url","stage"]}}},"required":["items"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}}}}},"/api/v1/services/{slug}":{"get":{"summary":"Fetch one service catalog entry","security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"base_url":{"type":"string"},"openapi_url":{"type":"string"},"stage":{"type":"string"}},"required":["slug","name","base_url","openapi_url","stage"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/conformance/{slug}":{"get":{"summary":"Run the API platform conformance suite against an op's live custom domain and return the report","security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"slug":{"type":"string"},"baseUrl":{"type":"string"},"startedAt":{"type":"string"},"finishedAt":{"type":"string"},"totalDurationMs":{"type":"number"},"passed":{"type":"number"},"failed":{"type":"number"},"skipped":{"type":"number"},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail","skip"]},"durationMs":{"type":"number"},"message":{"type":"string"}},"required":["name","status","durationMs"]}}},"required":["slug","baseUrl","startedAt","finishedAt","totalDurationMs","passed","failed","skipped","checks"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/feedback":{"post":{"summary":"Submit feedback about the Platform API","security":[{"forageKey":[]},{"internalJwt":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["bug","idea","question"]},"message":{"type":"string","minLength":1,"maxLength":5000},"email":{"type":"string","format":"email"}},"required":["message"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/feedback/status":{"post":{"summary":"Submit feedback from the public status page (anonymous, CORS-restricted to status.{base_domain})","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["bug","idea","question"]},"message":{"type":"string","minLength":3,"maxLength":4000},"email":{"type":"string","format":"email"},"context":{"type":"object","properties":{"url":{"type":"string"},"path":{"type":"string"},"page_title":{"type":"string"},"viewport":{"type":"string"},"user_agent":{"type":"string"},"session_id":{"type":"string"}}}},"required":["message"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"issue_number":{"type":"number"}},"required":["ok","issue_number"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/gtm/events":{"post":{"summary":"Record one customer-journey or platform-cost event into the portfolio gtm_events table","security":[{"forageKey":[]},{"internalJwt":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"op_slug":{"type":"string","pattern":"^[a-z][a-z0-9-]{1,40}$"},"event_type":{"type":"string","enum":["impression","click","visit","signup","page_view","free_step","intake_start","checkout_start","purchase","refund","platform_report"]},"vid":{"type":"string"},"channel":{"type":"string","minLength":1,"maxLength":64},"campaign_id":{"type":"string","minLength":1,"maxLength":128},"creative_id":{"type":"string","minLength":1,"maxLength":128},"placement":{"type":"string","minLength":1,"maxLength":256},"external_id":{"type":"string","minLength":1,"maxLength":256},"cost_cents":{"type":"integer","minimum":0},"metadata":{"type":"object","additionalProperties":{}},"ts":{"type":"string","format":"date-time"}},"required":["op_slug","event_type"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"ts":{"type":"string"}},"required":["id","ts"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/gtm/rollup":{"get":{"summary":"Per-op, per-event-type totals over the portfolio gtm_events table for a time window; by=channel also splits by channel and utm_campaign, drops crawler visits and moves our own QA visitors into qa_events and qa_visitors; by=funnel counts free_step and checkout_start per op for all traffic and for Reddit-ad visitors, with QA visitors in qa_events; by=language instead returns, per first-choice browser language across all ops, distinct non-crawler visitors that sent at least 2 visits on one op in the window","security":[{"internalJwt":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"anyOf":[{"type":"object","properties":{"since":{"type":"string"},"until":{"type":"string"},"by":{"type":"string","enum":["channel","funnel"]},"items":{"type":"array","items":{"type":"object","properties":{"op_slug":{"type":"string"},"event_type":{"type":"string"},"events":{"type":"number"},"cost_cents":{"type":"number"},"reddit_events":{"type":"number"},"reddit_visitors":{"type":"number"},"reddit_second_page_visitors":{"type":"number"},"qa_events":{"type":"number"},"qa_visitors":{"type":"number"},"channel":{"type":["string","null"]},"campaign_id":{"type":["string","null"]},"visitors":{"type":"number"}},"required":["op_slug","event_type","events"]}}},"required":["since","until","items"]},{"type":"object","properties":{"since":{"type":"string"},"until":{"type":"string"},"by":{"type":"string","enum":["language"]},"items":{"type":"array","items":{"type":"object","properties":{"lang":{"type":"string"},"visitors":{"type":"number"},"events":{"type":"number"}},"required":["lang","visitors","events"]}}},"required":["since","until","by","items"]}]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"403":{"description":"api_key_not_accepted","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/gtm/attribution":{"get":{"summary":"Resolve up to 100 visit ids (comma-separated vids, as carried in Stripe Checkout metadata.vid) to the channels their visits recorded, earliest first, and the ops on which each vid is QA","security":[{"internalJwt":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"vid":{"type":"string"},"op_slug":{"type":["string","null"]},"first_touch":{"type":["object","null"],"properties":{"channel":{"type":["string","null"]},"campaign_id":{"type":["string","null"]},"first_seen":{"type":"string"},"visits":{"type":"number"}},"required":["channel","campaign_id","first_seen","visits"]},"touches":{"type":"array","items":{"type":"object","properties":{"channel":{"type":["string","null"]},"campaign_id":{"type":["string","null"]},"first_seen":{"type":"string"},"visits":{"type":"number"}},"required":["channel","campaign_id","first_seen","visits"]}},"qa_op_slugs":{"type":"array","items":{"type":"string"}}},"required":["vid","op_slug","first_touch","touches","qa_op_slugs"]}}},"required":["items"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"403":{"description":"api_key_not_accepted","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/tokens":{"post":{"summary":"Issue a new API key for the calling account. The plaintext is returned once. It starts at zero balance, and a top-up started with it credits it.","security":[{"forageKey":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"key_id":{"type":"string"},"key":{"type":"string"}},"required":["key_id","key"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"upstream_failure","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/tokens/{id}":{"delete":{"summary":"Revoke a key. Its balance moves to another of the account's keys. Answers 409 when it is the only key and holds a balance.","security":[{"forageKey":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"key_id":{"type":"string"},"revoked":{"type":"boolean","enum":[true]}},"required":["key_id","revoked"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"upstream_failure","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/webhooks":{"post":{"summary":"Register a signed webhook. Supported events: topup.completed, topup.refunded. The secret is returned once.","security":[{"forageKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["topup.completed","topup.refunded"]},"minItems":1}},"required":["url","events"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"secret":{"type":"string"},"secret_preview":{"type":"string"}},"required":["id","url","events","secret","secret_preview"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/top-up":{"post":{"summary":"Start a Stripe Checkout session to add credit to the calling account's API key","security":[{"forageKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"amount_cents":{"anyOf":[{"type":"number","enum":[500]},{"type":"number","enum":[5000]},{"type":"number","enum":[20000]}]}},"required":["amount_cents"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"checkout_url":{"type":"string","format":"uri"},"order_id":{"type":"string"},"session_id":{"type":"string"}},"required":["checkout_url","order_id","session_id"]},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"400":{"description":"validation_failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/api/v1/top-up/{sessionId}":{"get":{"summary":"Status of one top-up by its Stripe Checkout session id, scoped to the calling account","security":[{"forageKey":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["confirming","completed","refunded","failed"]},"amount_cents":{"type":"integer","exclusiveMinimum":0},"completed_at":{"type":["string","null"]}},"required":["status","amount_cents","completed_at"],"additionalProperties":false},"_links":{"type":"object","additionalProperties":{"type":"string"}}},"required":["data"]}}}},"401":{"description":"invalid_auth","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","additionalProperties":{}}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}}},"webhooks":{}}