{"openapi":"3.1.0","info":{"title":"WTN Partner Channel API","version":"0.9.11","description":"Provision a survey, attach an audience, launch, and read results — from your own systems. Full integration guide: PARTNER_INTEGRATION.md. Every POST is idempotent when you send an `Idempotency-Key`; every route is metered per key; every denial uses one class-code catalog.","contact":{"name":"xAverage Technologies","email":"dev@xaverage.com"}},"servers":[{"url":"/api/v1/channel","description":"This gateway"}],"security":[{"bearerApiKey":[]}],"webhooks":{"feedback.received":{"post":{"summary":"A respondent finished a feedback session. Signed like every webhook (see the webhook guide).","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackReceivedEvent"}}}},"responses":{"2XX":{"description":"Acknowledge with any 2xx; anything else is retried with backoff."}}}},"feedback.analyzed":{"post":{"summary":"The analysis of a finished session completed (once per session).","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackAnalyzedEvent"}}}},"responses":{"2XX":{"description":"Acknowledge with any 2xx; anything else is retried with backoff."}}}}},"components":{"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"wtn_<prefix>_<secret>","description":"Send your API key as `Authorization: Bearer wtn_…`. `X-API-Key: wtn_…` is accepted identically."},"studioJwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A signed-in Studio/Admin session token. Used only by the launch-key and install-list routes that a person manages from Studio; the permission each needs is named on the route."}},"schemas":{"ChannelWhoamiResponse":{"type":"object","properties":{"serviceAccountId":{"type":"string","format":"uuid"},"accountId":{"type":["string","null"],"format":"uuid"},"scopes":{"type":"array","items":{"type":"string"}},"keyPrefix":{"type":"string"},"workspaceAllowlist":{"type":"array","items":{"type":"string","format":"uuid"}},"defaultWorkspaceId":{"type":["string","null"],"format":"uuid"},"orgId":{"type":["string","null"],"format":"uuid","deprecated":true}}},"ChannelWorkspaceSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"externalRef":{"type":["string","null"],"description":"Your own id for this workspace, if you created it."},"createdAt":{"type":"string","format":"date-time"}}},"ChannelWorkspaceCreateRequest":{"type":"object","additionalProperties":false,"required":["externalRef","name"],"properties":{"externalRef":{"type":"string","minLength":1,"maxLength":200,"description":"Your own stable id for this client. The same ref always means the same workspace."},"name":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["INDIVIDUAL","COMPANY","PARTNERSHIP","GOVERNMENT","EDUCATIONAL","OTHER"],"default":"COMPANY"},"team":{"type":"string","maxLength":120},"location":{"type":"string","maxLength":120}}},"ChannelWorkspaceCreateResponse":{"type":"object","properties":{"workspace":{"$ref":"#/components/schemas/ChannelWorkspaceSummary"},"created":{"type":"boolean","description":"False when the ref already named this workspace (a replay)."}}},"ChannelWorkspaceListResponse":{"type":"object","properties":{"workspaces":{"type":"array","items":{"$ref":"#/components/schemas/ChannelWorkspaceSummary"}},"total":{"type":"integer"},"defaultWorkspaceId":{"type":["string","null"],"format":"uuid"}}},"ProvisionRequest":{"type":"object","description":"Send EITHER `brief` OR `surveyId` — exactly one.","properties":{"brief":{"type":"object","properties":{"intentText":{"type":"string","minLength":10,"maxLength":4000},"constraints":{"type":"object","properties":{"questionCount":{"type":"integer","minimum":1,"maximum":50},"languages":{"type":"array","items":{"type":"string"},"maxItems":20},"tone":{"type":"string","maxLength":120},"bannedTopics":{"type":"array","items":{"type":"string"},"maxItems":50}}}}},"surveyId":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120},"quality":{"type":"object","properties":{"targetCount":{"type":"integer","minimum":1},"maxResponses":{"type":"integer","minimum":1},"minDurationSecs":{"type":"integer","minimum":0},"minCoverageRatio":{"type":"number","minimum":0,"maximum":1},"minAnswerWords":{"type":"integer","minimum":0}}},"delivery":{"type":"object","properties":{"channels":{"type":"array","items":{"enum":["EMAIL","WHATSAPP","SMS","TELEPHONY"]}},"reminderCount":{"type":"integer","minimum":0,"maximum":4},"audioRetentionDays":{"type":"integer","minimum":1,"maximum":90},"greetByName":{"type":"boolean"}}},"order":{"type":"object","properties":{"packageType":{"type":"string"},"quotedPriceInr":{"type":"integer","minimum":0},"acceptedResponsesCommitted":{"type":"integer","minimum":1}}}}},"LaunchRequest":{"type":"object","required":["campaignId"],"additionalProperties":false,"properties":{"campaignId":{"type":"string","format":"uuid"},"externalUserRef":{"type":"string","maxLength":200,"description":"Your own id for the person. Stored only as a keyed hash, never raw."},"language":{"type":"string","minLength":2,"maxLength":24,"description":"The session language (a language code such as `en`, `ar`). It rides on the link as `?lang=`; a language the campaign does not offer falls back to the campaign default, never an error."},"device":{"type":"object","additionalProperties":false,"description":"Short labels (at most 64 characters each).","properties":{"platform":{"type":"string"},"osName":{"type":"string"},"osVersion":{"type":"string"},"deviceVendor":{"type":"string"},"deviceModel":{"type":"string"},"browserName":{"type":"string"},"browserVersion":{"type":"string"},"appId":{"type":"string"},"appVersion":{"type":"string"},"appBuild":{"type":"string"},"sdkVersion":{"type":"string"},"locale":{"type":"string"},"timezone":{"type":"string"},"networkType":{"type":"string"}}},"attributes":{"type":"object","description":"At most 64 keys and 8 KB of JSON; values are strings, numbers or booleans only.","additionalProperties":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}}}},"LaunchResponse":{"type":"object","required":["url","expiresAt"],"properties":{"url":{"type":"string","description":"Open this in a Custom Tab / SFSafariViewController. Single use."},"expiresAt":{"type":"string","format":"date-time"}}},"AudienceRequest":{"type":"object","required":["rows"],"properties":{"rows":{"type":"array","minItems":1,"items":{"type":"object","required":["externalRef"],"properties":{"externalRef":{"type":"string","minLength":1,"maxLength":200},"name":{"type":"string","maxLength":200},"email":{"type":"string","format":"email"},"phone":{"type":"string","maxLength":32}}}}}},"WebhookSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"description":{"type":["string","null"]},"eventTypes":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"disabledAt":{"type":["string","null"],"format":"date-time"},"disabledReason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}},"AppRegisterRequest":{"type":"object","required":["campaignCode","appId","platform","appVersion"],"properties":{"campaignCode":{"type":"string","description":"The campaign's public code (the `<code>` in `/p/<code>`)."},"appId":{"type":"string","maxLength":128,"description":"Your bundle id / package name."},"platform":{"type":"string","enum":["ios","android","web","other"]},"appVersion":{"type":"string","maxLength":32},"deviceModel":{"type":"string","maxLength":64},"osVersion":{"type":"string","maxLength":32},"locale":{"type":"string","maxLength":24,"description":"BCP-47 tag of the app UI language."},"language":{"type":"string","maxLength":24,"description":"The session language; used when `locale` is not sent."},"deviceId":{"type":"string","format":"uuid","description":"The `deviceId` this app was given before. Honoured ONLY together with `refreshToken`; an id alone is ignored."},"refreshToken":{"type":"string","description":"The secret that proves the app owns `deviceId`."},"vendorDeviceId":{"type":"string","maxLength":128,"description":"An id the app persists across re-installs (IDFV / ANDROID_ID): finds the same device again."},"user":{"type":"object","description":"Who is using the app. Without it the device is `anonymous`.","properties":{"externalId":{"type":"string","maxLength":128,"description":"Your own user id."},"email":{"type":"string","format":"email","description":"Stored encrypted, never returned."},"phone":{"type":"string","description":"E.164, e.g. `+919876543210`. Stored encrypted, never returned."},"userHash":{"type":"string","description":"Hex HMAC-SHA256 of `externalId` keyed with an active launch-key secret of the campaign. Marks the user `verified`; a wrong one is `401 USER_HASH_INVALID`."}}},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":256},"description":"Flat string labels of your own, at most 32 keys and 2 KB."}}},"AppRegisterResponse":{"type":"object","properties":{"deviceId":{"type":"string","format":"uuid","description":"One install of the app, server-issued. Store it."},"userId":{"type":["string","null"],"format":"uuid","description":"The person, when `user` was sent."},"identity":{"type":"string","enum":["anonymous","self_declared","verified"]},"accessToken":{"type":"string","description":"Open the feedback page with `#dt=<accessToken>` (the fragment, never the query). Short-lived."},"accessTokenExpiresAt":{"type":"string","format":"date-time"},"refreshToken":{"type":"string","description":"Secret; store it with `deviceId`. Every register issues a new one and the old one stops working."},"refreshTokenExpiresAt":{"type":"string","format":"date-time"},"installId":{"type":"string","description":"v1: signed, opaque. Send it as `?inst=` on the link and on v1 heartbeats."},"heartbeatIntervalSecs":{"type":"integer"},"expiresAt":{"type":"string","format":"date-time","description":"v1: when `installId` expires."}}},"AppHeartbeatRequest":{"type":"object","description":"v2: `deviceId` + `refreshToken`. v1: `installId` + `appVersion`.","properties":{"deviceId":{"type":"string","format":"uuid"},"refreshToken":{"type":"string"},"installId":{"type":"string"},"appVersion":{"type":"string","maxLength":32},"osVersion":{"type":"string","maxLength":32},"locale":{"type":"string","maxLength":24}}},"AppHeartbeatResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"heartbeatIntervalSecs":{"type":"integer"},"accessToken":{"type":"string","description":"v2: a fresh access token on every call."},"accessTokenExpiresAt":{"type":"string","format":"date-time"},"refreshTokenExpiresAt":{"type":"string","format":"date-time"},"installId":{"type":"string","description":"v1: present only when the id is close to expiry: store this one instead. v2: the device install id."},"expiresAt":{"type":"string","format":"date-time"}}},"AppDevice":{"type":"object","description":"One app device. Never carries an email or a phone, only whether one is on file.","properties":{"deviceId":{"type":"string","format":"uuid"},"userId":{"type":["string","null"],"format":"uuid"},"identity":{"type":"string","enum":["anonymous","self_declared","verified"]},"hasEmail":{"type":"boolean"},"hasPhone":{"type":"boolean"},"appId":{"type":"string"},"platform":{"type":"string","enum":["ios","android","web","other"]},"appVersion":{"type":"string"},"deviceModel":{"type":["string","null"]},"osVersion":{"type":["string","null"]},"locale":{"type":["string","null"]},"metadata":{"type":["object","null"],"additionalProperties":{"type":"string"}},"status":{"type":"string","enum":["ACTIVE","BLOCKED"]},"firstSeenAt":{"type":"string","format":"date-time"},"lastSeenAt":{"type":"string","format":"date-time"},"heartbeatCount":{"type":"integer"},"feedbackCount":{"type":"integer","description":"Feedback sessions started from this device."},"sessionCount":{"type":"integer","description":"App sessions: a heartbeat or register after the last-seen window."},"recentSessions":{"type":"array","items":{"type":"string","format":"date-time"},"description":"Times of the newest app sessions, newest first."}}},"AppDevicePage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AppDevice"}},"nextCursor":{"type":["string","null"],"description":"Pass back as `?cursor=` until null."}}},"AppInstall":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"},"appId":{"type":"string"},"platform":{"type":"string","enum":["ios","android","web","other"]},"appVersion":{"type":"string"},"deviceModel":{"type":["string","null"]},"osVersion":{"type":["string","null"]},"locale":{"type":["string","null"]},"status":{"type":"string","enum":["ACTIVE","BLOCKED"]},"firstSeenAt":{"type":"string","format":"date-time"},"lastSeenAt":{"type":"string","format":"date-time"},"heartbeatCount":{"type":"integer"},"sessionCount":{"type":"integer"},"deviceId":{"type":["string","null"],"format":"uuid"},"userId":{"type":["string","null"],"format":"uuid"},"identity":{"type":"string","enum":["anonymous","self_declared","verified"]},"hasEmail":{"type":"boolean"},"hasPhone":{"type":"boolean"},"feedbackCount":{"type":"integer"},"recentSessions":{"type":"array","items":{"type":"string","format":"date-time"}},"appSessionCount":{"type":"integer"}}},"AppInstallPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AppInstall"}},"nextCursor":{"type":["string","null"],"description":"Pass back as `?cursor=` until null."}}},"PulseStartRequest":{"type":"object","description":"The integration-relevant fields of the public start. Consent fields are the respondent page's own.","properties":{"consentGiven":{"type":"boolean","description":"Required `true`: nothing is created without consent."},"language":{"type":"string","maxLength":24},"installId":{"type":"string","description":"The signed install id from `?inst=`."},"deviceToken":{"type":"string","maxLength":1024,"description":"The app device access token from the page fragment `#dt=`. A valid one attributes the feedback to its device and person; a bad or expired one is ignored (the feedback stays anonymous)."},"launchToken":{"type":"string","maxLength":4096,"description":"The signed launch token from `?lt=` (JWT HS256, see `/campaigns/{campaignId}/launch-keys`). Verified and used up here; a campaign that requires signing refuses a start without a valid one (`LAUNCH_SIGNATURE_REQUIRED` / `LAUNCH_TOKEN_INVALID`, 403)."},"client":{"type":"object","additionalProperties":{"type":["string","number","boolean"]},"description":"Short device/app labels; unreadable values are ignored."}}},"LaunchAccessState":{"type":"object","properties":{"requireSigned":{"type":"boolean"},"state":{"type":"string","enum":["NOT_REQUIRED","VALID","MISSING","INVALID"]},"refusal":{"type":["object","null"],"properties":{"code":{"type":"string","enum":["LAUNCH_SIGNATURE_REQUIRED","LAUNCH_TOKEN_INVALID"]},"title":{"type":"string"},"description":{"type":"string"}}},"language":{"type":["string","null"]}}},"LaunchKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Also the JWT header `kid`."},"slot":{"type":"integer","enum":[1,2]},"fingerprint":{"type":"string","description":"First 8 hex of SHA-256(secret)."},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"secret":{"type":["string","null"],"description":"Returned ONCE, on creation. `null` on a replay and on every read."},"kid":{"type":"string"}}},"LaunchKeyList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LaunchKey"}},"requireSigned":{"type":"boolean"}}},"FeedbackReceivedEvent":{"type":"object","description":"Webhook `feedback.received` — a respondent finished a session. Ids and counts only, never a word they said.","properties":{"conversationId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"},"publicRef":{"type":"string"},"appInstallId":{"type":["string","null"],"format":"uuid"},"answered":{"type":"integer"},"total":{"type":"integer"}}},"FeedbackAnalyzedEvent":{"type":"object","description":"Webhook `feedback.analyzed` — the analysis of a finished session completed (sent once per session). Ids and counts only.","properties":{"conversationId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"},"publicRef":{"type":["string","null"]},"appInstallId":{"type":["string","null"],"format":"uuid"},"answers":{"type":"integer"},"exchanges":{"type":"integer"},"analyzersRun":{"type":"integer"},"analyzersReused":{"type":"integer"}}},"WebhookCreateRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"https:// only; must resolve to a public address."},"description":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"},"description":"Empty or omitted = every event for this workspace. Events: `respondent.acknowledged`, `feedback.received`, `feedback.analyzed` (payloads under `webhooks` in this document)."}}},"WebhookCreateResponse":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/WebhookSubscription"},"secret":{"type":"string","description":"The HMAC signing secret — shown ONCE. There is no read-back endpoint."}}},"WebhookUpdateRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":["string","null"]},"eventTypes":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid"},"eventType":{"type":"string"},"status":{"enum":["PENDING","DELIVERED","FAILED","DEAD"]},"attempts":{"type":"integer"},"nextAttemptAt":{"type":["string","null"],"format":"date-time"},"lastStatusCode":{"type":["integer","null"]},"lastError":{"type":["string","null"]},"occurredAt":{"type":"string","format":"date-time"},"deliveredAt":{"type":["string","null"],"format":"date-time"}}},"Error":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}},"paths":{"/whoami":{"get":{"tags":["identity"],"summary":"The calling key's own identity — the first call any integration makes.","security":[{"bearerApiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWhoamiResponse"}}}},"401":{"description":"No key, or the key is invalid/revoked/expired.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/orgs":{"get":{"tags":["identity"],"summary":"Which workspaces this key may act on.","security":[{"bearerApiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWorkspaceListResponse"}}}},"403":{"description":"The key has no business (NO_ORG).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Hourly workspaces quota exhausted.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}},"post":{"tags":["identity"],"summary":"Create the workspace for one of your own clients, idempotent on your `externalRef` (scope `channel:workspaces`).","description":"The workspace joins your business and starts PENDING_APPROVAL — a WTN reviewer approves it before a campaign can launch. The creating key may name it in `X-WTN-Workspace` straight away; other keys are not widened. Replaying the same ref with the same details answers 200 with the same workspace; the same ref with different details is refused 409.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWorkspaceCreateRequest"}}}},"responses":{"200":{"description":"The ref already named this workspace with the same details (a replay).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWorkspaceCreateResponse"}}}},"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWorkspaceCreateResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"403":{"description":"The key lacks `channel:workspaces`, or has no business (NO_ORG).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"409":{"description":"The ref exists with different details, or an Idempotency-Key conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Hourly workspace-creation quota, or the business workspace limit, exhausted.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns":{"post":{"tags":["campaigns"],"summary":"Provision a campaign — generate or reuse a survey, publish it, create the campaign.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionRequest"}}}},"responses":{"201":{"description":"Created"},"400":{"description":"Validation failed, or neither/both of `brief`/`surveyId` were sent.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown or foreign workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"409":{"description":"Idempotency-Key conflict (different body, or a request already in flight).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Hourly provision quota exhausted.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/launch":{"post":{"tags":["sessions"],"summary":"Mint a one-time link for one respondent session, carrying your own context (scope `sessions:launch`).","security":[{"bearerApiKey":[]}],"parameters":[{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchRequest"}}}},"responses":{"201":{"description":"Created. The link works once and expires in about 10 minutes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchResponse"}}}},"400":{"description":"Oversized or malformed context: attributes over 64 keys or 8 KB, non-primitive values.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"403":{"description":"The key lacks the `sessions:launch` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign, or one in another workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"409":{"description":"The campaign is not collecting yet.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Hourly launch quota exhausted.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{id}/respondents":{"post":{"tags":["campaigns"],"summary":"Attach an audience by your own externalRef; get invitation links back.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceRequest"}}}},"responses":{"200":{"description":"OK — one outcome per input row."},"400":{"description":"Validation failed, or too many rows.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign, or a foreign workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Hourly audience quota exhausted.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{id}/launch":{"post":{"tags":["campaigns"],"summary":"Go live. Refusals name the exact readiness blocker.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"OK"},"400":{"description":"Not launch-ready — the description names the blocker.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign, or a foreign workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{id}":{"get":{"tags":["campaigns"],"summary":"Status, readiness and counts.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Unknown campaign, or a foreign workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{id}/results":{"get":{"tags":["campaigns"],"summary":"The per-campaign aggregate results projection. Never per-person.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Unknown campaign, or a foreign workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{id}/exports":{"post":{"tags":["exports"],"summary":"Request the campaign’s open-tier export as JSON or PDF (scope `channel:export`; verbatim answers also need `channel:transcripts`, JSON only).","description":"The file is the documented open schema `wtn.partner-export.v1`: study honesty block, funnel, per-question scores, themes and narrative. WTN-exclusive components (signature visualisations, cross-attribution, the composite integrity/attrition index) are NOT included; the document lists them under `exclusions`. No raw respondent PII, ever.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["format"],"additionalProperties":false,"properties":{"format":{"type":"string","enum":["json","pdf"]},"includeTranscripts":{"type":"boolean","description":"JSON only; needs `channel:transcripts`."}}}}}},"responses":{"202":{"description":"Queued. Poll `GET /exports/{id}` for the signed download link."},"400":{"description":"Validation failed, or transcripts were requested for a PDF.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"403":{"description":"The key lacks `channel:export` (or `channel:transcripts` for transcripts).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign, or a foreign workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Hourly export quota exhausted.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"503":{"description":"The export worker or the PDF renderer is not available.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/exports/{id}":{"get":{"tags":["exports"],"summary":"An export’s status; READY carries a fresh signed download link (scope `channel:export`).","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK. Status is QUEUED, RUNNING, READY, FAILED or EXPIRED."},"404":{"description":"Unknown export, or another workspace’s.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/downloads/{token}/{filename}":{"get":{"tags":["exports"],"summary":"Download an export file. No key: the signed link is the capability, and it expires.","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The file (`application/json` or `application/pdf`)."},"404":{"description":"The link is expired, tampered with, or its key was revoked (one answer for all).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"This link was fetched too often this hour.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/webhooks":{"get":{"tags":["webhooks"],"summary":"This workspace's webhook subscriptions. Never includes the signing secret.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateResponse"}}}}}},"post":{"tags":["webhooks"],"summary":"Register a webhook endpoint. The response carries the signing secret ONCE.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateRequest"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateResponse"}}}},"400":{"description":"The URL failed the SSRF check, or an unknown event type was named.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/webhooks/{id}":{"get":{"tags":["webhooks"],"summary":"One subscription.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Unknown subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}},"patch":{"tags":["webhooks"],"summary":"Update the URL, description, event filter, or active state.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdateRequest"}}}},"responses":{"200":{"description":"OK"},"404":{"description":"Unknown subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}},"delete":{"tags":["webhooks"],"summary":"Remove a subscription. Its delivery trail is deleted with it.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Unknown subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/webhooks/{id}/simulate":{"post":{"tags":["webhooks"],"summary":"Send a synthetic `webhook.test` delivery — prove your endpoint and signature check before a real campaign depends on them.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"404":{"description":"Unknown subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/webhooks/{id}/deliveries":{"get":{"tags":["webhooks"],"summary":"This subscription's delivery trail — keyset-paged.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Unknown subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{id}/installs":{"get":{"tags":["apps"],"summary":"App installs registered against a campaign, cursor-paged (scope `channel:results`).","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppInstallPage"}}}},"400":{"description":"A tampered or unreadable cursor.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign, or one in another workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/devices":{"get":{"tags":["apps"],"summary":"The workspace's app devices (identity v2), cursor-paged (scope `channel:results`). No email or phone.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"X-WTN-Workspace","in":"header","required":false,"description":"Which workspace this call acts on. Optional only when the key can reach exactly one workspace (see GET /whoami). Required, and refused with WORKSPACE_REQUIRED, when it can reach more than one.","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"appId","in":"query","schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppDevicePage"}}}},"400":{"description":"A tampered or unreadable cursor.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/apps/register":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"post":{"tags":["apps"],"summary":"An app registers itself against a campaign public code and gets a signed install id (no account, no secret).","security":[],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppRegisterRequest"}}}},"responses":{"200":{"description":"Replay of the same Idempotency-Key: the SAME install id (header `Idempotency-Replayed: true`)."},"201":{"description":"Registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppRegisterResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"401":{"description":"`USER_HASH_INVALID`: the userHash did not verify, or a verified user was addressed without one.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"403":{"description":"`INSTALL_BLOCKED`: this device was blocked by the workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign code.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"409":{"description":"The campaign is not collecting yet, or an Idempotency-Key conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"This network registered too many installs this hour.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/apps/heartbeat":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"post":{"tags":["apps"],"summary":"An app says it is alive. v2 (`deviceId` + `refreshToken`) returns a fresh access token on every call and works with an expired one; v1 (`installId`) returns a fresh install id late in its life.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHeartbeatRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppHeartbeatResponse"}}}},"401":{"description":"`INSTALL_INVALID` (v1: the install id is forged, expired, another campaign's, unknown or blocked) or `DEVICE_AUTH_INVALID` (v2: unknown device, wrong, expired or revoked refresh token — call register again).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"This install or device heartbeats too often.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/public/pulse/{code}/access":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"get":{"tags":["launch"],"summary":"What the page should show for this visit (read-only: a valid signed token is NOT used up).","security":[],"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"lt","in":"query","schema":{"type":"string","maxLength":4096},"description":"The signed launch token from the link."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchAccessState"}}}},"404":{"description":"Unknown topic.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"This network checked too many links this hour.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/public/pulse/{code}/start":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"post":{"tags":["launch"],"summary":"Start a session on an Open Pulse campaign (the respondent page calls this; integration fields documented).","security":[],"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PulseStartRequest"}}}},"responses":{"200":{"description":"Nothing created: the campaign is not open, consent or a site is still needed."},"201":{"description":"A session was created."},"403":{"description":"`LAUNCH_SIGNATURE_REQUIRED` / `LAUNCH_TOKEN_INVALID` on a signed-only campaign, or a challenge is required.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"429":{"description":"Too many attempts, or responses are paused for this campaign.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{campaignId}/launch-keys":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"get":{"tags":["launch"],"summary":"The campaign's launch keys (never the secret) and whether signing is required (Studio session, `campaign:view`).","security":[{"studioJwt":[]}],"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchKeyList"}}}},"404":{"description":"Unknown campaign, or one in another workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}},"post":{"tags":["launch"],"summary":"Create the next launch key (Studio session, `campaign:build`). The secret is returned ONCE. Rotation = create, switch the app, revoke the old.","security":[{"studioJwt":[]}],"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"An opaque string that makes this POST replay-safe for 24 hours. The same key with a different body is refused (CONFLICT); the same key with the same body replays the original response.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Replay of the same Idempotency-Key: the same key, `secret: null`."},"201":{"description":"Created, with the secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchKey"}}}},"403":{"description":"The session lacks `campaign:build`.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"404":{"description":"Unknown campaign, or one in another workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}},"409":{"description":"Both key slots are in use: revoke one first.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{campaignId}/launch-keys/{keyId}":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"delete":{"tags":["launch"],"summary":"Revoke a launch key at once (Studio session, `campaign:build`).","security":[{"studioJwt":[]}],"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Revoked."},"404":{"description":"Unknown key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{campaignId}/launch-access":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"put":{"tags":["launch"],"summary":"Require (or stop requiring) a signed launch for this campaign (Studio session, `campaign:build`).","security":[{"studioJwt":[]}],"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requireSigned"],"properties":{"requireSigned":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The setting now in force."},"404":{"description":"Unknown campaign.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/campaigns/{campaignId}/app-installs":{"servers":[{"url":"/api/v1","description":"This gateway (not under /channel)"}],"get":{"tags":["apps"],"summary":"The same install list for a Studio session (`campaign:view`), cursor-paged.","security":[{"studioJwt":[]}],"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppInstallPage"}}}},"404":{"description":"Unknown campaign.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A stable class code — see the class-code table in PARTNER_INTEGRATION.md."},"title":{"type":"string"},"description":{"type":"string"}},"required":["code","title","description"]}}}}}}},"/openapi.json":{"get":{"tags":["identity"],"summary":"This document. No authentication required.","security":[],"responses":{"200":{"description":"OK"}}}}}}