{"openapi":"3.0.0","info":{"title":"Broctic API","version":"1.0.0","description":"Broctic control plane."},"components":{"schemas":{"LogEntry":{"type":"object","additionalProperties":{"nullable":true}},"AppleConnection":{"type":"object","nullable":true,"properties":{"issuerId":{"type":"string"},"keyId":{"type":"string"},"vendorNumber":{"type":"string"},"status":{"type":"string","enum":["connected","invalid","revoked"]},"connectedAt":{"type":"string"},"lastVerifiedAt":{"type":"string","nullable":true},"lastError":{"type":"string","nullable":true},"teamId":{"type":"string","nullable":true},"teamType":{"type":"string","nullable":true,"enum":["COMPANY_OR_ORGANIZATION","INDIVIDUAL"]}},"required":["issuerId","keyId","vendorNumber","status","connectedAt","lastVerifiedAt","lastError","teamId","teamType"]},"AppleAppLink":{"type":"object","properties":{"appleAppId":{"type":"string"},"bundleId":{"type":"string"},"name":{"type":"string"},"appId":{"type":"string","nullable":true},"linkedAt":{"type":"string","nullable":true},"storeState":{"type":"string","nullable":true,"enum":["not_submitted","waiting_for_review","in_review","rejected","pending_release","live","removed","unknown"]},"storeVersion":{"type":"string","nullable":true},"storeCheckedAt":{"type":"string","nullable":true}},"required":["appleAppId","bundleId","name","appId","linkedAt","storeState","storeVersion","storeCheckedAt"]},"AnalyticsFreshness":{"type":"object","properties":{"yesterday":{"type":"string"},"today":{"type":"string"},"todayExpectedBy":{"type":"string"},"state":{"type":"string","enum":["ready","awaiting","no_sales","error","unchecked"]},"checkedAt":{"type":"string","nullable":true},"publishExpectedBy":{"type":"string"},"lastRunAt":{"type":"string","nullable":true},"lastError":{"type":"string","nullable":true},"coveredFrom":{"type":"string","nullable":true},"coveredThrough":{"type":"string","nullable":true},"daysBehind":{"type":"number","nullable":true},"gaps":{"type":"number"}},"required":["yesterday","today","todayExpectedBy","state","checkedAt","publishExpectedBy","lastRunAt","lastError","coveredFrom","coveredThrough","daysBehind","gaps"]},"Analytics":{"type":"object","properties":{"window":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"days":{"type":"number"},"previousFrom":{"type":"string"},"previousTo":{"type":"string"}},"required":["from","to","days","previousFrom","previousTo"]},"currency":{"type":"string"},"freshness":{"$ref":"#/components/schemas/AnalyticsFreshness"},"totals":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds"]},"previous":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds"]},"yesterday":{"type":"object","nullable":true,"properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"day":{"type":"string"},"covered":{"type":"boolean"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","day","covered"]},"series":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"day":{"type":"string"},"covered":{"type":"boolean"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","day","covered"]}},"seriesByApp":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"day":{"type":"string"},"appleAppId":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","day","appleAppId"]}},"byApp":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"key":{"type":"string"},"label":{"type":"string"},"appleAppId":{"type":"string"},"appId":{"type":"string","nullable":true},"name":{"type":"string"},"bundleId":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","key","label","appleAppId","appId","name","bundleId"]}},"previousByApp":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"key":{"type":"string"},"label":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","key","label"]}},"byCountry":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"key":{"type":"string"},"label":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","key","label"]}},"byDevice":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"key":{"type":"string"},"label":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","key","label"]}},"byKind":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"key":{"type":"string"},"label":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","key","label"]}},"byProductType":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"key":{"type":"string"},"label":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","key","label"]}},"products":{"type":"array","items":{"type":"object","properties":{"proceedsMinor":{"type":"number"},"customerSpendMinor":{"type":"number"},"unconvertedProceedsMinor":{"type":"number"},"downloads":{"type":"number"},"redownloads":{"type":"number"},"updates":{"type":"number"},"iapUnits":{"type":"number"},"subscriptionUnits":{"type":"number"},"trials":{"type":"number"},"otherUnits":{"type":"number"},"refunds":{"type":"number"},"appleAppId":{"type":"string"},"sku":{"type":"string"},"title":{"type":"string"},"kind":{"type":"string"}},"required":["proceedsMinor","customerSpendMinor","unconvertedProceedsMinor","downloads","redownloads","updates","iapUnits","subscriptionUnits","trials","otherUnits","refunds","appleAppId","sku","title","kind"]}},"currencies":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"proceedsMinor":{"type":"number"}},"required":["currency","proceedsMinor"]}},"unconverted":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"proceedsMinor":{"type":"number"}},"required":["currency","proceedsMinor"]}},"daysMissingRates":{"type":"number"}},"required":["window","currency","freshness","totals","previous","yesterday","series","seriesByApp","byApp","previousByApp","byCountry","byDevice","byKind","byProductType","products","currencies","unconverted","daysMissingRates"]},"Entitlement":{"type":"object","properties":{"entitled":{"type":"boolean"},"status":{"type":"string","enum":["active","billing_grace","billing_retry","expired","revoked","none"]},"productId":{"type":"string","nullable":true},"expiresAt":{"type":"string","nullable":true},"graceExpiresAt":{"type":"string","nullable":true},"willRenew":{"type":"boolean"},"ownership":{"type":"string","nullable":true,"enum":["purchased","family_shared"]},"originalTransactionId":{"type":"string","nullable":true},"checkedAt":{"type":"string"}},"required":["entitled","status","productId","expiresAt","graceExpiresAt","willRenew","ownership","originalTransactionId","checkedAt"]},"IapConnection":{"type":"object","nullable":true,"properties":{"orgId":{"type":"string"},"keyId":{"type":"string"},"issuerId":{"type":"string"},"status":{"type":"string","enum":["connected","invalid"]},"connectedAt":{"type":"string"},"lastVerifiedAt":{"type":"string","nullable":true},"lastError":{"type":"string","nullable":true}},"required":["orgId","keyId","issuerId","status","connectedAt","lastVerifiedAt","lastError"]},"PreviewSession":{"type":"object","properties":{"available":{"type":"boolean"},"phase":{"type":"string","enum":["starting","installing","ready","error","stopping","stopped"]},"ready":{"type":"boolean"},"webUrl":{"type":"string","nullable":true},"expoUrl":{"type":"string","nullable":true},"version":{"type":"integer","nullable":true},"errors":{"type":"array","items":{"type":"string"}},"error":{"type":"string","nullable":true},"startedAt":{"type":"string","nullable":true}},"required":["available","phase","ready","webUrl","expoUrl","version","errors","error","startedAt"]}},"parameters":{}},"paths":{"/healthz":{"get":{"tags":["system"],"summary":"Liveness probe","responses":{"200":{"description":"Service is up","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}},"required":["ok","service"]}}}}}}},"/v1/apps/import":{"post":{"tags":["apps"],"summary":"Bring an app that is already on the App Store into the organization","description":"Picks one of the apps the organization's App Store Connect key can see. Name and bundle id come from Apple.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appleAppId":{"type":"string","minLength":1,"maxLength":40}},"required":["appleAppId"]}}}},"responses":{"201":{"description":"App imported","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"slug":{"type":"string","minLength":3,"maxLength":40,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},"displayName":{"type":"string"},"region":{"type":"string","enum":["us-east-1","us-west-1","eu-west-1"]},"status":{"type":"string","enum":["provisioning","active","paused","error"]},"source":{"type":"string","enum":["built_here","imported","website"],"default":"built_here"},"bundleId":{"type":"string","nullable":true,"default":null},"appleAppId":{"type":"string","nullable":true,"default":null},"iconUrl":{"type":"string","nullable":true,"default":null},"store":{"type":"object","nullable":true,"properties":{"state":{"type":"string","enum":["not_submitted","waiting_for_review","in_review","rejected","pending_release","live","removed","unknown"]},"version":{"type":"string","nullable":true},"checkedAt":{"type":"string","nullable":true}},"default":null,"required":["state","version","checkedAt"]},"createdAt":{"type":"string","format":"date-time"},"supabase":{"type":"object","nullable":true,"properties":{"projectRef":{"type":"string"},"connected":{"type":"boolean"}},"required":["projectRef","connected"]}},"required":["id","orgId","slug","displayName","region","status","createdAt","supabase"]}}}},"400":{"description":"No active organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such App Store app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Already imported","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Apple integration unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps":{"get":{"tags":["apps"],"summary":"List the active organization's apps","responses":{"200":{"description":"Apps in the caller's active org","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"slug":{"type":"string","minLength":3,"maxLength":40,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},"displayName":{"type":"string"},"region":{"type":"string","enum":["us-east-1","us-west-1","eu-west-1"]},"status":{"type":"string","enum":["provisioning","active","paused","error"]},"source":{"type":"string","enum":["built_here","imported","website"],"default":"built_here"},"bundleId":{"type":"string","nullable":true,"default":null},"appleAppId":{"type":"string","nullable":true,"default":null},"iconUrl":{"type":"string","nullable":true,"default":null},"store":{"type":"object","nullable":true,"properties":{"state":{"type":"string","enum":["not_submitted","waiting_for_review","in_review","rejected","pending_release","live","removed","unknown"]},"version":{"type":"string","nullable":true},"checkedAt":{"type":"string","nullable":true}},"default":null,"required":["state","version","checkedAt"]},"createdAt":{"type":"string","format":"date-time"},"supabase":{"type":"object","nullable":true,"properties":{"projectRef":{"type":"string"},"connected":{"type":"boolean"}},"required":["projectRef","connected"]}},"required":["id","orgId","slug","displayName","region","status","createdAt","supabase"]}}}}},"400":{"description":"No active organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["apps"],"summary":"Provision a new app backend","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","minLength":3,"maxLength":40,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},"displayName":{"type":"string","minLength":1,"maxLength":80},"region":{"type":"string","enum":["us-east-1","us-west-1","eu-west-1"],"default":"us-east-1"}},"required":["slug","displayName"]}}}},"responses":{"201":{"description":"App created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"slug":{"type":"string","minLength":3,"maxLength":40,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},"displayName":{"type":"string"},"region":{"type":"string","enum":["us-east-1","us-west-1","eu-west-1"]},"status":{"type":"string","enum":["provisioning","active","paused","error"]},"source":{"type":"string","enum":["built_here","imported","website"],"default":"built_here"},"bundleId":{"type":"string","nullable":true,"default":null},"appleAppId":{"type":"string","nullable":true,"default":null},"iconUrl":{"type":"string","nullable":true,"default":null},"store":{"type":"object","nullable":true,"properties":{"state":{"type":"string","enum":["not_submitted","waiting_for_review","in_review","rejected","pending_release","live","removed","unknown"]},"version":{"type":"string","nullable":true},"checkedAt":{"type":"string","nullable":true}},"default":null,"required":["state","version","checkedAt"]},"createdAt":{"type":"string","format":"date-time"},"supabase":{"type":"object","nullable":true,"properties":{"projectRef":{"type":"string"},"connected":{"type":"boolean"}},"required":["projectRef","connected"]}},"required":["id","orgId","slug","displayName","region","status","createdAt","supabase"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}":{"get":{"tags":["apps"],"summary":"Fetch an app by id","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The app","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"slug":{"type":"string","minLength":3,"maxLength":40,"pattern":"^[a-z][a-z0-9-]*[a-z0-9]$"},"displayName":{"type":"string"},"region":{"type":"string","enum":["us-east-1","us-west-1","eu-west-1"]},"status":{"type":"string","enum":["provisioning","active","paused","error"]},"source":{"type":"string","enum":["built_here","imported","website"],"default":"built_here"},"bundleId":{"type":"string","nullable":true,"default":null},"appleAppId":{"type":"string","nullable":true,"default":null},"iconUrl":{"type":"string","nullable":true,"default":null},"store":{"type":"object","nullable":true,"properties":{"state":{"type":"string","enum":["not_submitted","waiting_for_review","in_review","rejected","pending_release","live","removed","unknown"]},"version":{"type":"string","nullable":true},"checkedAt":{"type":"string","nullable":true}},"default":null,"required":["state","version","checkedAt"]},"createdAt":{"type":"string","format":"date-time"},"supabase":{"type":"object","nullable":true,"properties":{"projectRef":{"type":"string"},"connected":{"type":"boolean"}},"required":["projectRef","connected"]}},"required":["id","orgId","slug","displayName","region","status","createdAt","supabase"]}}}},"400":{"description":"No active organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["apps"],"summary":"Delete an app and everything stored against it","description":"Irreversible. Removes the app, its build history and artifact bytes, store screenshots, spec and app system document. Does not modify the customer's GitHub repository or revoke the App installation — those are theirs to undo on GitHub.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","maxLength":200,"description":"The app's slug, typed to confirm deletion"},"required":false,"description":"The app's slug, typed to confirm deletion","name":"confirm","in":"query"}],"responses":{"200":{"description":"The app was deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]},"id":{"type":"string"},"displayName":{"type":"string"},"note":{"type":"string"}},"required":["deleted","id","displayName","note"]}}}},"400":{"description":"No active organization, or the typed confirmation did not match","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/marketing/connections":{"get":{"tags":["marketing"],"summary":"This app's social connections (Instagram, TikTok)","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Connection status","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"instagram":{"type":"object","properties":{"status":{"type":"string","enum":["not_connected","connected"]},"handle":{"type":"string","nullable":true},"displayName":{"type":"string","nullable":true},"profileImageUrl":{"type":"string","nullable":true},"connectedAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["status","handle","displayName","profileImageUrl","connectedAt"]},"tiktok":{"type":"object","properties":{"status":{"type":"string","enum":["not_connected","connected"]},"handle":{"type":"string","nullable":true},"displayName":{"type":"string","nullable":true},"profileImageUrl":{"type":"string","nullable":true},"connectedAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["status","handle","displayName","profileImageUrl","connectedAt"]},"lastCheckedAt":{"type":"string","nullable":true,"format":"date-time"},"uploadPostUsername":{"type":"string","nullable":true}},"required":["appId","instagram","tiktok","lastCheckedAt","uploadPostUsername"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/marketing/connections/{platform}/connect":{"post":{"tags":["marketing"],"summary":"Get a link to connect one platform for this app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["instagram","tiktok"]},"required":true,"name":"platform","in":"path"}],"responses":{"200":{"description":"Visit accessUrl to connect the platform on upload-post.com's hosted page","content":{"application/json":{"schema":{"type":"object","properties":{"accessUrl":{"type":"string"}},"required":["accessUrl"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"upload-post.com rejected the request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"upload-post.com is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/marketing/connections/refresh":{"post":{"tags":["marketing"],"summary":"Re-check this app's social connections against upload-post.com","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Updated connection status","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"instagram":{"type":"object","properties":{"status":{"type":"string","enum":["not_connected","connected"]},"handle":{"type":"string","nullable":true},"displayName":{"type":"string","nullable":true},"profileImageUrl":{"type":"string","nullable":true},"connectedAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["status","handle","displayName","profileImageUrl","connectedAt"]},"tiktok":{"type":"object","properties":{"status":{"type":"string","enum":["not_connected","connected"]},"handle":{"type":"string","nullable":true},"displayName":{"type":"string","nullable":true},"profileImageUrl":{"type":"string","nullable":true},"connectedAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["status","handle","displayName","profileImageUrl","connectedAt"]},"lastCheckedAt":{"type":"string","nullable":true,"format":"date-time"},"uploadPostUsername":{"type":"string","nullable":true}},"required":["appId","instagram","tiktok","lastCheckedAt","uploadPostUsername"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"upload-post.com rejected the request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"upload-post.com is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/marketing/scheduled":{"get":{"tags":["marketing"],"summary":"Posts already scheduled on upload-post.com for this app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Scheduled posts","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"jobId":{"type":"string"},"scheduledAt":{"type":"string","format":"date-time"},"postType":{"type":"string"},"platforms":{"type":"array","items":{"type":"string"}},"title":{"type":"string","nullable":true},"caption":{"type":"string","nullable":true},"previewUrl":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true}},"required":["jobId","scheduledAt","postType","platforms","title","caption","previewUrl","thumbnailUrl"]}}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"upload-post.com is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/marketing/history":{"get":{"tags":["marketing"],"summary":"What upload-post.com has actually published for this app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Publish history and total count","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string"},"mediaType":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"success":{"type":"boolean"},"postUrl":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"caption":{"type":"string","nullable":true},"errorMessage":{"type":"string","nullable":true}},"required":["platform","mediaType","publishedAt","success","postUrl","title","caption","errorMessage"]}},"total":{"type":"integer","minimum":0}},"required":["posts","total"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"upload-post.com is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/marketing/analytics":{"get":{"tags":["marketing"],"summary":"Per-platform performance for this app, from upload-post.com","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Performance by connected platform","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","tiktok"]},"followers":{"type":"number","nullable":true},"reach":{"type":"number","nullable":true},"views":{"type":"number","nullable":true},"impressions":{"type":"number","nullable":true},"likes":{"type":"number","nullable":true},"comments":{"type":"number","nullable":true},"shares":{"type":"number","nullable":true},"primaryMetric":{"type":"string","nullable":true,"enum":["reach","views","impressions"]},"timeseries":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"value":{"type":"number"}},"required":["date","value"]}}},"required":["platform","followers","reach","views","impressions","likes","comments","shares","primaryMetric","timeseries"]}}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such app in this organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"upload-post.com is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/supabase":{"post":{"tags":["supabase"],"summary":"Connect a Supabase project to an app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"existingProjectRef":{"type":"string"}}}}}},"responses":{"201":{"description":"Connected","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"projectRef":{"type":"string"},"url":{"type":"string","format":"uri"},"connected":{"type":"boolean","enum":[true]}},"required":["appId","projectRef","url","connected"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/onboarding":{"get":{"tags":["onboarding"],"summary":"Whether the current user has completed onboarding","responses":{"200":{"description":"Onboarding state","content":{"application/json":{"schema":{"type":"object","properties":{"completed":{"type":"boolean"},"source":{"type":"string","nullable":true,"enum":["search","ai_assistant","reddit","hacker_news","x_twitter","github","youtube","friend","content","other"]},"building":{"type":"string","nullable":true},"completedAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["completed","source","building","completedAt"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["onboarding"],"summary":"Record the onboarding survey and mark it complete","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","enum":["search","ai_assistant","reddit","hacker_news","x_twitter","github","youtube","friend","content","other"]},"sourceDetail":{"type":"string","maxLength":280},"building":{"type":"string","maxLength":280}}}}}},"responses":{"200":{"description":"Onboarding recorded","content":{"application/json":{"schema":{"type":"object","properties":{"completed":{"type":"boolean"},"source":{"type":"string","nullable":true,"enum":["search","ai_assistant","reddit","hacker_news","x_twitter","github","youtube","friend","content","other"]},"building":{"type":"string","nullable":true},"completedAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["completed","source","building","completedAt"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/logs":{"get":{"tags":["logs"],"summary":"Query recent log events","parameters":[{"schema":{"type":"string"},"required":false,"name":"resource","in":"query"},{"schema":{"type":"string","enum":["trace","debug","info","warn","error","fatal"]},"required":false,"name":"level","in":"query"},{"schema":{"type":"string"},"required":false,"name":"q","in":"query"},{"schema":{"type":"number","nullable":true,"description":"Only events at or after this ms-epoch timestamp"},"required":false,"name":"since","in":"query"},{"schema":{"type":"number","nullable":true,"description":"Only events at or before this ms-epoch timestamp"},"required":false,"name":"until","in":"query"},{"schema":{"type":"string","description":"Only events from this environment (e.g. production)"},"required":false,"name":"env","in":"query"},{"schema":{"type":"string","maxLength":128,"description":"Everything that happened during one request"},"required":false,"name":"requestId","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Recent log events, newest first","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/LogEntry"}},"resources":{"type":"array","items":{"type":"string"}},"envs":{"type":"array","items":{"type":"string"}},"total":{"type":"number"},"source":{"type":"string","enum":["postgres","memory"]},"dropped":{"type":"number"}},"required":["entries","resources","envs","total","source","dropped"]}}}}}},"post":{"tags":["logs"],"summary":"Report a client-side log event","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"level":{"type":"string","enum":["trace","debug","info","warn","error","fatal"],"default":"info"},"message":{"type":"string","minLength":1,"maxLength":2000},"service":{"type":"string","maxLength":64,"default":"broctic-dashboard"},"fields":{"type":"object","additionalProperties":{"nullable":true}}},"required":["message"]}}}},"responses":{"202":{"description":"Event accepted","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]}},"required":["accepted"]}}}}}}},"/v1/apple/connection":{"get":{"tags":["analytics"],"summary":"The organization's App Store Connect connection","responses":{"200":{"description":"The connection, or null when none is set up","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppleConnection"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["analytics"],"summary":"Connect or replace the App Store Connect key","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"issuerId":{"type":"string","minLength":8,"maxLength":100},"keyId":{"type":"string","minLength":4,"maxLength":40},"vendorNumber":{"type":"string","minLength":4,"maxLength":20},"privateKey":{"type":"string","minLength":100,"maxLength":8000},"teamId":{"type":"string","pattern":"^[A-Za-z0-9]{10}$"},"teamType":{"type":"string","enum":["COMPANY_OR_ORGANIZATION","INDIVIDUAL"]}},"required":["issuerId","keyId","vendorNumber","privateKey"]}}}},"responses":{"201":{"description":"Verified against Apple and stored","content":{"application/json":{"schema":{"type":"object","properties":{"connection":{"$ref":"#/components/schemas/AppleConnection"},"discoveredApps":{"type":"number"}},"required":["connection","discoveredApps"]}}}},"400":{"description":"Apple rejected the credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Not allowed, or the key lacks the required Apple role","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Apple has no such resource","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Apple is rate limiting this key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"App Store Connect is unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Secret storage unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["analytics"],"summary":"Remove the App Store Connect key","responses":{"204":{"description":"Removed"},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apple/apps":{"get":{"tags":["analytics"],"summary":"App Store apps this key can see, and what they map to","responses":{"200":{"description":"Apple's apps, linked and unlinked","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AppleAppLink"}}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apple/apps/refresh":{"post":{"tags":["analytics"],"summary":"Re-read Apple's app list","responses":{"200":{"description":"Catalogue refreshed","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"number"}},"required":["count"]}}}},"400":{"description":"Apple rejected the credentials","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The key lacks the required Apple role","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Nothing connected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Apple is rate limiting this key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"App Store Connect is unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apple/apps/link":{"post":{"tags":["analytics"],"summary":"Map an App Store app to a Broctic app, or unlink it","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appleAppId":{"type":"string","minLength":1,"maxLength":40},"appId":{"type":"string","nullable":true,"minLength":1,"maxLength":64}},"required":["appleAppId","appId"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"linked":{"type":"boolean"}},"required":["linked"]}}}},"404":{"description":"Unknown App Store app","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/analytics":{"get":{"tags":["analytics"],"summary":"Stored App Store figures for a window","parameters":[{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"to","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":400},"required":false,"name":"days","in":"query"},{"schema":{"type":"string","minLength":3,"maxLength":3},"required":false,"name":"currency","in":"query"}],"responses":{"200":{"description":"What has been pulled from Apple, with how current it is","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Analytics"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/analytics/sync":{"post":{"tags":["analytics"],"summary":"Pull the days that need pulling from Apple","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"force":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Ran. `daysRemaining` counts history still to collect","content":{"application/json":{"schema":{"type":"object","properties":{"checked":{"type":"number"},"rowsWritten":{"type":"number"},"daysRemaining":{"type":"number"},"coveredThrough":{"type":"string","nullable":true},"stoppedBecause":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["checked","rowsWritten","daysRemaining","coveredThrough","stoppedBecause","skipped"]}}}},"404":{"description":"Nothing connected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/analytics/sync-all":{"post":{"tags":["analytics"],"summary":"Pull the days that need pulling, for every connected organization","description":"Called by the scheduler. Requires the shared cron secret.","responses":{"200":{"description":"Ran","content":{"application/json":{"schema":{"type":"object","properties":{"organizations":{"type":"number"},"synced":{"type":"number"},"rowsWritten":{"type":"number"},"deferred":{"type":"number"},"errors":{"type":"array","items":{"type":"object","properties":{"orgId":{"type":"string"},"message":{"type":"string"}},"required":["orgId","message"]}}},"required":["organizations","synced","rowsWritten","deferred","errors"]}}}},"404":{"description":"Not available","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/events":{"post":{"tags":["events"],"summary":"Send product events from an app","description":"Authenticate with the app's publishable key in the `x-broctic-key` header. Up to 100 events per request. Event names are lowercase_with_underscores.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"ts":{"type":"string","format":"date-time"},"anonymousId":{"type":"string","minLength":8,"maxLength":128},"userId":{"type":"string","maxLength":128},"sessionId":{"type":"string","maxLength":128},"props":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"number"},{"type":"boolean"},{"nullable":true},{"nullable":true}]}}},"required":["name","anonymousId"]},"minItems":1,"maxItems":100},"context":{"type":"object","properties":{"platform":{"type":"string","enum":["ios","android","web","macos","other"]},"appVersion":{"type":"string","maxLength":40},"osVersion":{"type":"string","maxLength":40},"locale":{"type":"string","maxLength":16},"country":{"type":"string","minLength":2,"maxLength":2}}}},"required":["events"]}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"number"}},"required":["accepted"]}}}},"400":{"description":"Invalid batch","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or unknown key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many batches","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/keys":{"get":{"tags":["events"],"summary":"The app's publishable keys","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Keys, revoked ones included","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"createdAt":{"type":"string"},"revokedAt":{"type":"string","nullable":true}},"required":["id","appId","name","prefix","createdAt","revokedAt"]}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["events"],"summary":"Create a publishable key","description":"The secret is returned once. It can only write events for this app.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":60}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"createdAt":{"type":"string"},"revokedAt":{"type":"string","nullable":true}},"required":["id","appId","name","prefix","createdAt","revokedAt"]},"secret":{"type":"string"}},"required":["key","secret"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/keys/{keyId}":{"delete":{"tags":["events"],"summary":"Revoke a publishable key","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"name":"keyId","in":"path"}],"responses":{"204":{"description":"Revoked"},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/events/summary":{"get":{"tags":["events"],"summary":"What events have arrived","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":400},"required":false,"name":"days","in":"query"}],"responses":{"200":{"description":"Summary","content":{"application/json":{"schema":{"type":"object","properties":{"people":{"type":"integer","minimum":0},"events":{"type":"integer","minimum":0},"firstEventAt":{"type":"string","nullable":true},"lastEventAt":{"type":"string","nullable":true},"names":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"events":{"type":"integer","minimum":0},"people":{"type":"integer","minimum":0},"standard":{"type":"boolean"}},"required":["name","events","people","standard"]}},"platforms":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string"},"people":{"type":"integer"}},"required":["platform","people"]}},"versions":{"type":"array","items":{"type":"object","properties":{"appVersion":{"type":"string"},"people":{"type":"integer"}},"required":["appVersion","people"]}}},"required":["people","events","firstEventAt","lastEventAt","names","platforms","versions"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnels":{"get":{"tags":["events"],"summary":"The app's funnels","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Funnels, default first","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":80},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","name","steps","isDefault","createdAt","updatedAt"]}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["events"],"summary":"Create a funnel","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},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"}},"required":["name","steps"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":80},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","name","steps","isDefault","createdAt","updatedAt"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnels/{funnelId}":{"put":{"tags":["events"],"summary":"Replace a funnel's name and steps","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"name":"funnelId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"}},"required":["name","steps"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":80},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","name","steps","isDefault","createdAt","updatedAt"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["events"],"summary":"Delete a funnel","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"name":"funnelId","in":"path"}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnels/{funnelId}/report":{"get":{"tags":["events"],"summary":"How many people reached each step","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"name":"funnelId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":400},"required":false,"name":"days","in":"query"}],"responses":{"200":{"description":"The report","content":{"application/json":{"schema":{"type":"object","properties":{"funnel":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":80},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","name","steps","isDefault","createdAt","updatedAt"]},"window":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"days":{"type":"integer"}},"required":["from","to","days"]},"activePeople":{"type":"integer","minimum":0},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"people":{"type":"integer","minimum":0},"conversion":{"type":"number","nullable":true,"minimum":0,"maximum":1},"fromStart":{"type":"number","nullable":true,"minimum":0,"maximum":1},"medianSeconds":{"type":"number","nullable":true,"minimum":0}},"required":["step","people","conversion","fromStart","medianSeconds"]}},"recommendations":{"type":"array","items":{"type":"object","properties":{"stepIndex":{"type":"integer","nullable":true,"minimum":0},"verdict":{"type":"string","enum":["strong","typical","weak","unknown"]},"title":{"type":"string"},"finding":{"type":"string"},"action":{"type":"string"},"source":{"type":"string"},"impact":{"type":"string","enum":["high","medium","low"]}},"required":["stepIndex","verdict","title","finding","action","source","impact"]}},"thin":{"type":"boolean"},"source":{"type":"string","enum":["posthog","broctic"]},"breakdown":{"type":"object","properties":{"prop":{"type":"string"},"arms":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"people":{"type":"integer","minimum":0},"conversion":{"type":"number","nullable":true,"minimum":0,"maximum":1},"fromStart":{"type":"number","nullable":true,"minimum":0,"maximum":1},"medianSeconds":{"type":"number","nullable":true,"minimum":0}},"required":["step","people","conversion","fromStart","medianSeconds"]}},"thin":{"type":"boolean"}},"required":["value","steps","thin"]}},"source":{"type":"string","enum":["broctic"]}},"required":["prop","arms","source"]}},"required":["funnel","window","activePeople","steps","recommendations","thin","source"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/insights":{"get":{"tags":["events"],"summary":"Store conversion, the default funnel, and what to do about them","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":400},"required":false,"name":"days","in":"query"},{"schema":{"type":"string","minLength":3,"maxLength":3},"required":false,"name":"currency","in":"query"}],"responses":{"200":{"description":"Insights","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"store":{"type":"object","nullable":true,"properties":{"window":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"days":{"type":"integer"}},"required":["from","to","days"]},"currency":{"type":"string"},"downloads":{"type":"integer","minimum":0},"trials":{"type":"integer","minimum":0},"paid":{"type":"integer","minimum":0},"refunds":{"type":"integer","minimum":0},"proceedsMinor":{"type":"integer"},"downloadToTrial":{"type":"number","nullable":true,"minimum":0},"trialToPaid":{"type":"number","nullable":true,"minimum":0},"downloadToPaid":{"type":"number","nullable":true,"minimum":0},"refundRate":{"type":"number","nullable":true,"minimum":0},"proceedsPerDownloadMinor":{"type":"number","nullable":true}},"required":["window","currency","downloads","trials","paid","refunds","proceedsMinor","downloadToTrial","trialToPaid","downloadToPaid","refundRate","proceedsPerDownloadMinor"]},"funnel":{"type":"object","nullable":true,"properties":{"funnel":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":80},"steps":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"minItems":2,"maxItems":12},"isDefault":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","name","steps","isDefault","createdAt","updatedAt"]},"window":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"days":{"type":"integer"}},"required":["from","to","days"]},"activePeople":{"type":"integer","minimum":0},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"people":{"type":"integer","minimum":0},"conversion":{"type":"number","nullable":true,"minimum":0,"maximum":1},"fromStart":{"type":"number","nullable":true,"minimum":0,"maximum":1},"medianSeconds":{"type":"number","nullable":true,"minimum":0}},"required":["step","people","conversion","fromStart","medianSeconds"]}},"recommendations":{"type":"array","items":{"type":"object","properties":{"stepIndex":{"type":"integer","nullable":true,"minimum":0},"verdict":{"type":"string","enum":["strong","typical","weak","unknown"]},"title":{"type":"string"},"finding":{"type":"string"},"action":{"type":"string"},"source":{"type":"string"},"impact":{"type":"string","enum":["high","medium","low"]}},"required":["stepIndex","verdict","title","finding","action","source","impact"]}},"thin":{"type":"boolean"},"source":{"type":"string","enum":["posthog","broctic"]},"breakdown":{"type":"object","properties":{"prop":{"type":"string"},"arms":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":60},"where":{"type":"object","properties":{"prop":{"type":"string","maxLength":64},"equals":{"type":"string","maxLength":200}},"required":["prop","equals"]}},"required":["event","label"]},"people":{"type":"integer","minimum":0},"conversion":{"type":"number","nullable":true,"minimum":0,"maximum":1},"fromStart":{"type":"number","nullable":true,"minimum":0,"maximum":1},"medianSeconds":{"type":"number","nullable":true,"minimum":0}},"required":["step","people","conversion","fromStart","medianSeconds"]}},"thin":{"type":"boolean"}},"required":["value","steps","thin"]}},"source":{"type":"string","enum":["broctic"]}},"required":["prop","arms","source"]}},"required":["funnel","window","activePeople","steps","recommendations","thin","source"]},"recommendations":{"type":"array","items":{"type":"object","properties":{"stepIndex":{"type":"integer","nullable":true,"minimum":0},"verdict":{"type":"string","enum":["strong","typical","weak","unknown"]},"title":{"type":"string"},"finding":{"type":"string"},"action":{"type":"string"},"source":{"type":"string"},"impact":{"type":"string","enum":["high","medium","low"]}},"required":["stepIndex","verdict","title","finding","action","source","impact"]}}},"required":["appId","store","funnel","recommendations"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/purchases/entitlement":{"get":{"tags":["purchases"],"summary":"Whether this person may use what they paid for","description":"Authenticate with the app's publishable key in the `x-broctic-key` header. Answered from what Apple has already told us, so it costs no network call to Apple and is safe on every launch. Branch on `entitled`; everything else is detail.","parameters":[{"schema":{"type":"string","minLength":8,"maxLength":128},"required":true,"name":"anonymousId","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":128},"required":false,"name":"userId","in":"query"}],"responses":{"200":{"description":"The entitlement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Entitlement"}}}},"401":{"description":"Missing or unknown key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many calls","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/purchases/verify":{"post":{"tags":["purchases"],"summary":"Hand us a purchase the moment it completes","description":"Send StoreKit 2's signed transaction. It is verified against Apple's certificate chain, so this is not trusting the device — and it is what makes entitlement true in the second after a purchase instead of whenever Apple's notification arrives. Sending the `appAccountToken` with the purchase is what lets a future renewal be attributed to this person.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"signedTransaction":{"type":"string","minLength":32,"maxLength":16000},"anonymousId":{"type":"string","minLength":8,"maxLength":128},"userId":{"type":"string","minLength":1,"maxLength":128}},"required":["signedTransaction","anonymousId"]}}}},"responses":{"200":{"description":"The entitlement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Entitlement"}}}},"400":{"description":"Not a valid Apple transaction","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or unknown key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many calls","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Apple could not be reached","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/purchases/notifications":{"post":{"tags":["purchases"],"summary":"Receive an App Store Server Notification (V2)","description":"One URL for every app and both environments. Set it in App Store Connect under App Information → App Store Server Notifications, in the Production and Sandbox fields. The payload is a signed JWS; the bundle id inside it decides which app it belongs to, after the signature is checked.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"signedPayload":{"type":"string","minLength":32,"maxLength":200000}},"required":["signedPayload"]}}}},"responses":{"200":{"description":"Kept. Also the answer to a duplicate, which is not a failure.","content":{"application/json":{"schema":{"type":"object","properties":{"stored":{"type":"boolean"},"event":{"type":"string","nullable":true}},"required":["stored","event"]}}}},"400":{"description":"Not a verifiable notification","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No app here has that bundle id","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many deliveries","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Verification could not be completed. The one case worth a retry — answering 2xx here would lose the delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/purchases/connection":{"get":{"tags":["purchases"],"summary":"The organization's In-App Purchase key","description":"Never includes the key itself. `status` is `invalid` when Apple last refused it.","responses":{"200":{"description":"The connection, or null","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IapConnection"}}}}}},"put":{"tags":["purchases"],"summary":"Connect an In-App Purchase key","description":"From App Store Connect → Users and Access → Integrations → **In-App Purchase**. This is not the App Store Connect key on the neighbouring tab: the two look identical and are rejected by each other's endpoints. The .p8 is sealed before it is stored and is returned by no route.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","minLength":4,"maxLength":64},"issuerId":{"type":"string","minLength":8,"maxLength":128},"privateKey":{"type":"string","minLength":64,"maxLength":8000}},"required":["keyId","issuerId","privateKey"]}}}},"responses":{"200":{"description":"Stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IapConnection"}}}},"401":{"description":"No session","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["purchases"],"summary":"Disconnect the In-App Purchase key","description":"Deletes the key. Purchases already recorded stay; entitlement keeps answering from them, and stops moving when the next notification cannot be processed.","responses":{"204":{"description":"Disconnected"},"401":{"description":"No session","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/purchases/catch-up":{"post":{"tags":["purchases"],"summary":"Replay stored notifications that failed, and recover the ones Apple could not deliver","description":"Called by the scheduler. Requires the shared cron secret.","responses":{"200":{"description":"Ran","content":{"application/json":{"schema":{"type":"object","properties":{"replayed":{"type":"number"},"recovered":{"type":"number"},"skipped":{"type":"array","items":{"type":"object","properties":{"appId":{"type":"string"},"reason":{"type":"string"}},"required":["appId","reason"]}}},"required":["replayed","recovered","skipped"]}}}},"404":{"description":"Not available","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/posthog/connection":{"get":{"tags":["posthog"],"summary":"The organization's PostHog connection","description":"Never the personal API key. `projectCount` is how many of this organization's apps have a PostHog project — the number that explains why a free PostHog organization refuses a second one.","responses":{"200":{"description":"The connection, or null when none is set up","content":{"application/json":{"schema":{"type":"object","nullable":true,"properties":{"connected":{"type":"boolean"},"host":{"type":"string"},"organizationId":{"type":"string"},"organizationName":{"type":"string"},"projectCount":{"type":"integer"},"status":{"type":"string","enum":["connected","invalid","revoked"]},"connectedAt":{"type":"string"},"lastVerifiedAt":{"type":"string","nullable":true},"lastError":{"type":"string","nullable":true}},"required":["connected","host","organizationId","organizationName","projectCount","status","connectedAt","lastVerifiedAt","lastError"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["posthog"],"summary":"Connect or replace the PostHog personal API key","description":"The key is verified against PostHog before anything is stored, then sealed with AES-256-GCM. Create it in PostHog → Settings → Personal API keys with these scopes: user:read, organization:read, project:read, project:write, session_recording:read, query:read.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string","enum":["https://us.i.posthog.com","https://eu.i.posthog.com"],"default":"https://us.i.posthog.com"},"personalApiKey":{"type":"string","minLength":20,"maxLength":200},"organizationId":{"type":"string","minLength":1,"maxLength":64}},"required":["personalApiKey"]}}}},"responses":{"201":{"description":"Verified against PostHog and stored","content":{"application/json":{"schema":{"type":"object","properties":{"connected":{"type":"boolean"},"host":{"type":"string"},"organizationId":{"type":"string"},"organizationName":{"type":"string"},"projectCount":{"type":"integer"},"status":{"type":"string","enum":["connected","invalid","revoked"]},"connectedAt":{"type":"string"},"lastVerifiedAt":{"type":"string","nullable":true},"lastError":{"type":"string","nullable":true}},"required":["connected","host","organizationId","organizationName","projectCount","status","connectedAt","lastVerifiedAt","lastError"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["posthog"],"summary":"Remove the PostHog key","description":"The key is deleted. App→project mappings are kept, because the PostHog projects still exist and the shipped builds are still writing into them — forgetting where an app's data goes is not part of forgetting a credential.","responses":{"204":{"description":"Removed"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/posthog":{"get":{"tags":["posthog"],"summary":"This app's PostHog project, or null","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The link, or null","content":{"application/json":{"schema":{"type":"object","nullable":true,"properties":{"appId":{"type":"string"},"posthogProjectId":{"type":"integer"},"projectName":{"type":"string"},"projectApiToken":{"type":"string"},"host":{"type":"string"},"url":{"type":"string"},"sessionRecordingOptIn":{"type":"boolean"},"createdAt":{"type":"string"}},"required":["appId","posthogProjectId","projectName","projectApiToken","host","url","sessionRecordingOptIn","createdAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/posthog/link":{"post":{"tags":["posthog"],"summary":"Create this app's PostHog project, or adopt an existing one","description":"With no `projectId`, creates a project named after the app and stores the `phc_…` write key from the 201 body. With one, adopts that project instead — a founder who already runs PostHog keeps their history. Session replay is switched on unless you say otherwise.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"integer","minimum":0,"exclusiveMinimum":true},"enableSessionRecording":{"type":"boolean","default":true},"recordingDomains":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":10}}}}}},"responses":{"201":{"description":"Linked","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"posthogProjectId":{"type":"integer"},"projectName":{"type":"string"},"projectApiToken":{"type":"string"},"host":{"type":"string"},"url":{"type":"string"},"sessionRecordingOptIn":{"type":"boolean"},"createdAt":{"type":"string"}},"required":["appId","posthogProjectId","projectName","projectApiToken","host","url","sessionRecordingOptIn","createdAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["posthog"],"summary":"Forget this app's PostHog project","description":"The PostHog project and everything in it are left alone. Deleting a customer's analytics because they unlinked an app would be destroying data we do not own to tidy up a row we do.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Unlinked"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/posthog/recordings":{"get":{"tags":["posthog"],"summary":"Session recordings, summarised, with links into PostHog","description":"`friction` (the default) is sessions where `error_shown` or `$rageclick` fired, ordered by console errors; `funnel` is sessions that touched onboarding; `all` filters on nothing. Never the raw snapshots — PostHog documents that endpoint as never built for public use, and proxying a customer's users' screens through this API is not a decision anybody has made.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["friction","funnel","all"],"default":"friction"},"required":false,"name":"filter","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":10},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Up to `limit` recordings","content":{"application/json":{"schema":{"type":"object","properties":{"filter":{"type":"string","enum":["friction","funnel","all"]},"recordings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"distinctId":{"type":"string","nullable":true},"startedAt":{"type":"string"},"durationSeconds":{"type":"integer"},"clickCount":{"type":"integer"},"keypressCount":{"type":"integer"},"consoleErrorCount":{"type":"integer"},"url":{"type":"string"}},"required":["id","distinctId","startedAt","durationSeconds","clickCount","keypressCount","consoleErrorCount","url"]}},"hasMore":{"type":"boolean"}},"required":["filter","recordings","hasMore"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/posthog/events/summary":{"get":{"tags":["posthog"],"summary":"What PostHog has received lately, by event name","description":"A HogQL aggregate over the last `days` days (7 by default). The answer to 'is anything arriving at all'. Zero is a real answer — an app that has not shipped, or a build without the key — and is reported as zero rather than as no data.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":90,"default":7},"required":false,"name":"days","in":"query"}],"responses":{"200":{"description":"Counts by event name","content":{"application/json":{"schema":{"type":"object","properties":{"days":{"type":"integer"},"from":{"type":"string"},"to":{"type":"string"},"events":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"count":{"type":"integer"},"people":{"type":"integer"}},"required":["name","count","people"]}},"total":{"type":"integer"}},"required":["days","from","to","events","total"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/org/plan":{"get":{"tags":["plans"],"summary":"This organization's plan, its limits, and this month's usage","responses":{"200":{"description":"The plan","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["free","pro","max","internal"]},"name":{"type":"string"},"limits":{"type":"object","properties":{"apps":{"type":"integer","nullable":true},"members":{"type":"integer","nullable":true},"aiUsdPerMonth":{"type":"number","nullable":true},"nativeBuildsPerMonth":{"type":"integer","nullable":true},"runnerJobsPerMonth":{"type":"integer","nullable":true},"previewHoursPerMonth":{"type":"number","nullable":true},"socialPostsPerMonth":{"type":"integer","nullable":true}},"required":["apps","members","aiUsdPerMonth","nativeBuildsPerMonth","runnerJobsPerMonth","previewHoursPerMonth","socialPostsPerMonth"]},"month":{"type":"string"},"usage":{"type":"object","properties":{"aiUsd":{"type":"number"},"aiCalls":{"type":"integer"},"aiInputTokens":{"type":"integer"},"aiOutputTokens":{"type":"integer"},"nativeBuilds":{"type":"integer"},"runnerJobs":{"type":"integer"},"previewHours":{"type":"number"},"socialPosts":{"type":"integer"},"costUsd":{"type":"number"}},"required":["aiUsd","aiCalls","aiInputTokens","aiOutputTokens","nativeBuilds","runnerJobs","previewHours","socialPosts","costUsd"]},"apps":{"type":"integer"},"members":{"type":"integer"}},"required":["plan","name","limits","month","usage","apps","members"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/admin/usage":{"get":{"tags":["admin"],"summary":"What every organization cost this month, by plan","parameters":[{"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"YYYY-MM, UTC. Defaults to this month."},"required":false,"name":"month","in":"query"}],"responses":{"200":{"description":"The report","content":{"application/json":{"schema":{"type":"object","properties":{"month":{"type":"string"},"plans":{"type":"array","items":{"type":"object","properties":{"plan":{"type":"string","enum":["free","pro","max","internal"]},"orgs":{"type":"integer"},"activeOrgs":{"type":"integer"},"costUsd":{"type":"number"},"avgCostPerOrgUsd":{"type":"number"},"listRevenueUsd":{"type":"number","nullable":true}},"required":["plan","orgs","activeOrgs","costUsd","avgCostPerOrgUsd","listRevenueUsd"]}},"orgs":{"type":"array","items":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"plan":{"type":"string","enum":["free","pro","max","internal"]},"planNote":{"type":"string","nullable":true},"createdAt":{"type":"string","nullable":true},"apps":{"type":"integer"},"members":{"type":"integer"},"usage":{"type":"object","properties":{"aiUsd":{"type":"number"},"aiCalls":{"type":"integer"},"aiInputTokens":{"type":"integer"},"aiOutputTokens":{"type":"integer"},"nativeBuilds":{"type":"integer"},"runnerJobs":{"type":"integer"},"previewHours":{"type":"number"},"socialPosts":{"type":"integer"},"costUsd":{"type":"number"}},"required":["aiUsd","aiCalls","aiInputTokens","aiOutputTokens","nativeBuilds","runnerJobs","previewHours","socialPosts","costUsd"]}},"required":["orgId","name","plan","planNote","createdAt","apps","members","usage"]}},"unattributedCostUsd":{"type":"number"}},"required":["month","plans","orgs","unattributedCostUsd"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/admin/usage/orgs/{orgId}":{"get":{"tags":["admin"],"summary":"One organization's metered events this month (newest 200)","parameters":[{"schema":{"type":"string","maxLength":64},"required":true,"name":"orgId","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"YYYY-MM, UTC. Defaults to this month."},"required":false,"name":"month","in":"query"}],"responses":{"200":{"description":"The organization and its events","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"type":"object","nullable":true,"properties":{"orgId":{"type":"string"},"name":{"type":"string"},"plan":{"type":"string","enum":["free","pro","max","internal"]},"planNote":{"type":"string","nullable":true},"createdAt":{"type":"string","nullable":true},"apps":{"type":"integer"},"members":{"type":"integer"},"usage":{"type":"object","properties":{"aiUsd":{"type":"number"},"aiCalls":{"type":"integer"},"aiInputTokens":{"type":"integer"},"aiOutputTokens":{"type":"integer"},"nativeBuilds":{"type":"integer"},"runnerJobs":{"type":"integer"},"previewHours":{"type":"number"},"socialPosts":{"type":"integer"},"costUsd":{"type":"number"}},"required":["aiUsd","aiCalls","aiInputTokens","aiOutputTokens","nativeBuilds","runnerJobs","previewHours","socialPosts","costUsd"]}},"required":["orgId","name","plan","planNote","createdAt","apps","members","usage"]},"events":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["ai","native_build","runner_job","preview","social_post"]},"appId":{"type":"string","nullable":true},"quantity":{"type":"number"},"costUsd":{"type":"number"},"detail":{"type":"object","additionalProperties":{"nullable":true}},"createdAt":{"type":"string"}},"required":["kind","appId","quantity","costUsd","detail","createdAt"]}}},"required":["org","events"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/admin/orgs/{orgId}/plan":{"put":{"tags":["admin"],"summary":"Put an organization on a plan","description":"Takes effect on the next request. There is no checkout yet; this is how Pro, Max and Internal are given.","parameters":[{"schema":{"type":"string","maxLength":64},"required":true,"name":"orgId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["free","pro","max","internal"]},"note":{"type":"string","maxLength":200}},"required":["plan"]}}}},"responses":{"200":{"description":"The organization's plan now","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["free","pro","max","internal"]},"name":{"type":"string"},"limits":{"type":"object","properties":{"apps":{"type":"integer","nullable":true},"members":{"type":"integer","nullable":true},"aiUsdPerMonth":{"type":"number","nullable":true},"nativeBuildsPerMonth":{"type":"integer","nullable":true},"runnerJobsPerMonth":{"type":"integer","nullable":true},"previewHoursPerMonth":{"type":"number","nullable":true},"socialPostsPerMonth":{"type":"integer","nullable":true}},"required":["apps","members","aiUsdPerMonth","nativeBuildsPerMonth","runnerJobsPerMonth","previewHoursPerMonth","socialPostsPerMonth"]},"month":{"type":"string"},"usage":{"type":"object","properties":{"aiUsd":{"type":"number"},"aiCalls":{"type":"integer"},"aiInputTokens":{"type":"integer"},"aiOutputTokens":{"type":"integer"},"nativeBuilds":{"type":"integer"},"runnerJobs":{"type":"integer"},"previewHours":{"type":"number"},"socialPosts":{"type":"integer"},"costUsd":{"type":"number"}},"required":["aiUsd","aiCalls","aiInputTokens","aiOutputTokens","nativeBuilds","runnerJobs","previewHours","socialPosts","costUsd"]},"apps":{"type":"integer"},"members":{"type":"integer"}},"required":["plan","name","limits","month","usage","apps","members"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/org/creative":{"get":{"tags":["creative"],"responses":{"200":{"description":"Creative result","content":{"application/json":{"schema":{"type":"object","properties":{"connected":{"type":"boolean"},"encryptedConnections":{"type":"boolean"}},"required":["connected","encryptedConnections"]}}}}}},"put":{"tags":["creative"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":10,"maxLength":1000}},"required":["key"]}}}},"responses":{"200":{"description":"Creative result","content":{"application/json":{"schema":{"nullable":true}}}}}},"delete":{"tags":["creative"],"responses":{"200":{"description":"Creative result","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/v1/org/creative/models":{"get":{"tags":["creative"],"responses":{"200":{"description":"Creative result","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/v1/org/creative/models/text":{"get":{"tags":["creative"],"responses":{"200":{"description":"Creative result","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/v1/apps/{id}/creative/generate":{"post":{"tags":["creative"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"model":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"prompt":{"type":"string","minLength":10,"maxLength":3000}},"required":["assetId","model","prompt"]}}}},"responses":{"200":{"description":"Creative result","content":{"application/json":{"schema":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"bytes":{"type":"number"},"source":{"type":"object","nullable":true,"properties":{"kind":{"type":"string","enum":["app-store"]},"appleAppId":{"type":"string"},"country":{"type":"string"},"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"index":{"type":"integer"},"url":{"type":"string","format":"uri"},"importedAt":{"type":"string"}},"required":["kind","appleAppId","country","preset","index","url","importedAt"]},"generation":{"type":"object","nullable":true,"properties":{"model":{"type":"string"},"referenceAssetId":{"type":"string","format":"uuid"},"prompt":{"type":"string"},"cost":{"type":"number","nullable":true},"createdAt":{"type":"string"}},"required":["model","referenceAssetId","prompt","cost","createdAt"]}},"required":["id","name","width","height","bytes"]},"usage":{"nullable":true}},"required":["asset"]}}}}}}},"/v1/apps/{id}/slideshows":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Slideshows, newest first","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/campaigns":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"This app's recurring campaigns","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"},"status":{"type":"string","enum":["draft","active","paused"],"default":"draft"},"lastRunAt":{"type":"string","nullable":true,"format":"date-time"},"nextRunAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","appId","name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId","lastRunAt","nextRunAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["slideshows"],"summary":"Create a recurring campaign — starts in draft, does not run until activated","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":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"}},"required":["name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId"]}}}},"responses":{"200":{"description":"New campaign, status draft","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"},"status":{"type":"string","enum":["draft","active","paused"],"default":"draft"},"lastRunAt":{"type":"string","nullable":true,"format":"date-time"},"nextRunAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","appId","name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId","lastRunAt","nextRunAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/campaigns/{cid}":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"cid","in":"path"}],"responses":{"200":{"description":"One campaign","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"},"status":{"type":"string","enum":["draft","active","paused"],"default":"draft"},"lastRunAt":{"type":"string","nullable":true,"format":"date-time"},"nextRunAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","appId","name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId","lastRunAt","nextRunAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"cid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"}},"required":["name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId"]}}}},"responses":{"200":{"description":"Updated campaign","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"},"status":{"type":"string","enum":["draft","active","paused"],"default":"draft"},"lastRunAt":{"type":"string","nullable":true,"format":"date-time"},"nextRunAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","appId","name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId","lastRunAt","nextRunAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"cid","in":"path"}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}},"required":["removed"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/campaigns/{cid}/activate":{"post":{"tags":["slideshows"],"summary":"Start running this campaign — the next scheduled pass picks it up","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"cid","in":"path"}],"responses":{"200":{"description":"Campaign, status active","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"},"status":{"type":"string","enum":["draft","active","paused"],"default":"draft"},"lastRunAt":{"type":"string","nullable":true,"format":"date-time"},"nextRunAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","appId","name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId","lastRunAt","nextRunAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/campaigns/{cid}/pause":{"post":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"cid","in":"path"}],"responses":{"200":{"description":"Campaign, status paused","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"topic":{"type":"string","minLength":3,"maxLength":300},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1},"intervalHours":{"type":"integer","minimum":1,"maximum":720},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"templateId":{"type":"string","nullable":true,"format":"uuid"},"autoBrief":{"type":"boolean","default":false},"autonomy":{"type":"string","enum":["review","auto"],"default":"review"},"status":{"type":"string","enum":["draft","active","paused"],"default":"draft"},"lastRunAt":{"type":"string","nullable":true,"format":"date-time"},"nextRunAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","appId","name","topic","platforms","intervalHours","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","templateId","lastRunAt","nextRunAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/templates":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"This app's saved templates","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","nullable":true,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","appId","name","description","slideCount","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","textModel","imageModel","createdAt","updatedAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["slideshows"],"summary":"Save a reusable template — direction, visual style and text layout, minus the topic","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":120},"description":{"type":"string","nullable":true,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"}},"required":["name","description","slideCount","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","textModel","imageModel"]}}}},"responses":{"200":{"description":"New template","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","nullable":true,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","appId","name","description","slideCount","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","textModel","imageModel","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/templates/{tid}":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"tid","in":"path"}],"responses":{"200":{"description":"One template","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","nullable":true,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","appId","name","description","slideCount","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","textModel","imageModel","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"tid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","nullable":true,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"}},"required":["name","description","slideCount","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","textModel","imageModel"]}}}},"responses":{"200":{"description":"Updated template","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","nullable":true,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"textModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","nullable":true,"pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","appId","name","description","slideCount","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","textModel","imageModel","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"tid","in":"path"}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}},"required":["removed"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/context":{"get":{"tags":["slideshows"],"summary":"What the AI knows about this app before writing marketing for it (null until saved)","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Saved app context, or null","content":{"application/json":{"schema":{"type":"object","nullable":true,"properties":{"description":{"type":"string","minLength":10,"maxLength":2000},"audience":{"type":"string","nullable":true,"maxLength":500,"default":null},"guardrails":{"type":"string","nullable":true,"maxLength":1000,"default":null},"websiteUrl":{"type":"string","nullable":true,"maxLength":500,"format":"uri","default":null},"appId":{"type":"string"},"updatedAt":{"type":"string"}},"required":["description","appId","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":10,"maxLength":2000},"audience":{"type":"string","nullable":true,"maxLength":500,"default":null},"guardrails":{"type":"string","nullable":true,"maxLength":1000,"default":null},"websiteUrl":{"type":"string","nullable":true,"maxLength":500,"format":"uri","default":null}},"required":["description"]}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":10,"maxLength":2000},"audience":{"type":"string","nullable":true,"maxLength":500,"default":null},"guardrails":{"type":"string","nullable":true,"maxLength":1000,"default":null},"websiteUrl":{"type":"string","nullable":true,"maxLength":500,"format":"uri","default":null},"appId":{"type":"string"},"updatedAt":{"type":"string"}},"required":["description","appId","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/context/draft":{"post":{"tags":["slideshows"],"summary":"Draft the app context from the App Store listing and website — nothing is saved","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"websiteUrl":{"type":"string","maxLength":500,"format":"uri"},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"}},"required":["textModel"]}}}},"responses":{"200":{"description":"A draft for a person to review","content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"audience":{"type":"string","nullable":true},"guardrails":{"type":"string","nullable":true},"websiteUrl":{"type":"string","nullable":true},"sources":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["description","audience","guardrails","websiteUrl","sources","warnings"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/{sid}":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"}],"responses":{"200":{"description":"Full slideshow document","content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["slideshows"],"summary":"Save edits — reorder, caption/overlay text, revision-checked","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides"]}}}},"responses":{"200":{"description":"Saved slideshow with new revision","content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}},"required":["removed"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/{sid}/assets/{aid}":{"get":{"tags":["slideshows"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"aid","in":"path"}],"responses":{"200":{"description":"Slide image, PNG","content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string"},"mimeType":{"type":"string"},"base64":{"type":"string"}},"required":["filename","mimeType","base64"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/auto-brief":{"post":{"tags":["slideshows"],"summary":"Draft a full structured brief with one AI call — topic and every direction field","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","maxLength":300},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"}},"required":["textModel"]}}}},"responses":{"200":{"description":"A drafted brief, not yet saved anywhere","content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","minLength":3,"maxLength":300},"hookDirection":{"type":"string","maxLength":500},"bodyDirection":{"type":"string","maxLength":500},"ctaDirection":{"type":"string","maxLength":500},"visualStyle":{"type":"string","maxLength":500},"textLayout":{"type":"string","maxLength":300},"reasoning":{"type":"string","maxLength":600},"contextSource":{"type":"string","enum":["saved","app_store","name_only"]}},"required":["topic","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","reasoning","contextSource"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/generate":{"post":{"tags":["slideshows"],"summary":"Generate a slideshow plan (hook/body/cta + every slide's prompt) — no images yet","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","minLength":3,"maxLength":300},"slideCount":{"type":"integer","minimum":3,"maximum":10,"default":6},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","maxLength":500},"bodyDirection":{"type":"string","maxLength":500},"ctaDirection":{"type":"string","maxLength":500},"visualStyle":{"type":"string","maxLength":500},"textLayout":{"type":"string","maxLength":300},"steeringInstruction":{"type":"string","maxLength":1000},"templateId":{"type":"string","format":"uuid"}},"required":["topic","textModel","imageModel"]}}}},"responses":{"200":{"description":"New slideshow, status generating","content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/{sid}/slides/{index}/render":{"post":{"tags":["slideshows"],"summary":"Render (or re-render, optionally with an instruction) one slide's image","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":9},"required":false,"name":"index","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"instruction":{"type":"string","minLength":3,"maxLength":500}},"required":["revision"]}}}},"responses":{"200":{"description":"Slideshow with that slide rendered (or its error set)","content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/{sid}/regenerate":{"post":{"tags":["slideshows"],"summary":"Regenerate the whole slideshow from its original topic, optionally with a new steering instruction","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"hookDirection":{"type":"string","maxLength":500},"bodyDirection":{"type":"string","maxLength":500},"ctaDirection":{"type":"string","maxLength":500},"visualStyle":{"type":"string","maxLength":500},"textLayout":{"type":"string","maxLength":300},"steeringInstruction":{"type":"string","maxLength":1000}},"required":["revision"]}}}},"responses":{"200":{"description":"Slideshow reset to a fresh plan, status generating","content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/slideshows/{sid}/publish":{"post":{"tags":["slideshows"],"summary":"Publish a fully-rendered slideshow through upload-post.com","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"sid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok"]},"minItems":1}},"required":["platforms"]}}}},"responses":{"200":{"description":"Published slideshow","content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0},"topic":{"type":"string","minLength":3,"maxLength":300},"hook":{"type":"string"},"body":{"type":"string"},"cta":{"type":"string"},"caption":{"type":"string","maxLength":2200},"textModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"imageModel":{"type":"string","pattern":"^[a-zA-Z0-9_.:/-]{1,150}$"},"hookDirection":{"type":"string","nullable":true,"maxLength":500},"bodyDirection":{"type":"string","nullable":true,"maxLength":500},"ctaDirection":{"type":"string","nullable":true,"maxLength":500},"visualStyle":{"type":"string","nullable":true,"maxLength":500},"textLayout":{"type":"string","nullable":true,"maxLength":300},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","nullable":true,"format":"uuid"},"imagePrompt":{"type":"string","minLength":1,"maxLength":3000},"overlayText":{"type":"string","maxLength":80},"role":{"type":"string","enum":["hook","body","cta"]},"error":{"type":"string","nullable":true}},"required":["assetId","imagePrompt","overlayText","role","error"]},"minItems":3,"maxItems":10},"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"campaignId":{"type":"string","nullable":true,"format":"uuid"},"templateId":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["generating","draft","needs_review","published","failed"]},"publishedPostId":{"type":"string","nullable":true},"publishedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["revision","topic","hook","body","cta","caption","textModel","imageModel","hookDirection","bodyDirection","ctaDirection","visualStyle","textLayout","slides","id","appId","campaignId","templateId","status","publishedPostId","publishedAt","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/marketing/slideshows/run-campaigns":{"post":{"tags":["slideshows"],"summary":"Run every recurring campaign that's due, across every organization","description":"Called by the scheduler. Requires the shared cron secret.","responses":{"200":{"description":"Ran","content":{"application/json":{"schema":{"type":"object","properties":{"claimed":{"type":"number"},"ran":{"type":"number"},"deferred":{"type":"number"},"errors":{"type":"array","items":{"type":"object","properties":{"campaignId":{"type":"string"},"message":{"type":"string"}},"required":["campaignId","message"]}}},"required":["claimed","ran","deferred","errors"]}}}},"404":{"description":"Not available","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apple/request":{"post":{"tags":["apple-management"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PATCH","DELETE"]},"path":{"type":"string","maxLength":1000,"pattern":"^\\/v[12]\\/[A-Za-z0-9_/-]+$"},"query":{"type":"object","additionalProperties":{"type":"string","maxLength":1000},"default":{}},"body":{"type":"object","additionalProperties":{"nullable":true}}},"required":["method","path"]}}}},"responses":{"200":{"description":"Apple response with upstream status and payload","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/v1/apps/{id}/screenshots/publish":{"post":{"tags":["apple-management"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"localizationId":{"type":"string","pattern":"^[A-Za-z0-9-]{1,100}$"},"set":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]}},"required":["preset","locale","revision","slides"]}},"required":["localizationId","set"]}}}},"responses":{"200":{"description":"Apple response with upstream status and payload","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/v1/apps/{id}/store":{"get":{"tags":["store"],"summary":"This app's live App Store Connect listing","description":"Refreshes and reads `store_listing` — a cache with a timestamp, never Apple's truth beyond `syncedAt`. An app with no Apple app record linked gets a clear `unlinked` answer naming the values to type into App Store Connect's New App form, not an error. An organization with no working Apple connection gets 503 `apple_unavailable`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"boolean","nullable":true,"default":false},"required":false,"name":"force","in":"query"}],"responses":{"200":{"description":"The listing","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"linked":{"type":"boolean"},"appleAppId":{"type":"string","nullable":true},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"primaryLocale":{"type":"string","nullable":true},"versions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"versionString":{"type":"string","nullable":true},"platform":{"type":"string","nullable":true},"appVersionState":{"type":"string","nullable":true},"releaseType":{"type":"string","nullable":true},"copyright":{"type":"string","nullable":true},"createdDate":{"type":"string","nullable":true},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string"},"name":{"type":"string","nullable":true},"subtitle":{"type":"string","nullable":true},"privacyPolicyUrl":{"type":"string","nullable":true},"privacyChoicesUrl":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"keywords":{"type":"string","nullable":true},"promotionalText":{"type":"string","nullable":true},"whatsNew":{"type":"string","nullable":true},"supportUrl":{"type":"string","nullable":true},"marketingUrl":{"type":"string","nullable":true}},"required":["locale","name","subtitle","privacyPolicyUrl","privacyChoicesUrl","description","keywords","promotionalText","whatsNew","supportUrl","marketingUrl"]}},"screenshotSets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"displayType":{"type":"string"},"screenshots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"fileName":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"width":{"type":"integer","nullable":true},"height":{"type":"integer","nullable":true},"deliveryState":{"type":"string","nullable":true}},"required":["id","fileName","url","width","height","deliveryState"]}}},"required":["id","displayType","screenshots"]}},"build":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"version":{"type":"string","nullable":true},"uploadedDate":{"type":"string","nullable":true},"processingState":{"type":"string","nullable":true},"usesNonExemptEncryption":{"type":"boolean","nullable":true}},"required":["id","version","uploadedDate","processingState","usesNonExemptEncryption"]},"reviewDetail":{"type":"object","nullable":true,"properties":{"id":{"type":"string","nullable":true},"contactFirstName":{"type":"string","nullable":true},"contactLastName":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"contactEmail":{"type":"string","nullable":true},"demoAccountName":{"type":"string","nullable":true},"demoAccountRequired":{"type":"boolean","nullable":true},"notes":{"type":"string","nullable":true}},"required":["id","contactFirstName","contactLastName","contactPhone","contactEmail","demoAccountName","demoAccountRequired","notes"]}},"required":["id","versionString","platform","appVersionState","releaseType","copyright","createdDate","localizations","screenshotSets","build","reviewDetail"]}},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["iap","subscription"]},"name":{"type":"string","nullable":true},"productId":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"latestVersionState":{"type":"string","nullable":true},"groupId":{"type":"string","nullable":true}},"required":["id","kind","name","productId","type","state","latestVersionState","groupId"]}},"pricing":{"type":"object","nullable":true,"properties":{"baseTerritory":{"type":"string","nullable":true},"manualPriceCount":{"type":"integer","nullable":true}},"required":["baseTerritory","manualPriceCount"]},"availability":{"type":"object","nullable":true,"properties":{"availableInNewTerritories":{"type":"boolean","nullable":true},"territoryCount":{"type":"integer","nullable":true}},"required":["availableInNewTerritories","territoryCount"]},"ageRating":{"type":"object","nullable":true,"properties":{"id":{"type":"string","nullable":true},"ageRatingOverride":{"type":"string","nullable":true},"answers":{"type":"object","additionalProperties":{"nullable":true},"default":{}}},"required":["id","ageRatingOverride"]},"latestSubmission":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"state":{"type":"string"},"submittedDate":{"type":"string","nullable":true}},"required":["id","state","submittedDate"]},"reviews":{"type":"object","nullable":true,"properties":{"averageRating":{"type":"number","nullable":true},"ratingCount":{"type":"integer","nullable":true},"recent":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"rating":{"type":"integer"},"title":{"type":"string","nullable":true},"body":{"type":"string","nullable":true},"reviewerNickname":{"type":"string","nullable":true},"createdDate":{"type":"string","nullable":true},"territory":{"type":"string","nullable":true},"hasResponse":{"type":"boolean"}},"required":["id","rating","title","body","reviewerNickname","createdDate","territory","hasResponse"]}}},"required":["averageRating","ratingCount","recent"]},"syncedAt":{"type":"string","nullable":true},"lastError":{"type":"string","nullable":true},"newAppFormValues":{"type":"object","nullable":true,"properties":{"platform":{"type":"string","enum":["iOS"]},"name":{"type":"string"},"primaryLanguage":{"type":"string"}},"required":["platform","name","primaryLanguage"]},"uiOnlyTasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"why":{"type":"string"},"link":{"type":"string"}},"required":["id","title","why","link"]}}},"required":["appId","linked","appleAppId","state","primaryLocale","versions","products","pricing","availability","ageRating","latestSubmission","reviews","syncedAt","lastError","newAppFormValues","uiOnlyTasks"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/checks":{"get":{"tags":["store"],"summary":"Playbook rules backed by App Store Connect data — and the confirm token","description":"Every `submission`-set rule with a `store-*` check, evaluated against the current snapshot. With no snapshot yet — unlinked, or never synced — every rule reports `manual`, the same honest answer a QA-backed rule gives with no report.\n\n**This is the only thing that mints a confirm token.** When every required rule passes, `confirm` carries an HMAC bound to `(this app, this operation, a digest of exactly these verdicts, now)`, valid thirty minutes and usable once. The four irreversible operations — submit, release, pricing, availability — take it, and `?operation=` says which one to mint for. An agent must never mint, guess or reuse one: it shows the founder this output, and only the founder's own reply carries the token back.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["submit","release","pricing","availability","product_pricing","product_availability"],"default":"submit"},"required":false,"name":"operation","in":"query"}],"responses":{"200":{"description":"The store-backed rules, and a confirm token when they are clean","content":{"application/json":{"schema":{"type":"object","properties":{"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"must":{"type":"string"},"why":{"type":"string"},"status":{"type":"string","enum":["pass","fail","manual","skip"]},"auto":{"type":"string","enum":["pass","fail","manual","skip"]},"detail":{"type":"string"},"required":{"type":"boolean"},"checkedBy":{"type":"string","enum":["human","ai"]},"checkedAt":{"type":"string"},"note":{"type":"string"},"stale":{"type":"boolean"}},"required":["id","title","must","why","status","required"]}},"ready":{"type":"boolean"},"checksDigest":{"type":"string"},"operation":{"type":"string","enum":["submit","release","pricing","availability","product_pricing","product_availability"]},"confirm":{"type":"string","nullable":true},"confirmExpiresAt":{"type":"string","nullable":true},"nextEditablePath":{"type":"string"}},"required":["state","rules","ready","checksDigest","operation","confirm","confirmExpiresAt","nextEditablePath"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/draft":{"get":{"tags":["store"],"summary":"The intended listing — Broctic's own record, never Apple's","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The draft","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"draft":{"type":"object","properties":{"copyright":{"type":"string","maxLength":200},"ageRatingAnswers":{"type":"object","additionalProperties":{"nullable":true},"default":{}},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":1,"maxLength":20},"name":{"type":"string","maxLength":30},"subtitle":{"type":"string","maxLength":30},"privacyPolicyUrl":{"type":"string","maxLength":500},"description":{"type":"string","maxLength":4000},"keywords":{"type":"string","maxLength":200},"promotionalText":{"type":"string","maxLength":170},"whatsNew":{"type":"string","maxLength":4000},"supportUrl":{"type":"string","maxLength":500},"marketingUrl":{"type":"string","maxLength":500}},"required":["locale"]},"maxItems":60,"default":[]},"categories":{"type":"object","properties":{"primaryCategory":{"type":"string"},"primarySubcategoryOne":{"type":"string"},"primarySubcategoryTwo":{"type":"string"},"secondaryCategory":{"type":"string"},"secondarySubcategoryOne":{"type":"string"},"secondarySubcategoryTwo":{"type":"string"}},"default":{}},"reviewDetails":{"type":"object","properties":{"contactFirstName":{"type":"string","maxLength":100},"contactLastName":{"type":"string","maxLength":100},"contactPhone":{"type":"string","maxLength":50},"contactEmail":{"type":"string","maxLength":200},"demoAccountName":{"type":"string","maxLength":200},"demoAccountRequired":{"type":"boolean"},"notes":{"type":"string","maxLength":4000}},"default":{}},"products":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"kind":{"type":"string","enum":["iap","subscription"]},"name":{"type":"string","minLength":1,"maxLength":64},"reviewNote":{"type":"string","maxLength":4000},"type":{"type":"string","enum":["CONSUMABLE","NON_CONSUMABLE","NON_RENEWING_SUBSCRIPTION"]},"familySharable":{"type":"boolean"},"subscriptionPeriod":{"type":"string","enum":["ONE_WEEK","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"groupReferenceName":{"type":"string","minLength":1,"maxLength":64},"groupLevel":{"type":"integer","minimum":1,"maximum":20},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":1,"maxLength":30},"description":{"type":"string","maxLength":45}},"required":["locale","name"]},"maxItems":60,"default":[]},"pricePointId":{"type":"string","maxLength":200},"customerPrice":{"type":"string","maxLength":30},"baseTerritory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"preserveCurrentPrice":{"type":"boolean"},"territories":{"type":"array","items":{"type":"string","minLength":2,"maxLength":10},"maxItems":250},"availableInNewTerritories":{"type":"boolean"},"introductoryOffer":{"type":"object","properties":{"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["duration","offerMode"]},"promotionalOffers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"offerCode":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["name","offerCode","duration","offerMode"]},"maxItems":10,"default":[]}},"required":["productId","kind","name"]},"maxItems":200,"default":[]}}},"demoAccountPasswordSet":{"type":"boolean"},"updatedAt":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["appId","draft","demoAccountPasswordSet","updatedAt","updatedBy"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["store"],"summary":"Edit the intended listing","description":"A partial merge, not a replace — omitted fields keep their previous value. Nothing here is pushed to Apple; that is a later step. `integration: manage` because this is the same act as configuring what the org's Apple connection will eventually publish.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"copyright":{"type":"string","maxLength":200},"ageRatingAnswers":{"type":"object","additionalProperties":{"nullable":true}},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":1,"maxLength":20},"name":{"type":"string","maxLength":30},"subtitle":{"type":"string","maxLength":30},"privacyPolicyUrl":{"type":"string","maxLength":500},"description":{"type":"string","maxLength":4000},"keywords":{"type":"string","maxLength":200},"promotionalText":{"type":"string","maxLength":170},"whatsNew":{"type":"string","maxLength":4000},"supportUrl":{"type":"string","maxLength":500},"marketingUrl":{"type":"string","maxLength":500}},"required":["locale"]},"maxItems":60},"categories":{"type":"object","properties":{"primaryCategory":{"type":"string"},"primarySubcategoryOne":{"type":"string"},"primarySubcategoryTwo":{"type":"string"},"secondaryCategory":{"type":"string"},"secondarySubcategoryOne":{"type":"string"},"secondarySubcategoryTwo":{"type":"string"}}},"reviewDetails":{"type":"object","properties":{"contactFirstName":{"type":"string","maxLength":100},"contactLastName":{"type":"string","maxLength":100},"contactPhone":{"type":"string","maxLength":50},"contactEmail":{"type":"string","maxLength":200},"demoAccountName":{"type":"string","maxLength":200},"demoAccountRequired":{"type":"boolean"},"notes":{"type":"string","maxLength":4000},"demoAccountPassword":{"type":"string","maxLength":200}}},"products":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"kind":{"type":"string","enum":["iap","subscription"]},"name":{"type":"string","minLength":1,"maxLength":64},"reviewNote":{"type":"string","maxLength":4000},"type":{"type":"string","enum":["CONSUMABLE","NON_CONSUMABLE","NON_RENEWING_SUBSCRIPTION"]},"familySharable":{"type":"boolean"},"subscriptionPeriod":{"type":"string","enum":["ONE_WEEK","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"groupReferenceName":{"type":"string","minLength":1,"maxLength":64},"groupLevel":{"type":"integer","minimum":1,"maximum":20},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":1,"maxLength":30},"description":{"type":"string","maxLength":45}},"required":["locale","name"]},"maxItems":60,"default":[]},"pricePointId":{"type":"string","maxLength":200},"customerPrice":{"type":"string","maxLength":30},"baseTerritory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"preserveCurrentPrice":{"type":"boolean"},"territories":{"type":"array","items":{"type":"string","minLength":2,"maxLength":10},"maxItems":250},"availableInNewTerritories":{"type":"boolean"},"introductoryOffer":{"type":"object","properties":{"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["duration","offerMode"]},"promotionalOffers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"offerCode":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["name","offerCode","duration","offerMode"]},"maxItems":10,"default":[]}},"required":["productId","kind","name"]},"maxItems":200}}}}}},"responses":{"200":{"description":"The merged draft","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"draft":{"type":"object","properties":{"copyright":{"type":"string","maxLength":200},"ageRatingAnswers":{"type":"object","additionalProperties":{"nullable":true},"default":{}},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":1,"maxLength":20},"name":{"type":"string","maxLength":30},"subtitle":{"type":"string","maxLength":30},"privacyPolicyUrl":{"type":"string","maxLength":500},"description":{"type":"string","maxLength":4000},"keywords":{"type":"string","maxLength":200},"promotionalText":{"type":"string","maxLength":170},"whatsNew":{"type":"string","maxLength":4000},"supportUrl":{"type":"string","maxLength":500},"marketingUrl":{"type":"string","maxLength":500}},"required":["locale"]},"maxItems":60,"default":[]},"categories":{"type":"object","properties":{"primaryCategory":{"type":"string"},"primarySubcategoryOne":{"type":"string"},"primarySubcategoryTwo":{"type":"string"},"secondaryCategory":{"type":"string"},"secondarySubcategoryOne":{"type":"string"},"secondarySubcategoryTwo":{"type":"string"}},"default":{}},"reviewDetails":{"type":"object","properties":{"contactFirstName":{"type":"string","maxLength":100},"contactLastName":{"type":"string","maxLength":100},"contactPhone":{"type":"string","maxLength":50},"contactEmail":{"type":"string","maxLength":200},"demoAccountName":{"type":"string","maxLength":200},"demoAccountRequired":{"type":"boolean"},"notes":{"type":"string","maxLength":4000}},"default":{}},"products":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"kind":{"type":"string","enum":["iap","subscription"]},"name":{"type":"string","minLength":1,"maxLength":64},"reviewNote":{"type":"string","maxLength":4000},"type":{"type":"string","enum":["CONSUMABLE","NON_CONSUMABLE","NON_RENEWING_SUBSCRIPTION"]},"familySharable":{"type":"boolean"},"subscriptionPeriod":{"type":"string","enum":["ONE_WEEK","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"groupReferenceName":{"type":"string","minLength":1,"maxLength":64},"groupLevel":{"type":"integer","minimum":1,"maximum":20},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":1,"maxLength":30},"description":{"type":"string","maxLength":45}},"required":["locale","name"]},"maxItems":60,"default":[]},"pricePointId":{"type":"string","maxLength":200},"customerPrice":{"type":"string","maxLength":30},"baseTerritory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"preserveCurrentPrice":{"type":"boolean"},"territories":{"type":"array","items":{"type":"string","minLength":2,"maxLength":10},"maxItems":250},"availableInNewTerritories":{"type":"boolean"},"introductoryOffer":{"type":"object","properties":{"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["duration","offerMode"]},"promotionalOffers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"offerCode":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["name","offerCode","duration","offerMode"]},"maxItems":10,"default":[]}},"required":["productId","kind","name"]},"maxItems":200,"default":[]}}},"demoAccountPasswordSet":{"type":"boolean"},"updatedAt":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["appId","draft","demoAccountPasswordSet","updatedAt","updatedBy"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/reviews":{"get":{"tags":["store"],"summary":"Recent customer reviews, read live","description":"Read directly from Apple rather than the cached snapshot — one cheap call, and reviews move independently of the listing's own state.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Reviews","content":{"application/json":{"schema":{"type":"object","properties":{"averageRating":{"type":"number","nullable":true},"ratingCount":{"type":"integer","nullable":true},"recent":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"rating":{"type":"integer"},"title":{"type":"string","nullable":true},"body":{"type":"string","nullable":true},"reviewerNickname":{"type":"string","nullable":true},"createdDate":{"type":"string","nullable":true},"territory":{"type":"string","nullable":true},"hasResponse":{"type":"boolean"}},"required":["id","rating","title","body","reviewerNickname","createdDate","territory","hasResponse"]}}},"required":["averageRating","ratingCount","recent"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/products/price-points":{"get":{"tags":["store"],"summary":"The prices Apple will accept for a product, in one territory","description":"Apple removed `appPriceTiers` and publishes no account-wide list: price points are scoped to a **specific product**, and a subscription cannot be priced from an in-app-purchase point. With no `productId` this uses the first product of `type` on the app and says which in `resolvedFromProductId`, rather than returning an empty list that would read as \"Apple sells nothing here\". An app with no product of that kind yet gets a 409 naming the reason — create the product first, because which prices exist depends on which product it is.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"required":false,"name":"territory","in":"query"},{"schema":{"type":"string","enum":["iap","subscription"],"default":"subscription"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"productId","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Price points","content":{"application/json":{"schema":{"type":"object","properties":{"territory":{"type":"string"},"productType":{"type":"string","enum":["iap","subscription"]},"resolvedFromProductId":{"type":"string","nullable":true},"pricePoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"customerPrice":{"type":"string","nullable":true},"proceeds":{"type":"string","nullable":true},"proceedsYear2":{"type":"string","nullable":true},"territory":{"type":"string","nullable":true}},"required":["id","customerPrice","proceeds","proceedsYear2","territory"]}}},"required":["territory","productType","resolvedFromProductId","pricePoints"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/products/check":{"get":{"tags":["store"],"summary":"Where the three places a product id is written disagree","description":"`lib/offers.ts` and App Store Connect, compared. `kind` names the side an id is **missing from**, because that is the sentence to act on: `missing_in_asc` means create it, `extra_in_asc` means Apple holds something the code never asks for — fine for a retired product, and also exactly what a mistyped id looks like. A mismatch is invisible until a real customer taps Buy and the store returns nothing.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The comparison","content":{"application/json":{"schema":{"type":"object","properties":{"offerProductIds":{"type":"array","items":{"type":"string"},"default":[]},"draftProductIds":{"type":"array","items":{"type":"string"},"default":[]},"liveProductIds":{"type":"array","items":{"type":"string"},"default":[]},"mismatches":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["missing_in_asc","extra_in_asc","missing_in_offers"]},"productId":{"type":"string"},"hint":{"type":"string"}},"required":["kind","productId","hint"]},"default":[]},"matches":{"type":"boolean"},"sourceFile":{"type":"string","enum":["lib/offers.ts"]}},"required":["matches","sourceFile"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/products/review-screenshot":{"post":{"tags":["store"],"summary":"Render one slide and attach it to a product as its review screenshot","description":"Apple requires a review screenshot on every product before it can be reviewed at all, and the rejection names the product rather than the missing image. The bytes are rendered here from the set and slide named in the body — the JSON body cap is 64KB and a PNG is not, so an upload route taking base64 would be a route that never worked. `deliveryState` is Apple's own: only `COMPLETE` means it is really attached.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"set":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]}},"required":["preset","locale","revision","slides"]},"slideIndex":{"type":"integer","minimum":0,"maximum":19,"default":0}},"required":["productId","set"]}}}},"responses":{"200":{"description":"Uploaded","content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string"},"assetId":{"type":"string"},"deliveryState":{"type":"string","nullable":true}},"required":["productId","assetId","deliveryState"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/products":{"get":{"tags":["store"],"summary":"Apple's catalogue, the draft, and where they disagree","description":"The three questions are never asked apart, so they are one answer. `live` is what Apple holds right now, each product with the newest **version**'s id and state — since 4.4.1 that is where submission lives, and a product with no version at all cannot be added to a review submission. `draft` is Broctic's intended catalogue; `suggested` is the one derived from `lib/offers.ts`, offered only when the draft is empty so a founder never types the ids twice — nothing is ever pushed from it without being saved into the draft first. `firstProductNeedsBrowser` is read from Apple's own product states, never from Broctic's bookkeeping.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The catalogue","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"linked":{"type":"boolean"},"live":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["iap","subscription"]},"productId":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"versionId":{"type":"string","nullable":true},"versionState":{"type":"string","nullable":true},"locales":{"type":"array","items":{"type":"string"},"default":[]},"priced":{"type":"boolean"},"hasReviewScreenshot":{"type":"boolean"},"availableTerritoryCount":{"type":"integer","nullable":true},"groupId":{"type":"string","nullable":true},"groupLevel":{"type":"integer","nullable":true,"default":null}},"required":["id","kind","productId","name","type","state","versionId","versionState","priced","hasReviewScreenshot","availableTerritoryCount","groupId"]},"default":[]},"liveGroups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"referenceName":{"type":"string","nullable":true},"versionId":{"type":"string","nullable":true},"versionState":{"type":"string","nullable":true},"locales":{"type":"array","items":{"type":"string"},"default":[]},"subscriptionIds":{"type":"array","items":{"type":"string"},"default":[]}},"required":["id","referenceName","versionId","versionState"]},"default":[]},"draft":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"kind":{"type":"string","enum":["iap","subscription"]},"name":{"type":"string","minLength":1,"maxLength":64},"reviewNote":{"type":"string","maxLength":4000},"type":{"type":"string","enum":["CONSUMABLE","NON_CONSUMABLE","NON_RENEWING_SUBSCRIPTION"]},"familySharable":{"type":"boolean"},"subscriptionPeriod":{"type":"string","enum":["ONE_WEEK","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"groupReferenceName":{"type":"string","minLength":1,"maxLength":64},"groupLevel":{"type":"integer","minimum":1,"maximum":20},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":1,"maxLength":30},"description":{"type":"string","maxLength":45}},"required":["locale","name"]},"maxItems":60,"default":[]},"pricePointId":{"type":"string","maxLength":200},"customerPrice":{"type":"string","maxLength":30},"baseTerritory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"preserveCurrentPrice":{"type":"boolean"},"territories":{"type":"array","items":{"type":"string","minLength":2,"maxLength":10},"maxItems":250},"availableInNewTerritories":{"type":"boolean"},"introductoryOffer":{"type":"object","properties":{"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["duration","offerMode"]},"promotionalOffers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"offerCode":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["name","offerCode","duration","offerMode"]},"maxItems":10,"default":[]}},"required":["productId","kind","name"]},"default":[]},"suggested":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"kind":{"type":"string","enum":["iap","subscription"]},"name":{"type":"string","minLength":1,"maxLength":64},"reviewNote":{"type":"string","maxLength":4000},"type":{"type":"string","enum":["CONSUMABLE","NON_CONSUMABLE","NON_RENEWING_SUBSCRIPTION"]},"familySharable":{"type":"boolean"},"subscriptionPeriod":{"type":"string","enum":["ONE_WEEK","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"groupReferenceName":{"type":"string","minLength":1,"maxLength":64},"groupLevel":{"type":"integer","minimum":1,"maximum":20},"localizations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string","minLength":2,"maxLength":20},"name":{"type":"string","minLength":1,"maxLength":30},"description":{"type":"string","maxLength":45}},"required":["locale","name"]},"maxItems":60,"default":[]},"pricePointId":{"type":"string","maxLength":200},"customerPrice":{"type":"string","maxLength":30},"baseTerritory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"preserveCurrentPrice":{"type":"boolean"},"territories":{"type":"array","items":{"type":"string","minLength":2,"maxLength":10},"maxItems":250},"availableInNewTerritories":{"type":"boolean"},"introductoryOffer":{"type":"object","properties":{"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["duration","offerMode"]},"promotionalOffers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"offerCode":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"duration":{"type":"string","enum":["THREE_DAYS","ONE_WEEK","TWO_WEEKS","ONE_MONTH","TWO_MONTHS","THREE_MONTHS","SIX_MONTHS","ONE_YEAR"]},"numberOfPeriods":{"type":"integer","minimum":1,"maximum":12,"default":1},"offerMode":{"type":"string","enum":["PAY_AS_YOU_GO","PAY_UP_FRONT","FREE_TRIAL"]},"customerPrice":{"type":"string","maxLength":30},"pricePointId":{"type":"string","maxLength":200},"territory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"}},"required":["name","offerCode","duration","offerMode"]},"maxItems":10,"default":[]}},"required":["productId","kind","name"]},"default":[]},"check":{"type":"object","properties":{"offerProductIds":{"type":"array","items":{"type":"string"},"default":[]},"draftProductIds":{"type":"array","items":{"type":"string"},"default":[]},"liveProductIds":{"type":"array","items":{"type":"string"},"default":[]},"mismatches":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["missing_in_asc","extra_in_asc","missing_in_offers"]},"productId":{"type":"string"},"hint":{"type":"string"}},"required":["kind","productId","hint"]},"default":[]},"matches":{"type":"boolean"},"sourceFile":{"type":"string","enum":["lib/offers.ts"]}},"required":["matches","sourceFile"]},"firstProductNeedsBrowser":{"type":"boolean"},"syncedAt":{"type":"string","nullable":true}},"required":["appId","linked","check","firstProductNeedsBrowser","syncedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["store"],"summary":"Push the draft catalogue to App Store Connect","description":"Create-or-update and idempotent by `productId`: a product Apple already holds is updated rather than duplicated, and a second push with no changes reports `unchanged`. That matters more here than anywhere else in the module — a product id can never be reused once submitted, so a caller that retried its way into a typo has burned that string permanently.\n\nPer-product results rather than one verdict: a catalogue where two plans wrote and one failed on a bad price point is the ordinary outcome, and a single `failed` would hide the two that worked. `targets` lists every Apple resource that product's push touched, in order.\n\n`includePricing`, `includeAvailability` and `includeOffers` are **off by default**, and the first two additionally require a **confirm token** — the same mechanism `PUT …/store/pricing` and `PUT …/store/availability` use, because they are the same two irreversible acts on a smaller resource. Apple will not revert a price increase once it is in effect, and a territory left out of an availability list stops being on sale there immediately. Mint the token with `GET …/store/checks?operation=product_pricing` (or `product_availability`); its digest covers the draft's own prices and territories, so a token minted against one catalogue cannot be spent on another, and a catalogue edited in between answers `store_confirm_stale` — which means look again, not retry. One token authorises one operation, so pricing and availability are two calls.\n\nPrices are always price point ids resolved against Apple's own list for that product and territory — a `customerPrice` Apple does not sell is refused with the prices it does.\n\n**Versions are not churned.** A product's copy lives on a version, and a version is read-only once created, so writing copy means creating another one — which *replaces* the last. When Apple's newest version already says what the draft says, nothing is written and the product reports `unchanged`. When it differs and that version is `READY_FOR_REVIEW`, `WAITING_FOR_REVIEW`, `IN_REVIEW` or `APPROVED`, the product is refused rather than superseded: the replacement would drop it out of the next submission with no error anywhere. Name its id in `newVersionFor` to mean it on purpose.\n\nReview screenshots are their own call (`POST …/store/products/review-screenshot`), because their bytes do not fit in a JSON body.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productIds":{"type":"array","items":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"maxItems":200},"createMissing":{"type":"boolean","default":true},"includePricing":{"type":"boolean","default":false},"includeAvailability":{"type":"boolean","default":false},"includeOffers":{"type":"boolean","default":false},"confirm":{"type":"string","minLength":24,"maxLength":2000,"description":"The confirm token from GET …/store/checks. Minted only when every required store-* rule passes, valid 30 minutes, single-use. An agent must never mint, guess or reuse one: it comes from the founder's own reply."},"newVersionFor":{"type":"array","items":{"type":"string","minLength":3,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$"},"maxItems":200,"default":[]}}}}}},"responses":{"200":{"description":"Per-product results","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string","enum":["push_products"]},"results":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string"},"kind":{"type":"string","enum":["iap","subscription"]},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"targets":{"type":"array","items":{"type":"string"},"default":[]},"detail":{"type":"string","nullable":true}},"required":["productId","kind","action","detail"]},"default":[]},"warnings":{"type":"array","items":{"type":"string"},"default":[]},"firstProductNeedsBrowser":{"type":"boolean"}},"required":["operation","firstProductNeedsBrowser"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/version":{"post":{"tags":["store"],"summary":"Create (or reuse) the editable App Store version","description":"Creates `appStoreVersions`. An editable version that already exists is **reused**, not duplicated — Apple keeps at most one per platform and asking for a second answers with a `STATE_ERROR` that reads like a caller bug. `releaseType` defaults to `MANUAL` so the founder picks the moment the app goes live.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"versionString":{"type":"string","minLength":1,"maxLength":20,"pattern":"^\\d+(\\.\\d+){0,2}$"},"releaseType":{"type":"string","enum":["MANUAL","AFTER_APPROVAL","SCHEDULED"],"default":"MANUAL"},"platform":{"type":"string","enum":["IOS","MAC_OS","TV_OS","VISION_OS"],"default":"IOS"},"copyright":{"type":"string","maxLength":200},"earliestReleaseDate":{"type":"string","maxLength":40}},"required":["versionString"]}}}},"responses":{"200":{"description":"What was created or reused","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/metadata":{"put":{"tags":["store"],"summary":"Push the draft to App Store Connect","description":"Writes `appInfoLocalizations` (name, subtitle, privacy policy) and `appStoreVersionLocalizations` (description, keywords, promotional text, what's new, support and marketing URLs) **for the same locale set on both sides** — Apple refuses a submission whose two sets differ, with an error naming neither. Field limits are checked against Apple's documented numbers before the first call, so a push either applies or does not: keywords and review notes are counted in bytes. What's-new is dropped on a first version, which Apple does not accept it on.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"locales":{"type":"array","items":{"type":"string","minLength":2,"maxLength":20},"maxItems":60},"createMissing":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Per-locale, per-side results","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/categories":{"put":{"tags":["store"],"summary":"Set primary and secondary categories","description":"Relationships on `appInfos` — that resource has no patchable attributes at all. A field set to `null` clears it; a field omitted is left alone. Category ids come from `GET /v1/appCategories`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"primaryCategory":{"type":"string","nullable":true,"maxLength":100},"primarySubcategoryOne":{"type":"string","nullable":true,"maxLength":100},"primarySubcategoryTwo":{"type":"string","nullable":true,"maxLength":100},"secondaryCategory":{"type":"string","nullable":true,"maxLength":100},"secondarySubcategoryOne":{"type":"string","nullable":true,"maxLength":100},"secondarySubcategoryTwo":{"type":"string","nullable":true,"maxLength":100}}}}}},"responses":{"200":{"description":"Which relationships moved","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/age-rating":{"put":{"tags":["store"],"summary":"Answer the age rating questionnaire","description":"`ageRatingDeclarations`, on the 2025–26 attribute set: frequencies are `NONE | INFREQUENT | FREQUENT` (the `INFREQUENT_OR_MILD` scale was deprecated in 4.1 and is not accepted here), the override is `ageRatingOverrideV2` (`SEVENTEEN_PLUS` became `EIGHTEEN_PLUS`), and `gamblingAndContests`/`seventeenPlus` were removed in 4.0. Send only what is changing — Apple's own instruction for this endpoint.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"violenceCartoonOrFantasy":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"violenceRealistic":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"violenceRealisticProlongedGraphicOrSadistic":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"sexualContentOrNudity":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"sexualContentGraphicAndNudity":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"profanityOrCrudeHumor":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"alcoholTobaccoOrDrugUseOrReferences":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"matureOrSuggestiveThemes":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"horrorOrFearThemes":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"medicalOrTreatmentInformation":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"gamblingSimulated":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"contests":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"gunsOrOtherWeapons":{"type":"string","enum":["NONE","INFREQUENT","FREQUENT"]},"advertising":{"type":"boolean"},"gambling":{"type":"boolean"},"lootBox":{"type":"boolean"},"messagingAndChat":{"type":"boolean"},"parentalControls":{"type":"boolean"},"socialMedia":{"type":"boolean"},"socialMediaAgeRestricted":{"type":"boolean"},"unrestrictedWebAccess":{"type":"boolean"},"userGeneratedContent":{"type":"boolean"},"healthOrWellnessTopics":{"type":"boolean"},"ageAssurance":{"type":"boolean"},"ageRatingOverrideV2":{"type":"string","enum":["NONE","NINE_PLUS","THIRTEEN_PLUS","SIXTEEN_PLUS","EIGHTEEN_PLUS","UNRATED"]},"koreaAgeRatingOverride":{"type":"string","enum":["NONE","FIFTEEN_PLUS","NINETEEN_PLUS"]},"kidsAgeBand":{"type":"string","nullable":true,"enum":["FIVE_AND_UNDER","SIX_TO_EIGHT","NINE_TO_ELEVEN"]},"developerAgeRatingInfoUrl":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Which answers were written","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/review-details":{"put":{"tags":["store"],"summary":"Contact, demo account and notes for the reviewer","description":"`appStoreReviewDetails`. `demoAccountRequired: true` with no username and password is refused here rather than at review: a reviewer who cannot get past the login screen rejects the whole submission. Notes are limited to 4000 **bytes**.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contactFirstName":{"type":"string","maxLength":100},"contactLastName":{"type":"string","maxLength":100},"contactPhone":{"type":"string","maxLength":50},"contactEmail":{"type":"string","maxLength":200},"demoAccountName":{"type":"string","maxLength":200},"demoAccountRequired":{"type":"boolean"},"notes":{"type":"string","maxLength":4000}}}}}},"responses":{"200":{"description":"Created or updated","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/screenshots/publish":{"post":{"tags":["store"],"summary":"Render and publish a screenshot set, polling until Apple finishes","description":"Reads the display type's existing screenshots **first** and refuses to touch a non-empty set unless `replace: true` — an imported app usually has artwork a founder paid for. Then reserves, uploads in chunks and commits through the hardened `apple-management` path, and polls `assetDeliveryState` until every screenshot is `COMPLETE`. `UPLOAD_COMPLETE` is not done, and `pending: true` means the poll ran out, not that the set is ready.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"localizationId":{"type":"string","pattern":"^[A-Za-z0-9-]{1,100}$"},"set":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]}},"required":["preset","locale","revision","slides"]},"replace":{"type":"boolean","default":false},"waitForComplete":{"type":"boolean","default":true}},"required":["localizationId","set"]}}}},"responses":{"200":{"description":"Delivery states","content":{"application/json":{"schema":{"type":"object","properties":{"setId":{"type":"string"},"displayType":{"type":"string"},"uploaded":{"type":"integer"},"deleted":{"type":"integer"},"deliveryStates":{"type":"array","items":{"type":"string"}},"pending":{"type":"boolean"}},"required":["setId","displayType","uploaded","deleted","deliveryStates","pending"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/builds":{"get":{"tags":["store"],"summary":"Builds Apple has processed, newest first","description":"`processingState` is `PROCESSING | FAILED | INVALID | VALID`; only a `VALID` build can be attached. `attached` marks the one already on the current version.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Builds","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"type":"string","nullable":true},"uploadedDate":{"type":"string","nullable":true},"processingState":{"type":"string","nullable":true},"usesNonExemptEncryption":{"type":"boolean","nullable":true},"expired":{"type":"boolean","nullable":true},"attached":{"type":"boolean"}},"required":["id","version","uploadedDate","processingState","usesNonExemptEncryption","expired","attached"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/build/attach":{"post":{"tags":["store"],"summary":"Attach a VALID build and answer export compliance","description":"Both in one call, because they are one act: a build attached without `usesNonExemptEncryption` stalls the submission on a manual question and looks, from the console, like nothing happening at all.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"buildId":{"type":"string","minLength":1,"maxLength":100},"usesNonExemptEncryption":{"type":"boolean"}},"required":["buildId"]}}}},"responses":{"200":{"description":"What was attached","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/build/upload":{"post":{"tags":["store"],"summary":"Upload an .ipa through buildUploads (flagged off)","description":"Apple's 4.1 `buildUploads` → `buildUploadFiles` → commit flow, which would replace the `eas submit` iOS leg. **Not enabled**: it is the step that most often fails opaquely, and shipping it without a real .ipa to prove it against would be a guess. Set `STORE_BUILD_UPLOAD_ENABLED=true` to turn it on once there is one; until then this answers 501 rather than pretending. The request shapes are written against the spec in `asc-writes.ts`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ipaUrl":{"type":"string","maxLength":2000,"format":"uri"},"cfBundleVersion":{"type":"string","minLength":1,"maxLength":50},"cfBundleShortVersionString":{"type":"string","minLength":1,"maxLength":50},"platform":{"type":"string","enum":["IOS","MAC_OS","TV_OS","VISION_OS"],"default":"IOS"}},"required":["ipaUrl","cfBundleVersion","cfBundleShortVersionString"]}}}},"responses":{"200":{"description":"Uploaded","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"501":{"description":"Not enabled in this environment","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/submit":{"post":{"tags":["store"],"summary":"Submit this version for review (confirm token required)","description":"`reviewSubmissions` → `reviewSubmissionItems` (the version, plus every product version that is `READY_FOR_REVIEW`) → `{submitted: true}`. Takes a confirm token from `GET …/store/checks`: minted only when every required rule passes, valid thirty minutes, usable once, bound to the state the checks saw. **If the app has never shipped a paid product and the draft defines one, this refuses with `store_first_iap_browser`** — Apple does not accept that submission through the API at all. A submission that cannot be completed is cancelled rather than left open, because an open one blocks the next.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"string","minLength":24,"maxLength":2000,"description":"The confirm token from GET …/store/checks. Minted only when every required store-* rule passes, valid 30 minutes, single-use. An agent must never mint, guess or reuse one: it comes from the founder's own reply."},"versionOnly":{"type":"boolean","default":false}},"required":["confirm"]}}}},"responses":{"200":{"description":"What Apple accepted","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/release":{"post":{"tags":["store"],"summary":"Release an approved version (confirm token required)","description":"`appStoreVersionReleaseRequests`. Apple: \"You can't cancel this request.\"","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"string","minLength":24,"maxLength":2000,"description":"The confirm token from GET …/store/checks. Minted only when every required store-* rule passes, valid 30 minutes, single-use. An agent must never mint, guess or reuse one: it comes from the founder's own reply."}},"required":["confirm"]}}}},"responses":{"200":{"description":"Released","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/pricing":{"put":{"tags":["store"],"summary":"Set the price (confirm token required)","description":"`appPriceSchedules` — a schedule **replaces the whole plan**. The price is a price point id, never a number: Apple's price points are the only legal prices. Apple: \"once a price increase goes into effect, your change can't be reverted.\"","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"string","minLength":24,"maxLength":2000,"description":"The confirm token from GET …/store/checks. Minted only when every required store-* rule passes, valid 30 minutes, single-use. An agent must never mint, guess or reuse one: it comes from the founder's own reply."},"pricePointId":{"type":"string","minLength":1,"maxLength":200},"tier":{"type":"string","minLength":1,"maxLength":50},"baseTerritory":{"type":"string","minLength":2,"maxLength":10,"default":"USA"},"startDate":{"type":"string","maxLength":40}},"required":["confirm"]}}}},"responses":{"200":{"description":"Scheduled","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/availability":{"put":{"tags":["store"],"summary":"Set territory availability (confirm token required)","description":"`POST /v2/appAvailabilities`. Every territory **not** in the list stops being on sale, immediately — which is why this is one of the four.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"string","minLength":24,"maxLength":2000,"description":"The confirm token from GET …/store/checks. Minted only when every required store-* rule passes, valid 30 minutes, single-use. An agent must never mint, guess or reuse one: it comes from the founder's own reply."},"territories":{"type":"array","items":{"type":"string","minLength":2,"maxLength":10},"minItems":1,"maxItems":250},"availableInNewTerritories":{"type":"boolean","default":true}},"required":["confirm","territories"]}}}},"responses":{"200":{"description":"Applied","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/submissions":{"get":{"tags":["store"],"summary":"Every submission Broctic has made for this app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"History","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"state":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"}},"required":["type","id"]},"default":[]},"submittedAt":{"type":"string","nullable":true},"resolvedAt":{"type":"string","nullable":true},"outcome":{"type":"string","nullable":true},"createdAt":{"type":"string"}},"required":["id","state","submittedAt","resolvedAt","outcome","createdAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/reviews/{reviewId}/reply":{"post":{"tags":["store"],"summary":"Reply to a customer review","description":"`customerReviewResponses`. There is no PATCH — replacing a reply is a second POST, and Apple keeps one response per review. A 403 here usually means the role: App Manager cannot respond to reviews, only Admin, Account Holder or Customer Support.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":100},"required":true,"name":"reviewId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"responseBody":{"type":"string","minLength":1,"maxLength":5970}},"required":["responseBody"]}}}},"responses":{"200":{"description":"Posted","content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string"},"state":{"type":"string","enum":["unlinked","draft","metadata_complete","build_attached","ready_to_submit","in_review","approved","released","rejected","new_version"]},"results":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string"},"action":{"type":"string","enum":["created","updated","unchanged","skipped","failed"]},"detail":{"type":"string","nullable":true}},"required":["target","action","detail"]}},"warnings":{"type":"array","items":{"type":"string"},"default":[]}},"required":["operation","state","results"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/webhooks":{"get":{"tags":["store"],"summary":"Whether Apple is pushing state changes at this app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Subscription state","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"subscribed":{"type":"boolean"},"webhookId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string"},"default":[]},"url":{"type":"string","nullable":true},"createdAt":{"type":"string","nullable":true}},"required":["appId","subscribed","webhookId","url","createdAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/webhooks/subscribe":{"post":{"tags":["store"],"summary":"Subscribe to Apple's version and build events","description":"Creates the `webhooks` resource with a freshly minted secret, sealed on our side and sent to Apple once — Apple never returns it. Re-subscribing mints a new secret and deletes the old webhook. Polling stays the fallback: a webhook can be deleted in App Store Connect and a delivery can be dropped.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Subscribed","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"subscribed":{"type":"boolean"},"webhookId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string"},"default":[]},"url":{"type":"string","nullable":true},"createdAt":{"type":"string","nullable":true}},"required":["appId","subscribed","webhookId","url","createdAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/store/webhooks/unsubscribe":{"post":{"tags":["store"],"summary":"Stop Apple pushing events for this app","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Unsubscribed","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"subscribed":{"type":"boolean"},"webhookId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string"},"default":[]},"url":{"type":"string","nullable":true},"createdAt":{"type":"string","nullable":true}},"required":["appId","subscribed","webhookId","url","createdAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/store/webhooks/{appId}":{"post":{"tags":["store"],"summary":"Receive an App Store Connect webhook delivery","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64},"required":true,"name":"appId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"nullable":true}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"stored":{"type":"boolean"},"state":{"type":"string","nullable":true}},"required":["stored","state"]}}}},"400":{"description":"Not a delivery","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Bad signature, or no webhook is configured for that app — one answer for both, so the endpoint cannot be walked to find which apps are on the App Store","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many deliveries","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/store-preview":{"post":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appStoreId":{"type":"string","minLength":1,"maxLength":500},"country":{"type":"string","pattern":"^[A-Za-z]{2}$","default":"US"}},"required":["appStoreId"]}}}},"responses":{"200":{"description":"Public listing screenshot choices","content":{"application/json":{"schema":{"type":"object","properties":{"appleAppId":{"type":"string"},"name":{"type":"string"},"country":{"type":"string"},"listingUrl":{"type":"string","format":"uri"},"token":{"type":"string"},"images":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"url":{"type":"string","format":"uri"}},"required":["index","preset","url"]}}},"required":["appleAppId","name","country","listingUrl","token","images"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/store-import":{"post":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appStoreId":{"type":"string","minLength":1,"maxLength":500},"country":{"type":"string","pattern":"^[A-Za-z]{2}$","default":"US"},"token":{"type":"string","pattern":"^[a-f0-9]{64}$"},"selections":{"type":"array","items":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"index":{"type":"integer","minimum":0,"maximum":9}},"required":["preset","index"]},"minItems":1,"maxItems":10}},"required":["appStoreId","token","selections"]}}}},"responses":{"200":{"description":"Imported sources and per-image warnings","content":{"application/json":{"schema":{"type":"object","properties":{"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"bytes":{"type":"number"},"source":{"type":"object","nullable":true,"properties":{"kind":{"type":"string","enum":["app-store"]},"appleAppId":{"type":"string"},"country":{"type":"string"},"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"index":{"type":"integer"},"url":{"type":"string","format":"uri"},"importedAt":{"type":"string"}},"required":["kind","appleAppId","country","preset","index","url","importedAt"]},"generation":{"type":"object","nullable":true,"properties":{"model":{"type":"string"},"referenceAssetId":{"type":"string","format":"uuid"},"prompt":{"type":"string"},"cost":{"type":"number","nullable":true},"createdAt":{"type":"string"}},"required":["model","referenceAssetId","prompt","cost","createdAt"]}},"required":["id","name","width","height","bytes"]}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["assets","warnings"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/workspace":{"get":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Sources and saved sets","content":{"application/json":{"schema":{"type":"object","properties":{"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"bytes":{"type":"number"},"source":{"type":"object","nullable":true,"properties":{"kind":{"type":"string","enum":["app-store"]},"appleAppId":{"type":"string"},"country":{"type":"string"},"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"index":{"type":"integer"},"url":{"type":"string","format":"uri"},"importedAt":{"type":"string"}},"required":["kind","appleAppId","country","preset","index","url","importedAt"]},"generation":{"type":"object","nullable":true,"properties":{"model":{"type":"string"},"referenceAssetId":{"type":"string","format":"uuid"},"prompt":{"type":"string"},"cost":{"type":"number","nullable":true},"createdAt":{"type":"string"}},"required":["model","referenceAssetId","prompt","cost","createdAt"]}},"required":["id","name","width","height","bytes"]}},"sets":{"type":"array","items":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]},"updatedAt":{"type":"string"}},"required":["preset","locale","revision","slides","updatedAt"]}}},"required":["assets","sets"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/set":{"put":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]}},"required":["preset","locale","revision","slides"]}}}},"responses":{"200":{"description":"Saved set with new revision","content":{"application/json":{"schema":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]},"updatedAt":{"type":"string"}},"required":["preset","locale","revision","slides","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/assets":{"post":{"tags":["screenshots"],"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":120},"base64":{"type":"string","minLength":4,"maxLength":11184812,"pattern":"^[A-Za-z0-9+/]*={0,2}$"}},"required":["name","base64"]}}}},"responses":{"201":{"description":"Normalized source","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"bytes":{"type":"number"},"source":{"type":"object","nullable":true,"properties":{"kind":{"type":"string","enum":["app-store"]},"appleAppId":{"type":"string"},"country":{"type":"string"},"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"index":{"type":"integer"},"url":{"type":"string","format":"uri"},"importedAt":{"type":"string"}},"required":["kind","appleAppId","country","preset","index","url","importedAt"]},"generation":{"type":"object","nullable":true,"properties":{"model":{"type":"string"},"referenceAssetId":{"type":"string","format":"uuid"},"prompt":{"type":"string"},"cost":{"type":"number","nullable":true},"createdAt":{"type":"string"}},"required":["model","referenceAssetId","prompt","cost","createdAt"]}},"required":["id","name","width","height","bytes"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/assets/{assetId}":{"get":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"assetId","in":"path"}],"responses":{"200":{"description":"Source PNG","content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string"},"mimeType":{"type":"string"},"base64":{"type":"string"},"warnings":{"type":"array","items":{"type":"string"}}},"required":["filename","mimeType","base64","warnings"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"assetId","in":"path"}],"responses":{"200":{"description":"Unused source removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}},"required":["removed"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/plan":{"post":{"tags":["screenshots"],"summary":"Validate copy, lock the type scale, resolve the grid — before any capture","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]},"minItems":3,"maxItems":10}},"required":["template","locale","device","slides"]}}}},"responses":{"200":{"description":"The resolved grid and locked type scale for this template/device","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/audit":{"get":{"tags":["screenshots"],"summary":"Render the saved set and check it at search-thumbnail scale","description":"Renders every slide of the saved preset/locale set, returns 120px-wide thumbnails plus the eleven machine checks. Bounded and in-request, like render.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"required":true,"name":"locale","in":"query"},{"schema":{"type":"string","enum":["ios-phone","ipad-13"]},"required":true,"name":"device","in":"query"}],"responses":{"200":{"description":"Thumbnails and machine checks","content":{"application/json":{"schema":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string"},"thumbnailWidth":{"type":"integer"},"thumbnails":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"base64":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"}},"required":["index","base64","width","height"]}},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"status":{"type":"string","enum":["pass","fail","warn"]},"detail":{"type":"string"}},"required":["id","label","status","detail"]}},"summary":{"type":"object","properties":{"pass":{"type":"integer"},"fail":{"type":"integer"},"warn":{"type":"integer"}},"required":["pass","fail","warn"]}},"required":["preset","locale","thumbnailWidth","thumbnails","checks","summary"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/screenshots/render":{"post":{"tags":["screenshots"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preset":{"type":"string","enum":["ios-phone","ipad-13"]},"locale":{"type":"string","minLength":2,"maxLength":35,"pattern":"^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$"},"revision":{"type":"integer","minimum":0},"slides":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid"},"backgroundAssetId":{"type":"string","format":"uuid"},"headline":{"type":"string","minLength":1,"maxLength":40},"subtitle":{"type":"string","minLength":1,"maxLength":60},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"layout":{"type":"string","enum":["contained","bleed","overlay","artwork"]},"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"statusBar":{"type":"boolean","default":true},"crop":{"type":"object","properties":{"left":{"type":"number","minimum":0,"maximum":0.99},"top":{"type":"number","minimum":0,"maximum":0.99},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["left","top","width","height"]}},"required":["assetId","headline","subtitle","background","layout"]},"maxItems":10},"font":{"type":"string","enum":["impact","friendly","editorial"],"default":"impact"},"plan":{"type":"object","properties":{"template":{"type":"string","enum":["benefit-story","feature-tour","panorama","dark-hero-light-details","full-bleed-ui","ipad-companion"]},"locale":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13"]},"slides":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["hero","benefit","feature","proof","value","split-view"]},"route":{"type":"string","minLength":1,"maxLength":300},"headline":{"type":"string","minLength":1,"maxLength":60},"subhead":{"type":"string","minLength":1,"maxLength":80}},"required":["role","route","headline","subhead"]}},"grid":{"type":"object","properties":{"canvasWidth":{"type":"number"},"canvasHeight":{"type":"number"},"sideMargin":{"type":"number"},"captionBoxHeight":{"type":"number"},"captionPosition":{"type":"string","enum":["above","beside","overlay"]},"deviceTreatment":{"type":"string","enum":["contained","bleed","none"]}},"required":["canvasWidth","canvasHeight","sideMargin","captionBoxHeight","captionPosition","deviceTreatment"]},"typeScale":{"type":"object","properties":{"headlinePx":{"type":"integer","minimum":0,"exclusiveMinimum":true},"subheadPx":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["headlinePx","subheadPx"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["template","locale","device","slides","grid","typeScale","warnings"]},"index":{"type":"integer","minimum":0,"maximum":9}},"required":["preset","locale","revision","slides"]}}}},"responses":{"200":{"description":"Validated PNG preview or ordered ZIP","content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string"},"mimeType":{"type":"string"},"base64":{"type":"string"},"warnings":{"type":"array","items":{"type":"string"}}},"required":["filename","mimeType","base64","warnings"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/org/invitations/{id}/expiry":{"post":{"tags":["organization"],"summary":"Set how long an invitation stays valid","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"days":{"type":"integer","minimum":1,"maximum":365}},"required":["days"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"expiresAt":{"type":"string"}},"required":["expiresAt"]}}}},"404":{"description":"No such pending invitation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/org":{"delete":{"tags":["organization"],"summary":"Delete this organization and everything in it","description":"Irreversible. Removes every app in the organization along with its store screenshots, analytics, events and stored App Store credentials, then removes the organization, its members and its invitations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"string","maxLength":200}}}}}},"responses":{"200":{"description":"The organization and everything in it was deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]},"id":{"type":"string"},"slug":{"type":"string"},"apps":{"type":"integer"},"note":{"type":"string"}},"required":["deleted","id","slug","apps","note"]}}}},"400":{"description":"The typed confirmation did not match","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such organization","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/project":{"get":{"tags":["studio"],"summary":"This app's Expo project, created from the template on first read","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The project","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"templateId":{"type":"string"},"sdkVersion":{"type":"string"},"bundleId":{"type":"string","nullable":true},"easProjectId":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]}},"version":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"dependencies":{"type":"object","additionalProperties":{"type":"string"}},"previewSupported":{"type":"boolean","default":true},"hasOwnAppConfig":{"type":"boolean","default":false},"appJson":{"type":"string"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"nextRule":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"}},"required":["id","title"]}},"required":["appId","templateId","sdkVersion","bundleId","easProjectId","files","version","dependencies","phase","nextRule"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["studio"],"summary":"Start this app's project from the Studio's template","description":"For an app whose project does not exist yet. `built_here` apps get one on first GET; an imported app has to choose between this and an import, because generating a template over an app that already has source would overwrite it.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The project","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"templateId":{"type":"string"},"sdkVersion":{"type":"string"},"bundleId":{"type":"string","nullable":true},"easProjectId":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]}},"version":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"dependencies":{"type":"object","additionalProperties":{"type":"string"}},"previewSupported":{"type":"boolean","default":true},"hasOwnAppConfig":{"type":"boolean","default":false},"appJson":{"type":"string"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"nextRule":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"}},"required":["id","title"]}},"required":["appId","templateId","sdkVersion","bundleId","easProjectId","files","version","dependencies","phase","nextRule"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/import":{"post":{"tags":["studio"],"summary":"Replace this app's project with an existing Expo project (zip)","description":"`content-type: application/zip`, at most 25MB — the composition root must allow the larger body on this path. node_modules/, ios/, android/, .git/, .expo/, dist/, web-build/ and coverage/ are skipped, and a single wrapping folder (as GitHub's Download ZIP produces) is stripped. The project is replaced, not merged, as one new version.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/zip":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"The imported project","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"templateId":{"type":"string"},"sdkVersion":{"type":"string"},"bundleId":{"type":"string","nullable":true},"easProjectId":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]}},"version":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"dependencies":{"type":"object","additionalProperties":{"type":"string"}},"previewSupported":{"type":"boolean","default":true},"hasOwnAppConfig":{"type":"boolean","default":false},"appJson":{"type":"string"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"nextRule":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"}},"required":["id","title"]}},"required":["appId","templateId","sdkVersion","bundleId","easProjectId","files","version","dependencies","phase","nextRule"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/files":{"put":{"tags":["studio"],"summary":"Replace the project's files (manual edit), creating a version","description":"The composition root must allow a larger body on this path; a project is bigger than the 64KB default.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]},"maxItems":400}},"required":["files"]}}}},"responses":{"200":{"description":"The saved project","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"templateId":{"type":"string"},"sdkVersion":{"type":"string"},"bundleId":{"type":"string","nullable":true},"easProjectId":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]}},"version":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"dependencies":{"type":"object","additionalProperties":{"type":"string"}},"previewSupported":{"type":"boolean","default":true},"hasOwnAppConfig":{"type":"boolean","default":false},"appJson":{"type":"string"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"nextRule":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"}},"required":["id","title"]}},"required":["appId","templateId","sdkVersion","bundleId","easProjectId","files","version","dependencies","phase","nextRule"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"tags":["studio"],"summary":"Write or delete some files, leaving every other file alone","description":"The partial save coding agents and `broctic dev` use. Send `baseVersionId` (the version you read) and the patch is refused with 409 `studio_conflict` only if a file it touches changed since. `live: true` folds a stream of small edits into one version.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"changes":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]},{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"delete":{"type":"boolean","enum":[true]}},"required":["path","delete"]}]},"minItems":1,"maxItems":200},"baseVersionId":{"type":"string","format":"uuid"},"summary":{"type":"string","minLength":1,"maxLength":200},"live":{"type":"boolean","default":false}},"required":["changes"]}}}},"responses":{"200":{"description":"What was written","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"revision":{"type":"string"},"changed":{"type":"array","items":{"type":"string"}},"deleted":{"type":"array","items":{"type":"string"}},"coalesced":{"type":"boolean"}},"required":["version","revision","changed","deleted","coalesced"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/icon":{"put":{"tags":["studio"],"summary":"Set the app's icon from an SVG or PNG","description":"Renders the 1024x1024 square both stores build every other size from, flattened onto the app's accent — the App Store rejects an icon with an alpha channel.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"svg":{"type":"string","minLength":32,"maxLength":400000},"png":{"type":"string","minLength":64,"maxLength":4000000}}}}}},"responses":{"200":{"description":"The icon","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"path":{"type":"string"},"bytes":{"type":"integer"}},"required":["version","path","bytes"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/kit":{"post":{"tags":["studio"],"summary":"Rewrite the project's kit to the current one","description":"A project keeps the kit it was created with. This writes today's kit/ files and any dependencies they need, as a version, and leaves screens, lib/ and components/ alone.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"What changed","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"changed":{"type":"array","items":{"type":"string"}},"kitVersion":{"type":"string"}},"required":["version","changed","kitVersion"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/project/head":{"get":{"tags":["studio"],"summary":"The newest version and revision, without any file contents","description":"Poll this to notice an edit made anywhere else; fetch the project only when `revision` moves.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The head","content":{"application/json":{"schema":{"type":"object","properties":{"versionId":{"type":"string","nullable":true,"format":"uuid"},"number":{"type":"integer","nullable":true,"minimum":0,"exclusiveMinimum":true},"summary":{"type":"string","nullable":true},"revision":{"type":"string"}},"required":["versionId","number","summary","revision"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/messages":{"get":{"tags":["studio"],"summary":"The chat transcript, oldest first","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Messages","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"changedPaths":{"type":"array","nullable":true,"items":{"type":"string"}},"status":{"type":"string","enum":["running","done","failed"]},"error":{"type":"string","nullable":true},"createdAt":{"type":"string"}},"required":["id","role","content","versionId","changedPaths","status","error","createdAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["studio"],"summary":"Send a message and stream the generation back","description":"Server-sent events. Each `data:` line is one StudioEvent: {type:'text'|'file'|'done'|'error'}. One generation at a time per app — a second concurrent request is refused with 409 generation_in_progress.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":4000}},"required":["content"]}}}},"responses":{"200":{"description":"A stream of StudioEvent JSON objects","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/versions":{"get":{"tags":["studio"],"summary":"Every version of this project, newest first","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Versions","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/versions/{versionId}/restore":{"post":{"tags":["studio"],"summary":"Restore a version as a new version","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"versionId","in":"path"}],"responses":{"200":{"description":"The restored project","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"templateId":{"type":"string"},"sdkVersion":{"type":"string"},"bundleId":{"type":"string","nullable":true},"easProjectId":{"type":"string","nullable":true},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[A-Za-z0-9_@][A-Za-z0-9_./@()[\\]+-]{0,200}$"},"content":{"type":"string","maxLength":5333336},"encoding":{"type":"string","enum":["utf8","base64"],"default":"utf8"}},"required":["path","content"]}},"version":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]},"dependencies":{"type":"object","additionalProperties":{"type":"string"}},"previewSupported":{"type":"boolean","default":true},"hasOwnAppConfig":{"type":"boolean","default":false},"appJson":{"type":"string"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"nextRule":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"}},"required":["id","title"]}},"required":["appId","templateId","sdkVersion","bundleId","easProjectId","files","version","dependencies","phase","nextRule"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/export.zip":{"get":{"tags":["studio"],"summary":"Download the project, including a rendered app.json, eas.json and package.json","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The project as a zip archive","content":{"application/zip":{"schema":{"type":"string"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/settings":{"get":{"tags":["studio"],"summary":"What still has to be configured before this app can ship","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Readiness","content":{"application/json":{"schema":{"type":"object","properties":{"aiConfigured":{"type":"boolean"},"easConfigured":{"type":"boolean"},"githubConfigured":{"type":"boolean"},"appleConnected":{"type":"boolean"},"appleTeamKnown":{"type":"boolean"},"appleAppLinked":{"type":"boolean"},"playConfigured":{"type":"boolean"},"bundleId":{"type":"string","nullable":true}},"required":["aiConfigured","easConfigured","githubConfigured","appleConnected","appleTeamKnown","appleAppLinked","playConfigured","bundleId"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["studio"],"summary":"Set this app's bundle identifier","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bundleId":{"type":"string","minLength":3,"maxLength":155,"pattern":"^[a-z][a-z0-9]*(\\.[a-z0-9-]+)+$"}}}}}},"responses":{"200":{"description":"Readiness","content":{"application/json":{"schema":{"type":"object","properties":{"aiConfigured":{"type":"boolean"},"easConfigured":{"type":"boolean"},"githubConfigured":{"type":"boolean"},"appleConnected":{"type":"boolean"},"appleTeamKnown":{"type":"boolean"},"appleAppLinked":{"type":"boolean"},"playConfigured":{"type":"boolean"},"bundleId":{"type":"string","nullable":true}},"required":["aiConfigured","easConfigured","githubConfigured","appleConnected","appleTeamKnown","appleAppLinked","playConfigured","bundleId"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/audit":{"get":{"tags":["studio"],"summary":"Every playbook rule against this project, by phase","description":"Computed from the project's files on every read — nothing is cached, because a stored verdict disagrees with the files the moment somebody saves. `phase` is the first phase, in order, that still has a required rule nobody has satisfied: failing, or waiting on a human. A rule whose `status` is `manual` needs a person; ticking it with `PUT …/studio/audit/manual` makes it `pass` and can move the phase on.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The audit, the phase, and the manual ticks behind it","content":{"application/json":{"schema":{"type":"object","properties":{"phases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"title":{"type":"string"},"goal":{"type":"string"},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"must":{"type":"string"},"why":{"type":"string"},"status":{"type":"string","enum":["pass","fail","manual","skip"]},"auto":{"type":"string","enum":["pass","fail","manual","skip"]},"detail":{"type":"string"},"required":{"type":"boolean"},"checkedBy":{"type":"string","enum":["human","ai"]},"checkedAt":{"type":"string"},"note":{"type":"string"},"stale":{"type":"boolean"}},"required":["id","title","must","why","status","required"]}},"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"}},"required":["id","title","goal","rules","passed","failed","manual"]}},"summary":{"type":"object","properties":{"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"},"readyToShip":{"type":"boolean"}},"required":["passed","failed","manual","readyToShip"]},"pass":{"type":"string","enum":["build","ship"]},"stale":{"type":"integer"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"manualChecks":{"type":"object","additionalProperties":{"type":"object","properties":{"done":{"type":"boolean"},"by":{"type":"string","enum":["human","ai"]},"at":{"type":"string"},"note":{"type":"string"},"version":{"type":"string"}},"required":["done","by","at"]}},"passes":{"type":"array","items":{"type":"object","properties":{"pass":{"type":"string","enum":["build","ship"]},"versionId":{"type":"string"},"at":{"type":"string"},"by":{"type":"string","enum":["human","ai"]}},"required":["pass","versionId","at","by"]}}},"required":["phases","summary","pass","stale","phase","manualChecks","passes"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/audit/manual":{"put":{"tags":["studio"],"summary":"Tick or un-tick one manual playbook rule","description":"For the rules a file set cannot answer — \"I ran it and looked at every screen\", \"the screenshots are of the real app\", \"the app never begs for a rating\". A tick stores **who, when and what they saw**: `by` is `human` or `ai`, `at` is stamped by the server, and `note` is the evidence. `by` defaults to `ai` when the caller authenticated with an `x-api-key` and `human` for a session, and the body may say so explicitly — the MCP `studio_check` tool always sends `ai`. A tick or an untick applies to **any** rule, automatic ones included, and wins over the files; the automatic verdict stays visible as `auto`. Un-ticking stores `done: false`; `DELETE …/audit/manual/{ruleId}` forgets the record so the rule reads from the files again. The whole audit comes back, because ticking one of these is what moves a project to the next phase.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ruleId":{"type":"string","minLength":1,"maxLength":120},"done":{"type":"boolean"},"note":{"type":"string","maxLength":1000},"by":{"type":"string","enum":["human","ai"]}},"required":["ruleId","done"]}}}},"responses":{"200":{"description":"The audit after the change","content":{"application/json":{"schema":{"type":"object","properties":{"phases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"title":{"type":"string"},"goal":{"type":"string"},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"must":{"type":"string"},"why":{"type":"string"},"status":{"type":"string","enum":["pass","fail","manual","skip"]},"auto":{"type":"string","enum":["pass","fail","manual","skip"]},"detail":{"type":"string"},"required":{"type":"boolean"},"checkedBy":{"type":"string","enum":["human","ai"]},"checkedAt":{"type":"string"},"note":{"type":"string"},"stale":{"type":"boolean"}},"required":["id","title","must","why","status","required"]}},"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"}},"required":["id","title","goal","rules","passed","failed","manual"]}},"summary":{"type":"object","properties":{"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"},"readyToShip":{"type":"boolean"}},"required":["passed","failed","manual","readyToShip"]},"pass":{"type":"string","enum":["build","ship"]},"stale":{"type":"integer"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"manualChecks":{"type":"object","additionalProperties":{"type":"object","properties":{"done":{"type":"boolean"},"by":{"type":"string","enum":["human","ai"]},"at":{"type":"string"},"note":{"type":"string"},"version":{"type":"string"}},"required":["done","by","at"]}},"passes":{"type":"array","items":{"type":"object","properties":{"pass":{"type":"string","enum":["build","ship"]},"versionId":{"type":"string"},"at":{"type":"string"},"by":{"type":"string","enum":["human","ai"]}},"required":["pass","versionId","at","by"]}}},"required":["phases","summary","pass","stale","phase","manualChecks","passes"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/audit/manual/{ruleId}":{"delete":{"tags":["studio"],"summary":"Forget a tick or untick so the rule reads from the files again","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":120},"required":true,"name":"ruleId","in":"path"}],"responses":{"200":{"description":"The audit after the change","content":{"application/json":{"schema":{"type":"object","properties":{"phases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"title":{"type":"string"},"goal":{"type":"string"},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"must":{"type":"string"},"why":{"type":"string"},"status":{"type":"string","enum":["pass","fail","manual","skip"]},"auto":{"type":"string","enum":["pass","fail","manual","skip"]},"detail":{"type":"string"},"required":{"type":"boolean"},"checkedBy":{"type":"string","enum":["human","ai"]},"checkedAt":{"type":"string"},"note":{"type":"string"},"stale":{"type":"boolean"}},"required":["id","title","must","why","status","required"]}},"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"}},"required":["id","title","goal","rules","passed","failed","manual"]}},"summary":{"type":"object","properties":{"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"},"readyToShip":{"type":"boolean"}},"required":["passed","failed","manual","readyToShip"]},"pass":{"type":"string","enum":["build","ship"]},"stale":{"type":"integer"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"manualChecks":{"type":"object","additionalProperties":{"type":"object","properties":{"done":{"type":"boolean"},"by":{"type":"string","enum":["human","ai"]},"at":{"type":"string"},"note":{"type":"string"},"version":{"type":"string"}},"required":["done","by","at"]}},"passes":{"type":"array","items":{"type":"object","properties":{"pass":{"type":"string","enum":["build","ship"]},"versionId":{"type":"string"},"at":{"type":"string"},"by":{"type":"string","enum":["human","ai"]}},"required":["pass","versionId","at","by"]}}},"required":["phases","summary","pass","stale","phase","manualChecks","passes"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/audit/passes":{"post":{"tags":["studio"],"summary":"Record that a pass over the requirements just finished","description":"Appends `{pass, versionId, at, by}` to the app's review log — `versionId` is the project's current version, read here rather than sent by the caller. `by` follows the same rule `PUT …/audit/manual` does: `ai` for an API-key caller, `human` for a session. The Ship tab uses the newest `ship` entry to say whether the project has been reviewed since its last change. Refused with 409 if the project has no version yet — there is nothing to record a pass against.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"pass":{"type":"string","enum":["build","ship"]}},"required":["pass"]}}}},"responses":{"200":{"description":"The audit, with the new pass in `passes`","content":{"application/json":{"schema":{"type":"object","properties":{"phases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"title":{"type":"string"},"goal":{"type":"string"},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"must":{"type":"string"},"why":{"type":"string"},"status":{"type":"string","enum":["pass","fail","manual","skip"]},"auto":{"type":"string","enum":["pass","fail","manual","skip"]},"detail":{"type":"string"},"required":{"type":"boolean"},"checkedBy":{"type":"string","enum":["human","ai"]},"checkedAt":{"type":"string"},"note":{"type":"string"},"stale":{"type":"boolean"}},"required":["id","title","must","why","status","required"]}},"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"}},"required":["id","title","goal","rules","passed","failed","manual"]}},"summary":{"type":"object","properties":{"passed":{"type":"integer"},"failed":{"type":"integer"},"manual":{"type":"integer"},"readyToShip":{"type":"boolean"}},"required":["passed","failed","manual","readyToShip"]},"pass":{"type":"string","enum":["build","ship"]},"stale":{"type":"integer"},"phase":{"type":"string","enum":["core","verify","accounts","subscriptions","funnel","analytics","submission","ship"]},"manualChecks":{"type":"object","additionalProperties":{"type":"object","properties":{"done":{"type":"boolean"},"by":{"type":"string","enum":["human","ai"]},"at":{"type":"string"},"note":{"type":"string"},"version":{"type":"string"}},"required":["done","by","at"]}},"passes":{"type":"array","items":{"type":"object","properties":{"pass":{"type":"string","enum":["build","ship"]},"versionId":{"type":"string"},"at":{"type":"string"},"by":{"type":"string","enum":["human","ai"]}},"required":["pass","versionId","at","by"]}}},"required":["phases","summary","pass","stale","phase","manualChecks","passes"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/builds":{"get":{"tags":["studio"],"summary":"This app's native builds, newest first","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Builds","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["studio"],"summary":"Start a signed build on EAS (one row per platform)","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","enum":["ios","android","all"]}},"required":["platform"]}}}},"responses":{"200":{"description":"The builds that were started","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/builds/{buildId}/refresh":{"post":{"tags":["studio"],"summary":"Re-read this build's status from EAS","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The build","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/builds/{buildId}/submit":{"post":{"tags":["studio"],"summary":"Send this build to TestFlight or Google Play's internal track","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The build","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/builds/{buildId}/cancel":{"post":{"tags":["studio"],"summary":"Cancel this build","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The build","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/runs":{"get":{"tags":["studio"],"summary":"This app's browser runs (web exports), newest first","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Runs","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["studio"],"summary":"Export this app for the web on a free GitHub job","description":"Needs only STUDIO_GITHUB_TOKEN — no EAS, no Apple, no bundle identifier. Takes two to four minutes; the row finishes when the bundle arrives.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The run","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/runs/latest":{"get":{"tags":["studio"],"summary":"The newest finished browser run, or null","description":"What the phone frame shows. One row rather than a list, because the console polls this while a run is going and the answer it wants is 'is there a newer one yet'.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The newest finished run, or null","content":{"application/json":{"schema":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/runs/{buildId}/preview":{"post":{"tags":["studio"],"summary":"Mint a two-hour URL that serves this run in an iframe","description":"The URL carries a one-off token; opening it plants a cookie scoped to that run so the bundle's own asset requests are authorised without one.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The preview URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/bundle":{"get":{"tags":["studio"],"summary":"Everything the build runner needs: files, rendered config, credentials","description":"Called by the GitHub Actions job with its one-time bearer token. The Apple private key leaves this API here and nowhere else.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The build bundle","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/callback":{"post":{"tags":["studio"],"summary":"Progress, EAS ids and newly created signing material from the runner","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"buildId":{"type":"string","format":"uuid"},"phase":{"type":"string","enum":["dispatched","eas_started","web_exported","submitted","failed"]},"platform":{"type":"string","enum":["ios","android","web"]},"runUrl":{"type":"string"},"easBuildId":{"type":"string"},"easBuildUrl":{"type":"string"},"easProjectId":{"type":"string"},"error":{"type":"string","maxLength":8000},"signing":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","maxLength":64},"secretBase64":{"type":"string","maxLength":2000000}},"required":["kind","secretBase64"]},"maxItems":16}},"required":["buildId","phase"]}}}},"responses":{"204":{"description":"Recorded"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/web-bundle":{"put":{"tags":["studio"],"summary":"The zip of the runner's `expo export --platform web` output","description":"`content-type: application/zip`, at most 40MB, bearer token as everywhere under /internal. Must contain index.html. Storing it is what finishes the run; a retry replaces the bytes.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"requestBody":{"required":true,"content":{"application/zip":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"The run","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/drives":{"post":{"tags":["studio"],"summary":"Drive the newest browser run and screenshot it","description":"Opens the web export the newest finished run produced, walks at most 20 steps (`navigate`, `tap`, `type`, `press`, `wait`, `screenshot`) on a phone or tablet viewport, and uploads the PNGs. Free, and about a minute. Needs a finished browser run: 409 `studio_no_run` otherwise.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"steps":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"navigate":{"type":"string","minLength":1,"maxLength":300}},"required":["navigate"],"additionalProperties":false},{"type":"object","properties":{"tap":{"type":"string","minLength":1,"maxLength":200}},"required":["tap"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","minLength":1,"maxLength":200}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"press":{"type":"string","enum":["Enter","Tab","Escape","Backspace","Delete","Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown"]}},"required":["press"],"additionalProperties":false},{"type":"object","properties":{"wait":{"type":"integer","minimum":0,"maximum":8000}},"required":["wait"],"additionalProperties":false},{"type":"object","properties":{"screenshot":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["screenshot"],"additionalProperties":false},{"type":"object","properties":{"onboarded":{"type":"boolean","enum":[true]}},"required":["onboarded"],"additionalProperties":false}]},"maxItems":20},"device":{"type":"string","enum":["ios-phone","ipad-13","store-phone","store-ipad"],"default":"ios-phone"}}}}}},"responses":{"200":{"description":"The drive","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/drives/{buildId}":{"get":{"tags":["studio"],"summary":"A drive: its status, its step log and the screenshots it took","description":"Poll this while `status` is `queued`, `dispatching` or `building`. `captures[].url` is the PNG; `log` is every step with its timing and, when one failed, the failure text verbatim.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The drive","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"device":{"type":"string","enum":["ios-phone","ipad-13","store-phone","store-ipad"]},"steps":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"navigate":{"type":"string","minLength":1,"maxLength":300}},"required":["navigate"],"additionalProperties":false},{"type":"object","properties":{"tap":{"type":"string","minLength":1,"maxLength":200}},"required":["tap"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","minLength":1,"maxLength":200}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"press":{"type":"string","enum":["Enter","Tab","Escape","Backspace","Delete","Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown"]}},"required":["press"],"additionalProperties":false},{"type":"object","properties":{"wait":{"type":"integer","minimum":0,"maximum":8000}},"required":["wait"],"additionalProperties":false},{"type":"object","properties":{"screenshot":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["screenshot"],"additionalProperties":false},{"type":"object","properties":{"onboarded":{"type":"boolean","enum":[true]}},"required":["onboarded"],"additionalProperties":false}]}},"log":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"captures":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"bytes":{"type":"integer","minimum":0},"url":{"type":"string"}},"required":["name","bytes","url"]}}},"required":["id","status","device","steps","log","error","captures"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/drives/{buildId}/captures/{name}":{"get":{"tags":["studio"],"summary":"One screenshot from a drive, as a PNG","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"name","in":"path"}],"responses":{"200":{"description":"The screenshot","content":{"image/png":{"schema":{"type":"string"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/drive":{"get":{"tags":["studio"],"summary":"Everything a drive runner needs: a preview URL, a viewport and the steps","description":"The drive equivalent of `/bundle`, and deliberately not that route: a drive installs nothing and builds nothing, so it is never handed the project's files or any credential. The preview token in `previewUrl` is minted when this is called.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The drive bundle","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/captures":{"put":{"tags":["studio"],"summary":"The zip of the drive's screenshots","description":"`content-type: application/zip`, at most 20MB, bearer token as everywhere under /internal. One PNG per screenshot at the archive root, named after the step. A retry replaces the bytes under the same names.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"requestBody":{"required":true,"content":{"application/zip":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"How many screenshots were stored","content":{"application/json":{"schema":{"type":"object","properties":{"stored":{"type":"number"}},"required":["stored"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/drive/callback":{"post":{"tags":["studio"],"summary":"The drive's step log, and whether the script finished","description":"`captured` finishes the row; `failed` errors it. Both carry the log — a drive that stopped on step four still uploaded three screenshots, and the log is the only thing that says which step stopped it and why.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phase":{"type":"string","enum":["captured","failed"]},"log":{"type":"string","maxLength":20000},"error":{"type":"string","maxLength":4000}},"required":["phase"]}}}},"responses":{"204":{"description":"Recorded"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/qa":{"post":{"tags":["studio"],"summary":"Sweep every screen of the newest browser run for speed and glitches","description":"Walks every route under `app/` at an iPhone and an iPad viewport and records whether each screen rendered, what it logged, whether it overflows, how many controls are under 44pt, how much text is clipped, and how long it took to paint — plus a screenshot per route. Free, up to about eight minutes. Needs a finished browser run: 409 `studio_no_run` otherwise. The playbook's `performance` and `quality` rules read what it stores.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The sweep","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"appId":{"type":"string"},"versionId":{"type":"string","nullable":true,"format":"uuid"},"platform":{"type":"string","enum":["ios","android","web"]},"profile":{"type":"string"},"status":{"type":"string","enum":["queued","dispatching","building","finished","errored","canceled"]},"runUrl":{"type":"string","nullable":true},"easBuildId":{"type":"string","nullable":true},"easBuildUrl":{"type":"string","nullable":true},"artifactUrl":{"type":"string","nullable":true},"artifactExpiresAt":{"type":"string","nullable":true},"appVersion":{"type":"string","nullable":true},"buildNumber":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"submitStatus":{"type":"string","nullable":true,"enum":["submitting","submitted","failed"]},"submitError":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","versionId","platform","profile","status","runUrl","easBuildId","easBuildUrl","artifactUrl","artifactExpiresAt","appVersion","buildNumber","error","submitStatus","submitError","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"get":{"tags":["studio"],"summary":"The newest QA sweep and what it found","description":"`status: \"none\"` when this app has never had one. `stale` is true when the report was taken against a version the project has since moved past — the same comparison the audit makes, so the console can say it without fetching the audit.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The sweep","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string"},"error":{"type":"string","nullable":true},"log":{"type":"string","nullable":true},"report":{"type":"object","nullable":true,"properties":{"versionId":{"type":"string","nullable":true},"runId":{"type":"string","nullable":true},"at":{"type":"string"},"routes":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","maxLength":300},"viewport":{"type":"string","enum":["phone","tablet"]},"rendered":{"type":"boolean"},"failure":{"type":"string","nullable":true,"maxLength":500},"consoleErrors":{"type":"array","items":{"type":"string","maxLength":500},"maxItems":50},"consoleErrorCount":{"type":"integer","minimum":0},"keyWarnings":{"type":"integer","minimum":0},"overflowPx":{"type":"integer","minimum":0},"smallTapTargets":{"type":"integer","minimum":0},"truncatedText":{"type":"integer","minimum":0},"imagesWithoutSize":{"type":"integer","minimum":0},"firstPaintMs":{"type":"number","nullable":true,"minimum":0},"transitionMs":{"type":"number","nullable":true,"minimum":0},"capture":{"type":"string","nullable":true,"maxLength":60}},"required":["path","viewport","rendered","failure","consoleErrors","consoleErrorCount","keyWarnings","overflowPx","smallTapTargets","truncatedText","imagesWithoutSize","firstPaintMs","transitionMs","capture"]},"maxItems":120},"skipped":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","maxLength":300},"reason":{"type":"string","maxLength":200}},"required":["path","reason"]},"maxItems":60},"bundleJsBytes":{"type":"integer","nullable":true,"minimum":0},"bundleTotalBytes":{"type":"integer","nullable":true,"minimum":0},"error":{"type":"string","nullable":true,"maxLength":2000,"default":null}},"required":["versionId","runId","at","routes","skipped","bundleJsBytes","bundleTotalBytes"]},"captures":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"bytes":{"type":"integer"},"url":{"type":"string"}},"required":["name","bytes","url"]}},"stale":{"type":"boolean"}},"required":["id","status","error","log","report","captures","stale"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/qa/{buildId}":{"get":{"tags":["studio"],"summary":"One QA sweep: its status, its log and its findings","description":"Poll this while `status` is `queued`, `dispatching` or `building`. `report` is null until the runner reports; a failed sweep still carries whatever it measured.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The sweep","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string"},"error":{"type":"string","nullable":true},"log":{"type":"string","nullable":true},"report":{"type":"object","nullable":true,"properties":{"versionId":{"type":"string","nullable":true},"runId":{"type":"string","nullable":true},"at":{"type":"string"},"routes":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","maxLength":300},"viewport":{"type":"string","enum":["phone","tablet"]},"rendered":{"type":"boolean"},"failure":{"type":"string","nullable":true,"maxLength":500},"consoleErrors":{"type":"array","items":{"type":"string","maxLength":500},"maxItems":50},"consoleErrorCount":{"type":"integer","minimum":0},"keyWarnings":{"type":"integer","minimum":0},"overflowPx":{"type":"integer","minimum":0},"smallTapTargets":{"type":"integer","minimum":0},"truncatedText":{"type":"integer","minimum":0},"imagesWithoutSize":{"type":"integer","minimum":0},"firstPaintMs":{"type":"number","nullable":true,"minimum":0},"transitionMs":{"type":"number","nullable":true,"minimum":0},"capture":{"type":"string","nullable":true,"maxLength":60}},"required":["path","viewport","rendered","failure","consoleErrors","consoleErrorCount","keyWarnings","overflowPx","smallTapTargets","truncatedText","imagesWithoutSize","firstPaintMs","transitionMs","capture"]},"maxItems":120},"skipped":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","maxLength":300},"reason":{"type":"string","maxLength":200}},"required":["path","reason"]},"maxItems":60},"bundleJsBytes":{"type":"integer","nullable":true,"minimum":0},"bundleTotalBytes":{"type":"integer","nullable":true,"minimum":0},"error":{"type":"string","nullable":true,"maxLength":2000,"default":null}},"required":["versionId","runId","at","routes","skipped","bundleJsBytes","bundleTotalBytes"]},"captures":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"bytes":{"type":"integer"},"url":{"type":"string"}},"required":["name","bytes","url"]}},"stale":{"type":"boolean"}},"required":["id","status","error","log","report","captures","stale"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/studio/qa/{buildId}/captures/{name}":{"get":{"tags":["studio"],"summary":"One route's screenshot from a QA sweep, as a PNG","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"name","in":"path"}],"responses":{"200":{"description":"The screenshot","content":{"image/png":{"schema":{"type":"string"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/qa":{"get":{"tags":["studio"],"summary":"Everything a QA runner needs: a preview URL, the route list and two viewports","description":"The route list is derived on the server from the project's `app/**` files, never by the runner: every path the browser is sent to has to be a path inside the previewed app. No project files, no package.json and no credential are handed over — a sweep opens a web page.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"responses":{"200":{"description":"The QA bundle","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/qa/captures":{"put":{"tags":["studio"],"summary":"The zip of the sweep's per-route screenshots","description":"`content-type: application/zip`, at most 30MB, bearer token as everywhere under /internal. One PNG per capture at the archive root, named after the route. A retry replaces the bytes under the same names.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"requestBody":{"required":true,"content":{"application/zip":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"How many screenshots were stored","content":{"application/json":{"schema":{"type":"object","properties":{"stored":{"type":"number"}},"required":["stored"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/studio/builds/{buildId}/qa/callback":{"post":{"tags":["studio"],"summary":"What the sweep found, route by route","description":"`swept` finishes the row; `failed` errors it, and both store whatever was measured. The API fills in the four facts the runner cannot state honestly — which version this is evidence about, which run was walked, when, and how big the bundle is.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"buildId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phase":{"type":"string","enum":["swept","failed"]},"routes":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","maxLength":300},"viewport":{"type":"string","enum":["phone","tablet"]},"rendered":{"type":"boolean"},"failure":{"type":"string","nullable":true,"maxLength":500},"consoleErrors":{"type":"array","items":{"type":"string","maxLength":500},"maxItems":50},"consoleErrorCount":{"type":"integer","minimum":0},"keyWarnings":{"type":"integer","minimum":0},"overflowPx":{"type":"integer","minimum":0},"smallTapTargets":{"type":"integer","minimum":0},"truncatedText":{"type":"integer","minimum":0},"imagesWithoutSize":{"type":"integer","minimum":0},"firstPaintMs":{"type":"number","nullable":true,"minimum":0},"transitionMs":{"type":"number","nullable":true,"minimum":0},"capture":{"type":"string","nullable":true,"maxLength":60}},"required":["path","viewport","rendered","failure","consoleErrors","consoleErrorCount","keyWarnings","overflowPx","smallTapTargets","truncatedText","imagesWithoutSize","firstPaintMs","transitionMs","capture"]},"maxItems":120,"default":[]},"skipped":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","maxLength":300},"reason":{"type":"string","maxLength":200}},"required":["path","reason"]},"maxItems":60,"default":[]},"log":{"type":"string","maxLength":20000},"error":{"type":"string","maxLength":2000}},"required":["phase"]}}}},"responses":{"204":{"description":"Recorded"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/preview":{"get":{"tags":["preview"],"summary":"This app's hosted preview, without starting it","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The preview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewSession"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["preview"],"summary":"Start this app's hosted preview (or keep it running)","description":"Starts a dev server for the app on Broctic's own infrastructure, or returns the one already running. Idempotent: call it whenever the Studio opens. `webUrl` loads in a browser, `expoUrl` in the App Store's Expo Go. A cold start takes roughly half a minute; poll the GET until `ready`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The preview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewSession"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["preview"],"summary":"Stop this app's hosted preview","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Stopped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewSession"}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/preview/snapshot":{"get":{"tags":["preview"],"summary":"The project, for a preview runner (long-polls for a newer version)","parameters":[{"schema":{"type":"integer","nullable":true,"minimum":-1,"default":-1},"required":false,"name":"since","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":25,"default":0},"required":false,"name":"wait","in":"query"}],"responses":{"200":{"description":"A newer version","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"integer"},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"content":{"type":"string"},"encoding":{"type":"string","enum":["utf8","base64"]}},"required":["path","content","encoding"]}}},"required":["version","files"]}}}},"204":{"description":"Nothing newer within the wait"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/preview/heartbeat":{"post":{"tags":["preview"],"summary":"A preview runner reporting its state","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phase":{"type":"string","enum":["starting","installing","ready","error","stopping","stopped"]},"ready":{"type":"boolean"},"version":{"type":"integer","minimum":-1,"maximum":1000000},"openSockets":{"type":"integer","minimum":0,"maximum":10000},"lastActivityAt":{"type":"string","format":"date-time"},"error":{"type":"string","nullable":true,"maxLength":2000},"errors":{"type":"array","items":{"type":"string","maxLength":1000},"maxItems":20}},"required":["phase","ready","version","openSockets","lastActivityAt","error","errors"]}}}},"responses":{"204":{"description":"Recorded"},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/internal/preview/route":{"get":{"tags":["preview"],"summary":"Where a preview label's container is (and wake it if stopped)","parameters":[{"schema":{"type":"string","maxLength":64},"required":true,"name":"label","in":"query"}],"responses":{"200":{"description":"The route","content":{"application/json":{"schema":{"type":"object","properties":{"phase":{"type":"string","enum":["starting","installing","ready","error","stopping","stopped"]},"ready":{"type":"boolean"},"ip":{"type":"string","nullable":true},"port":{"type":"integer","nullable":true}},"required":["phase","ready","ip","port"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel":{"get":{"tags":["funnels"],"summary":"This app's onboarding funnel, and the experiment running on it","description":"Arm A is read from the project's own `lib/funnel.json` on every call (an older app's `lib/funnel.ts` is converted and reported as `legacy`), because the chat edits these files too and a cached copy would show a funnel the app stopped shipping. A funnel that cannot be read is reported as `unparseable` with a hint, never as an empty one.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The funnel, and the current experiment if there is one","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"source":{"type":"string","enum":["json","legacy","missing","unparseable"]},"doc":{"type":"object","nullable":true,"properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"drafts":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]}},"hint":{"type":"string","nullable":true},"rendererInstalled":{"type":"boolean"},"experiment":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]},"posthogLinked":{"type":"boolean"}},"required":["appId","source","doc","drafts","hint","rendererInstalled","experiment","posthogLinked"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"tags":["funnels"],"summary":"Save the onboarding funnel and its draft arms","description":"Writes `lib/funnel.json` (arm A, what the app ships) and `lib/funnel.variants.json` (draft arms B–D, imported by nothing) as one project version, so the live preview reloads with them. The first save of an app built before funnel design v2 also installs the kit's funnel renderer and an onboarding route that uses it; the version is restorable like any other.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"drafts":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"maxItems":3,"default":[]}},"required":["doc"]}}}},"responses":{"200":{"description":"The funnel as saved","content":{"application/json":{"schema":{"type":"object","properties":{"appId":{"type":"string"},"source":{"type":"string","enum":["json","legacy","missing","unparseable"]},"doc":{"type":"object","nullable":true,"properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"drafts":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]}},"hint":{"type":"string","nullable":true},"rendererInstalled":{"type":"boolean"},"experiment":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]},"posthogLinked":{"type":"boolean"}},"required":["appId","source","doc","drafts","hint","rendererInstalled","experiment","posthogLinked"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/experiments":{"get":{"tags":["funnels"],"summary":"Every funnel experiment this app has run, newest first","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Bounded to the 50 most recent","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]}}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["funnels"],"summary":"Start an A/B test of the onboarding funnel","description":"Records the experiment and starts serving its arms. Two to four arms, control first, weights adding up to 100; from this moment `GET /v1/experiments` hands each person the arm a hash of the experiment and their device id puts them in, so assignment is sticky and nothing is stored per person. Needs no third-party account. One running experiment per app: two would split the same population twice and neither result would mean anything. An arm's weights cannot be changed while it runs — that would re-bucket people who have already seen an arm.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]}},"required":["variants"]}}}},"responses":{"201":{"description":"Running","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/variants/propose":{"post":{"tags":["funnels"],"summary":"Ask Claude for variant B","description":"One non-streaming model call, constrained by the funnel, monetization and wins rules of the playbook — the same objects the audit checks, so a proposal cannot be something that would fail the audit once promoted. Writes nothing: the variant comes back for a person to edit, and only starting an experiment sends it anywhere.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"instruction":{"type":"string","maxLength":500},"model":{"type":"string","maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$"},"mode":{"type":"string","enum":["challenger","revise"]},"history":{"type":"array","items":{"type":"string","maxLength":500},"maxItems":12}}}}}},"responses":{"200":{"description":"A proposed variant, validated","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/models":{"get":{"tags":["funnels"],"summary":"The models a funnel can be designed with","description":"OpenRouter's text models, with this environment's default first. Pass one as `model` to `variants/propose`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The models","content":{"application/json":{"schema":{"type":"object","properties":{"default":{"type":"string"},"locked":{"type":"boolean"},"models":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id"]}}},"required":["default","locked","models"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/phone-preview":{"post":{"tags":["funnels"],"summary":"A code to open this funnel on a phone","description":"Stores the given funnel document for an hour and returns a token. The app, opened in Expo Go at `/onboarding/1?preview=<token>`, shows exactly this document — any version, unsaved edits included — without tracking anything. Nothing is written into the project.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]}},"required":["doc"]}}}},"responses":{"200":{"description":"The token, and the app path that opens it","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"expiresAt":{"type":"string"},"path":{"type":"string"}},"required":["token","expiresAt","path"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/funnel-previews/{token}":{"get":{"tags":["funnels"],"summary":"The funnel a phone-test code stands for","description":"Called by the app in Expo Go. The token is the capability; unknown and expired tokens are a 404.","parameters":[{"schema":{"type":"string","maxLength":64},"required":true,"name":"token","in":"path"}],"responses":{"200":{"description":"The funnel","content":{"application/json":{"schema":{"type":"object","properties":{"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]}},"required":["doc"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/experiments/{expId}":{"get":{"tags":["funnels"],"summary":"One experiment, with fresh numbers","description":"Counted from the app's own events: exposures from `funnel_variant_assigned`, conversions from the goal's last event by the same person afterwards, per-screen drop-off from `onboarding_step`, and revenue from the App Store transactions Apple reports, per currency and never summed across them. `enoughData` is 50 exposures and 5 conversions in every arm, and `callableWinner` is null until `enoughData && significant` — anything else is a lead, not a winner. An experiment nobody has reached yet answers `results: null` with a sentence saying so, never arms tied at zero.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"expId","in":"path"}],"responses":{"200":{"description":"The experiment and its results","content":{"application/json":{"schema":{"type":"object","properties":{"experiment":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]},"results":{"type":"object","nullable":true,"properties":{"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"exposures":{"type":"integer","minimum":0},"conversions":{"type":"integer","minimum":0},"conversionRate":{"type":"number","nullable":true,"minimum":0,"maximum":1},"probability":{"type":"number","nullable":true,"minimum":0,"maximum":1},"credibleInterval":{"type":"array","nullable":true,"items":{"type":"number"},"minItems":2,"maxItems":2},"lift":{"type":"number","nullable":true},"liftInterval":{"type":"array","nullable":true,"items":{"type":"number"},"minItems":2,"maxItems":2}},"required":["key","exposures","conversions","conversionRate","probability"]}},"steps":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"people":{"type":"integer","minimum":0}},"required":["id","people"]}}},"required":["key","screens"]}},"revenue":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"currency":{"type":"string","minLength":3,"maxLength":3},"amountMinor":{"type":"integer","minimum":0},"payers":{"type":"integer","minimum":0}},"required":["key","currency","amountMinor","payers"]}},"significant":{"type":"boolean"},"enoughData":{"type":"boolean"},"minExposures":{"type":"integer","minimum":0},"minConversions":{"type":"integer","minimum":0},"fetchedAt":{"type":"string"}},"required":["variants","significant","enoughData","minExposures","minConversions","fetchedAt"]},"resultsError":{"type":"string","nullable":true},"callableWinner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]}},"required":["experiment","results","resultsError","callableWinner"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/experiments/{expId}/stop":{"post":{"tags":["funnels"],"summary":"End an experiment without promoting anything","description":"Ends the experiment, so the next call to `GET /v1/experiments` serves the funnel the app ships again. Nothing is written into the project: stopping means 'this told us nothing', not 'A won'.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"expId","in":"path"}],"responses":{"200":{"description":"Ended","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/apps/{id}/funnel/experiments/{expId}/promote":{"post":{"tags":["funnels"],"summary":"Ship the winning funnel","description":"Writes the winning design into lib/funnel.json as a new project version, then ends the experiment. **Promoting is a code change** — leaving one arm serving everybody would work, and would leave the project's own record of its onboarding permanently wrong. Refused with 409 `experiment_not_enough_data` until every arm has 50 exposures and 5 conversions, unless `force` is true — which is recorded in the version's message.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"expId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"variant":{"type":"string","enum":["control","test","test_2","test_3"]},"force":{"type":"boolean","default":false},"note":{"type":"string","maxLength":300}},"required":["variant"]}}}},"responses":{"200":{"description":"Promoted, with the version it created","content":{"application/json":{"schema":{"type":"object","properties":{"experiment":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"flagKey":{"type":"string"},"assignedBy":{"type":"string","enum":["broctic","posthog"]},"posthogFlagId":{"type":"integer","nullable":true},"posthogExperimentId":{"type":"integer","nullable":true},"status":{"type":"string","enum":["draft","running","ended","promoted"]},"variants":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80},"doc":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"weight":{"type":"integer","minimum":1,"maximum":100,"default":50},"offeringId":{"type":"string","minLength":1,"maxLength":120}},"required":["key","name","doc"]},"minItems":2,"maxItems":4},"goal":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":2,"maxItems":8}},"required":["events"]},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"winner":{"type":"string","nullable":true,"enum":["control","test","test_2","test_3"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","appId","flagKey","assignedBy","posthogFlagId","posthogExperimentId","status","variants","goal","startedAt","endedAt","winner","createdAt","updatedAt"]},"version":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","minimum":0,"exclusiveMinimum":true},"summary":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","number","summary","createdAt"]}},"required":["experiment","version"]}}}},"400":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Request refused","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/experiments":{"get":{"tags":["experiments"],"summary":"The onboarding funnel this person should see","description":"Called by a shipped app when onboarding starts, authenticated with the app's publishable key in the `x-broctic-key` header. Returns the arm this person is assigned to when a funnel experiment is running, and the funnel the app currently ships when one is not — which is what lets a funnel be edited without an App Store release. Assignment is a hash of the experiment and the person, so it is the same answer on every launch and nothing is stored. Send `anonymousId` (the app's persisted device id) and `userId` when signed in. Honours `If-None-Match`.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":128},"required":false,"name":"anonymousId","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":128},"required":false,"name":"userId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"v","in":"query"}],"responses":{"200":{"description":"The funnel to show, and the arm it came from","content":{"application/json":{"schema":{"type":"object","properties":{"funnel":{"type":"object","properties":{"version":{"type":"number","enum":[2]},"theme":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentText":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"headingFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"bodyFont":{"type":"string","enum":["system","system-serif","poppins","lato","fira-sans","barlow","ibm-plex-serif","ibm-plex-mono","space-mono","dm-serif-display","archivo-black","abril-fatface","bebas-neue","alfa-slab-one","righteous","lobster","pacifico"]},"titleSize":{"type":"integer","minimum":20,"maximum":56},"bodySize":{"type":"integer","minimum":12,"maximum":22},"align":{"type":"string","enum":["left","center"]},"buttonShape":{"type":"string","enum":["rounded","pill","square"]},"buttonStyle":{"type":"string","enum":["filled","outline"]},"progress":{"type":"string","enum":["dots","bar","count","none"]}},"required":["background","text","muted","accent","accentText","surface","headingFont","bodyFont","titleSize","bodySize","align","buttonShape","buttonStyle","progress"]},"screens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"kind":{"type":"string","enum":["welcome","features","question","testimonial","preview","permission","paywall"]},"eyebrow":{"type":"string","maxLength":60},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":400},"cta":{"type":"string","minLength":1,"maxLength":40},"skip":{"type":"string","maxLength":40},"media":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"position":{"type":"string","enum":["top","bottom","background","inline"]},"fit":{"type":"string","enum":["cover","contain"],"default":"cover"},"height":{"type":"number","minimum":0.15,"maximum":0.65,"default":0.4},"radius":{"type":"integer","minimum":0,"maximum":40,"default":20},"alt":{"type":"string","maxLength":160,"default":""}},"required":["type","url","position"]},{"type":"object","properties":{"type":{"type":"string","enum":["icon"]},"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","icon"]},{"type":"object","properties":{"type":{"type":"string","enum":["emoji"]},"emoji":{"type":"string","minLength":1,"maxLength":8},"size":{"type":"integer","minimum":32,"maximum":160,"default":72}},"required":["type","emoji"]}]},"choices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":8}},"required":["id","label"]},"maxItems":8},"multiple":{"type":"boolean"},"bullets":{"type":"array","items":{"type":"object","properties":{"icon":{"type":"string","enum":["sparkles","star","heart","flame","trophy","checkmark-circle","time","calendar","notifications","people","person","chatbubbles","book","musical-notes","fitness","leaf","moon","sunny","cafe","wallet","cash","trending-up","stats-chart","rocket","flash","lock-closed","shield-checkmark","globe","camera","image","gift","ribbon","school","briefcase","home","location","map","restaurant","water","bed","happy","hand-left","bulb","compass","infinite"]},"text":{"type":"string","minLength":1,"maxLength":120}},"required":["icon","text"]},"maxItems":5},"quote":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":280},"author":{"type":"string","minLength":1,"maxLength":80},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["text","author"]},"permission":{"type":"string","enum":["notifications","tracking"]},"style":{"type":"object","properties":{"background":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["color"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","color"]},{"type":"object","properties":{"type":{"type":"string","enum":["gradient"]},"from":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"to":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"angle":{"type":"integer","minimum":0,"maximum":359,"default":0}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":1000,"pattern":"^https:\\/\\/[^\\s\"'<>]+$"},"overlay":{"type":"number","minimum":0,"maximum":0.85,"default":0.35},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["type","url","color"]}]},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"muted":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"titleSize":{"type":"integer","minimum":20,"maximum":56},"align":{"type":"string","enum":["left","center"]}}}},"required":["id","kind","title","cta"]},"minItems":1,"maxItems":8},"placeholder":{"type":"boolean"}},"required":["version","theme","screens"]},"experiment":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"variant":{"type":"string","enum":["control","test","test_2","test_3"]},"name":{"type":"string","minLength":1,"maxLength":80}},"required":["id","variant","name"]},"offeringId":{"type":"string","nullable":true,"minLength":1,"maxLength":120},"etag":{"type":"string"}},"required":["funnel","experiment","offeringId","etag"]}}}},"304":{"description":"Unchanged since the ETag the client holds"},"401":{"description":"Missing or unknown key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"This app has no funnel yet","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/research/categories":{"get":{"tags":["research"],"summary":"Apple's genre tree","parameters":[{"schema":{"type":"string","pattern":"^[a-z]{2}$","default":"us","description":"Two-letter App Store storefront, e.g. us."},"required":false,"name":"country","in":"query"}],"responses":{"200":{"description":"Categories","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string"},"genres":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"subgenres":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"default":[]}},"required":["id","name"]}}},"required":["country","genres"]}}}}}}},"/v1/research/top":{"get":{"tags":["research"],"summary":"Today's ranked chart, enriched","description":"Reads today's cached walk of one (country, genre, feed) chart, building it on a cache miss. Bounded: never fans out per app.","parameters":[{"schema":{"type":"string","pattern":"^[a-z]{2}$","default":"us","description":"Two-letter App Store storefront, e.g. us."},"required":false,"name":"country","in":"query"},{"schema":{"type":"string","pattern":"^(?:\\d{1,10}|all)$"},"required":true,"name":"genreId","in":"query"},{"schema":{"type":"string","enum":["topfree","toppaid","topgrossing","new"]},"required":true,"name":"feed","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"The chart","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string"},"genreId":{"type":"string"},"feed":{"type":"string","enum":["topfree","toppaid","topgrossing","new"]},"day":{"type":"string"},"apps":{"type":"array","items":{"type":"object","properties":{"appleAppId":{"type":"string"},"country":{"type":"string"},"bundleId":{"type":"string","nullable":true},"name":{"type":"string"},"sellerName":{"type":"string","nullable":true},"primaryGenreId":{"type":"string","nullable":true},"genreIds":{"type":"array","items":{"type":"string"}},"price":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"averageUserRating":{"type":"number","nullable":true},"userRatingCount":{"type":"number","nullable":true},"releaseDate":{"type":"string","nullable":true},"currentVersionReleaseDate":{"type":"string","nullable":true},"version":{"type":"string","nullable":true},"iconUrl":{"type":"string","nullable":true},"rank":{"type":"integer","nullable":true},"listingUrl":{"type":"string"}},"required":["appleAppId","country","bundleId","name","sellerName","primaryGenreId","genreIds","price","currency","averageUserRating","userRatingCount","releaseDate","currentVersionReleaseDate","version","iconUrl","rank","listingUrl"]}},"score":{"type":"number","nullable":true},"scoreInputs":{"type":"object","nullable":true,"properties":{"demand":{"type":"number"},"qualityGap":{"type":"number"},"staleness":{"type":"number"},"freshness":{"type":"number"},"saturation":{"type":"number"},"sampleSize":{"type":"integer"},"medianRatingCount":{"type":"number"},"meanRating":{"type":"number"}},"required":["demand","qualityGap","staleness","freshness","saturation","sampleSize","medianRatingCount","meanRating"]},"source":{"type":"string"},"fetchedAt":{"type":"string"}},"required":["country","genreId","feed","day","apps","score","scoreInputs","source","fetchedAt"]}}}},"429":{"description":"Apple rate-limited this walk","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/research/search":{"get":{"tags":["research"],"summary":"Search the App Store","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":200},"required":true,"name":"term","in":"query"},{"schema":{"type":"string","pattern":"^[a-z]{2}$","default":"us","description":"Two-letter App Store storefront, e.g. us."},"required":false,"name":"country","in":"query"},{"schema":{"type":"string","pattern":"^(?:\\d{1,10}|all)$"},"required":false,"name":"genreId","in":"query"}],"responses":{"200":{"description":"Results","content":{"application/json":{"schema":{"type":"object","properties":{"term":{"type":"string"},"country":{"type":"string"},"apps":{"type":"array","items":{"type":"object","properties":{"appleAppId":{"type":"string"},"country":{"type":"string"},"bundleId":{"type":"string","nullable":true},"name":{"type":"string"},"sellerName":{"type":"string","nullable":true},"primaryGenreId":{"type":"string","nullable":true},"genreIds":{"type":"array","items":{"type":"string"}},"price":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"averageUserRating":{"type":"number","nullable":true},"userRatingCount":{"type":"number","nullable":true},"releaseDate":{"type":"string","nullable":true},"currentVersionReleaseDate":{"type":"string","nullable":true},"version":{"type":"string","nullable":true},"iconUrl":{"type":"string","nullable":true},"rank":{"type":"integer","nullable":true},"listingUrl":{"type":"string"}},"required":["appleAppId","country","bundleId","name","sellerName","primaryGenreId","genreIds","price","currency","averageUserRating","userRatingCount","releaseDate","currentVersionReleaseDate","version","iconUrl","rank","listingUrl"]}}},"required":["term","country","apps"]}}}}}}},"/v1/research/apps/{appleAppId}":{"get":{"tags":["research"],"summary":"One app's public listing, and its reviews on request","parameters":[{"schema":{"type":"string","pattern":"^\\d{5,20}$"},"required":true,"name":"appleAppId","in":"path"},{"schema":{"type":"string","pattern":"^[a-z]{2}$","default":"us","description":"Two-letter App Store storefront, e.g. us."},"required":false,"name":"country","in":"query"},{"schema":{"type":"boolean","nullable":true},"required":false,"name":"reviews","in":"query"}],"responses":{"200":{"description":"The app","content":{"application/json":{"schema":{"type":"object","properties":{"appleAppId":{"type":"string"},"country":{"type":"string"},"bundleId":{"type":"string","nullable":true},"name":{"type":"string"},"sellerName":{"type":"string","nullable":true},"primaryGenreId":{"type":"string","nullable":true},"genreIds":{"type":"array","items":{"type":"string"}},"price":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"averageUserRating":{"type":"number","nullable":true},"userRatingCount":{"type":"number","nullable":true},"releaseDate":{"type":"string","nullable":true},"currentVersionReleaseDate":{"type":"string","nullable":true},"version":{"type":"string","nullable":true},"iconUrl":{"type":"string","nullable":true},"rank":{"type":"integer","nullable":true},"listingUrl":{"type":"string"},"reviews":{"type":"array","items":{"type":"object","properties":{"rating":{"type":"integer","minimum":1,"maximum":5},"title":{"type":"string"},"body":{"type":"string"},"version":{"type":"string","nullable":true},"at":{"type":"string","nullable":true}},"required":["rating","title","body","version","at"]}},"reviewsFetchedAt":{"type":"string","nullable":true}},"required":["appleAppId","country","bundleId","name","sellerName","primaryGenreId","genreIds","price","currency","averageUserRating","userRatingCount","releaseDate","currentVersionReleaseDate","version","iconUrl","rank","listingUrl"]}}}},"404":{"description":"No public listing","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/research/ideas":{"get":{"tags":["research"],"summary":"The organization's ideas","parameters":[{"schema":{"type":"string","enum":["new","shortlisted","building","built","dismissed"]},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Ideas, newest first","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"title":{"type":"string"},"pitch":{"type":"string"},"country":{"type":"string"},"genreId":{"type":"string"},"evidence":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["app","review","snapshot"]},"url":{"type":"string","minLength":1,"maxLength":2000},"note":{"type":"string","maxLength":2000}},"required":["kind","url"]}},"score":{"type":"number","nullable":true},"scoreInputs":{"type":"object","nullable":true,"properties":{"demand":{"type":"number"},"qualityGap":{"type":"number"},"staleness":{"type":"number"},"freshness":{"type":"number"},"saturation":{"type":"number"},"sampleSize":{"type":"integer"},"medianRatingCount":{"type":"number"},"meanRating":{"type":"number"}},"required":["demand","qualityGap","staleness","freshness","saturation","sampleSize","medianRatingCount","meanRating"]},"status":{"type":"string","enum":["new","shortlisted","building","built","dismissed"]},"appId":{"type":"string","nullable":true},"dismissedReason":{"type":"string","nullable":true},"createdBy":{"type":"string","enum":["human","ai"]},"createdByUserId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","orgId","title","pitch","country","genreId","evidence","score","scoreInputs","status","appId","dismissedReason","createdBy","createdByUserId","createdAt","updatedAt"]}}}}}}},"post":{"tags":["research"],"summary":"Add an idea","description":"Returns any dedupe warnings alongside the created idea — never silently rejected or accepted.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"pitch":{"type":"string","minLength":1,"maxLength":4000},"country":{"type":"string","pattern":"^[a-z]{2}$"},"genreId":{"type":"string","pattern":"^(?:\\d{1,10}|all)$"},"evidence":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["app","review","snapshot"]},"url":{"type":"string","minLength":1,"maxLength":2000},"note":{"type":"string","maxLength":2000}},"required":["kind","url"]},"minItems":1},"score":{"type":"number","nullable":true},"scoreInputs":{"type":"object","nullable":true,"properties":{"demand":{"type":"number"},"qualityGap":{"type":"number"},"staleness":{"type":"number"},"freshness":{"type":"number"},"saturation":{"type":"number"},"sampleSize":{"type":"integer"},"medianRatingCount":{"type":"number"},"meanRating":{"type":"number"}},"required":["demand","qualityGap","staleness","freshness","saturation","sampleSize","medianRatingCount","meanRating"]},"appleAppId":{"type":"string","pattern":"^\\d{5,20}$"},"bundleId":{"type":"string","minLength":1,"maxLength":200}},"required":["title","pitch","country","genreId","evidence"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"idea":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"title":{"type":"string"},"pitch":{"type":"string"},"country":{"type":"string"},"genreId":{"type":"string"},"evidence":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["app","review","snapshot"]},"url":{"type":"string","minLength":1,"maxLength":2000},"note":{"type":"string","maxLength":2000}},"required":["kind","url"]}},"score":{"type":"number","nullable":true},"scoreInputs":{"type":"object","nullable":true,"properties":{"demand":{"type":"number"},"qualityGap":{"type":"number"},"staleness":{"type":"number"},"freshness":{"type":"number"},"saturation":{"type":"number"},"sampleSize":{"type":"integer"},"medianRatingCount":{"type":"number"},"meanRating":{"type":"number"}},"required":["demand","qualityGap","staleness","freshness","saturation","sampleSize","medianRatingCount","meanRating"]},"status":{"type":"string","enum":["new","shortlisted","building","built","dismissed"]},"appId":{"type":"string","nullable":true},"dismissedReason":{"type":"string","nullable":true},"createdBy":{"type":"string","enum":["human","ai"]},"createdByUserId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","orgId","title","pitch","country","genreId","evidence","score","scoreInputs","status","appId","dismissedReason","createdBy","createdByUserId","createdAt","updatedAt"]},"dedupeWarnings":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["bundle_id","name_similarity","prior_idea"]},"similarity":{"type":"number","nullable":true},"appId":{"type":"string","nullable":true},"ideaId":{"type":"string","nullable":true},"name":{"type":"string"},"detail":{"type":"string"}},"required":["kind","similarity","appId","ideaId","name","detail"]}}},"required":["idea","dedupeWarnings"]}}}}}}},"/v1/research/ideas/{id}":{"patch":{"tags":["research"],"summary":"Update an idea's status, pitch, app link or dismissal reason","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["new","shortlisted","building","built","dismissed"]},"pitch":{"type":"string","minLength":1,"maxLength":4000},"appId":{"type":"string","nullable":true},"dismissedReason":{"type":"string","nullable":true,"maxLength":2000}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"title":{"type":"string"},"pitch":{"type":"string"},"country":{"type":"string"},"genreId":{"type":"string"},"evidence":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["app","review","snapshot"]},"url":{"type":"string","minLength":1,"maxLength":2000},"note":{"type":"string","maxLength":2000}},"required":["kind","url"]}},"score":{"type":"number","nullable":true},"scoreInputs":{"type":"object","nullable":true,"properties":{"demand":{"type":"number"},"qualityGap":{"type":"number"},"staleness":{"type":"number"},"freshness":{"type":"number"},"saturation":{"type":"number"},"sampleSize":{"type":"integer"},"medianRatingCount":{"type":"number"},"meanRating":{"type":"number"}},"required":["demand","qualityGap","staleness","freshness","saturation","sampleSize","medianRatingCount","meanRating"]},"status":{"type":"string","enum":["new","shortlisted","building","built","dismissed"]},"appId":{"type":"string","nullable":true},"dismissedReason":{"type":"string","nullable":true},"createdBy":{"type":"string","enum":["human","ai"]},"createdByUserId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","orgId","title","pitch","country","genreId","evidence","score","scoreInputs","status","appId","dismissedReason","createdBy","createdByUserId","createdAt","updatedAt"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/research/ideas/{id}/build":{"post":{"tags":["research"],"summary":"Turn an idea into a Broctic app + Studio project","description":"Sets status to building and stamps appId. `built` is not set automatically — a human or the founder's Claude confirms the build shipped and sets it with PATCH.","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Building","content":{"application/json":{"schema":{"type":"object","properties":{"idea":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"title":{"type":"string"},"pitch":{"type":"string"},"country":{"type":"string"},"genreId":{"type":"string"},"evidence":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["app","review","snapshot"]},"url":{"type":"string","minLength":1,"maxLength":2000},"note":{"type":"string","maxLength":2000}},"required":["kind","url"]}},"score":{"type":"number","nullable":true},"scoreInputs":{"type":"object","nullable":true,"properties":{"demand":{"type":"number"},"qualityGap":{"type":"number"},"staleness":{"type":"number"},"freshness":{"type":"number"},"saturation":{"type":"number"},"sampleSize":{"type":"integer"},"medianRatingCount":{"type":"number"},"meanRating":{"type":"number"}},"required":["demand","qualityGap","staleness","freshness","saturation","sampleSize","medianRatingCount","meanRating"]},"status":{"type":"string","enum":["new","shortlisted","building","built","dismissed"]},"appId":{"type":"string","nullable":true},"dismissedReason":{"type":"string","nullable":true},"createdBy":{"type":"string","enum":["human","ai"]},"createdByUserId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","orgId","title","pitch","country","genreId","evidence","score","scoreInputs","status","appId","dismissedReason","createdBy","createdByUserId","createdAt","updatedAt"]},"appId":{"type":"string"}},"required":["idea","appId"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Already building or built","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"The Studio is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/setup":{"get":{"tags":["setup"],"summary":"What this organization still has to do","description":"Every step is derived from stored data rather than from a flag, so it cannot report finished for something that is not.","responses":{"200":{"description":"Setup state","content":{"application/json":{"schema":{"type":"object","properties":{"next":{"type":"string","enum":["connect_apple","import_app","create_key","link_posthog","create_funnel","done"]},"appleConnected":{"type":"boolean"},"appleError":{"type":"string","nullable":true},"hasStoreData":{"type":"boolean"},"apps":{"type":"integer","minimum":0},"importedApps":{"type":"integer","minimum":0},"appsWithKey":{"type":"integer","minimum":0},"appsSendingEvents":{"type":"integer","minimum":0},"appsWithPostHog":{"type":"integer","minimum":0},"appsWithFunnel":{"type":"integer","minimum":0},"lastEventAt":{"type":"string","nullable":true},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["connect_apple","import_app","create_key","link_posthog","create_funnel","done"]},"title":{"type":"string"},"done":{"type":"boolean"}},"required":["step","title","done"]}}},"required":["next","appleConnected","appleError","hasStoreData","apps","importedApps","appsWithKey","appsSendingEvents","appsWithPostHog","appsWithFunnel","lastEventAt","steps"]}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}}}}