{"openapi":"3.1.0","info":{"title":"KeepSafe Messenger API","version":"0.1.0","description":"Multi-application messaging service for device registration, APNs push notifications, ActivityKit Live Activities, SMS, email, Slack webhooks, and admin app management."},"servers":[{"url":"https://messenger.keepsafe.ai","description":"Production"},{"url":"http://127.0.0.1:4324","description":"Local development"}],"tags":[{"name":"Health"},{"name":"Admin Apps"},{"name":"API Clients"},{"name":"Device Registration"},{"name":"Push"},{"name":"Live Activities"},{"name":"SMS"},{"name":"Email"},{"name":"Slack"},{"name":"Events"},{"name":"Legacy Push Compatibility"}],"paths":{"/health":{"get":{"tags":["Health"],"summary":"Health check","operationId":"getHealth","responses":{"200":{"description":"Service is healthy.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true}}}}}}}}},"/api/apps":{"get":{"tags":["Admin Apps"],"summary":"List visible apps","security":[{"adminAuth":[]}],"responses":{"200":{"description":"Visible apps.","content":{"application/json":{"schema":{"type":"object","properties":{"apps":{"type":"array","items":{"$ref":"#/components/schemas/App"}}}}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Admin Apps"],"summary":"Create an app","security":[{"adminAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","bundleId"],"properties":{"name":{"type":"string","example":"Flame Games"},"bundleId":{"type":"string","example":"com.silverpine.Flame-Games"}}}}}},"responses":{"201":{"description":"Created app.","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"$ref":"#/components/schemas/App"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/apps/{id}":{"delete":{"tags":["Admin Apps"],"summary":"Delete an app","security":[{"adminAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"App ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["confirmDelete","confirmText"],"properties":{"confirmDelete":{"type":"string","example":"delete"},"confirmText":{"type":"string","example":"confirm"}}}}}},"responses":{"200":{"description":"Deleted app.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"app":{"$ref":"#/components/schemas/App"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/api-clients":{"get":{"tags":["API Clients"],"summary":"List API clients","security":[{"adminAuth":[]}],"responses":{"200":{"description":"API clients visible to the caller.","content":{"application/json":{"schema":{"type":"object","properties":{"apiClients":{"type":"array","items":{"$ref":"#/components/schemas/ApiClient"}}}}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["API Clients"],"summary":"Create an API client token","description":"Returns the token once. Store it immediately.","security":[{"adminAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiClientRequest"}}}},"responses":{"201":{"description":"Created API client and one-time token.","content":{"application/json":{"schema":{"type":"object","properties":{"apiClient":{"$ref":"#/components/schemas/ApiClient"},"token":{"type":"string"}}}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/devices/register":{"post":{"tags":["Device Registration"],"summary":"Register or update a push device token","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceRequest"}}}},"responses":{"201":{"description":"Registered device.","content":{"application/json":{"schema":{"type":"object","properties":{"device":{"$ref":"#/components/schemas/Device"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/push/send":{"post":{"tags":["Push"],"summary":"Send a push notification","description":"Requires `push:send` or `admin`. Use `dryRun: true` to record recipients without provider delivery.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendPushRequest"}}}},"responses":{"201":{"description":"Recorded push event.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/live-activities/register":{"post":{"tags":["Live Activities"],"summary":"Register or update an ActivityKit Live Activity push token","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterLiveActivityRequest"}}}},"responses":{"201":{"description":"Registered Live Activity token.","content":{"application/json":{"schema":{"type":"object","properties":{"liveActivity":{"$ref":"#/components/schemas/LiveActivity"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/live-activities/send":{"post":{"tags":["Live Activities"],"summary":"Send a Live Activity start, update, or end event","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendLiveActivityRequest"}}}},"responses":{"201":{"description":"Recorded Live Activity event.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/sms/register":{"post":{"tags":["SMS"],"summary":"Register or update an SMS recipient","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterSmsRecipientRequest"}}}},"responses":{"201":{"description":"Registered SMS recipient.","content":{"application/json":{"schema":{"type":"object","properties":{"smsRecipient":{"$ref":"#/components/schemas/SmsRecipient"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/sms/send":{"post":{"tags":["SMS"],"summary":"Send an SMS message","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendSmsRequest"}}}},"responses":{"201":{"description":"Recorded SMS event.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/email/register":{"post":{"tags":["Email"],"summary":"Register or update an email recipient","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterEmailRecipientRequest"}}}},"responses":{"201":{"description":"Registered email recipient.","content":{"application/json":{"schema":{"type":"object","properties":{"emailRecipient":{"$ref":"#/components/schemas/EmailRecipient"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/email/send":{"post":{"tags":["Email"],"summary":"Send an email message","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailRequest"}}}},"responses":{"201":{"description":"Recorded email event.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/slack/register":{"post":{"tags":["Slack"],"summary":"Register or update a Slack incoming webhook recipient","description":"Requires `slack:write` or `admin`. Webhook URLs are encrypted at rest and redacted from responses/events.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterSlackWebhookRecipientRequest"}}}},"responses":{"201":{"description":"Registered Slack webhook recipient.","content":{"application/json":{"schema":{"type":"object","properties":{"slackWebhookRecipient":{"$ref":"#/components/schemas/SlackWebhookRecipient"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/slack/register-webhook":{"post":{"tags":["Slack"],"summary":"Alias for Slack webhook registration","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterSlackWebhookRecipientRequest"}}}},"responses":{"201":{"description":"Registered Slack webhook recipient.","content":{"application/json":{"schema":{"type":"object","properties":{"slackWebhookRecipient":{"$ref":"#/components/schemas/SlackWebhookRecipient"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/slack/send":{"post":{"tags":["Slack"],"summary":"Send a Slack webhook message","description":"Requires `slack:send` or `admin`. Specific sends target registered recipient IDs, never raw webhook URLs.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendSlackRequest"}}}},"responses":{"201":{"description":"Recorded Slack event.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}}}}}},"400":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/stats/overview":{"get":{"tags":["Events"],"summary":"Get admin overview stats","security":[{"adminAuth":[]}],"responses":{"200":{"description":"Overview stats.","content":{"application/json":{"schema":{"type":"object","properties":{"overview":{"type":"object","additionalProperties":true}}}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/events":{"get":{"tags":["Events"],"summary":"List recent notification events","security":[{"adminAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Recent events.","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/push/health":{"get":{"tags":["Legacy Push Compatibility"],"summary":"Legacy push-service health check","responses":{"200":{"description":"Legacy health response.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/push/token":{"post":{"tags":["Legacy Push Compatibility"],"summary":"Legacy WNBA device-token registration","security":[{"legacyRegistrationToken":[]}],"responses":{"201":{"description":"Registered legacy device token.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/push/events":{"get":{"tags":["Legacy Push Compatibility"],"summary":"Legacy event listing","security":[{"legacyAdminToken":[]}],"responses":{"200":{"description":"Legacy events.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Legacy Push Compatibility"],"summary":"Legacy event push send","security":[{"legacyAdminToken":[]}],"responses":{"201":{"description":"Recorded legacy push event.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Request failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"App API client token with the required scope."},"adminAuth":{"type":"http","scheme":"bearer","description":"Admin bearer token. HTTP Basic admin auth is also supported operationally."},"legacyAdminToken":{"type":"apiKey","in":"header","name":"x-push-admin-token"},"legacyRegistrationToken":{"type":"apiKey","in":"header","name":"x-push-registration-token"}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}},"App":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"bundleId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ApiClient":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"},"example":["device:write","push:send"]},"allowedAppIds":{"type":"array","items":{"type":"string"}},"tokenPreview":{"type":"string"},"revokedAt":{"type":["string","null"],"format":"date-time"}}},"CreateApiClientRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","example":"Backend sender"},"scopes":{"type":"array","items":{"type":"string"},"example":["device:write","push:send","sms:send","email:send","slack:write","slack:send"]},"appIds":{"type":"array","items":{"type":"string"},"description":"Optional app ID allow-list."}}},"Device":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"platform":{"type":"string","enum":["ios","android"]},"environment":{"type":"string"},"tokenHash":{"type":"string"},"tokenPreview":{"type":"string"},"deviceId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegisterDeviceRequest":{"type":"object","required":["platform","token"],"properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"platform":{"type":"string","enum":["ios","android"]},"environment":{"type":"string","default":"production","example":"production"},"token":{"type":"string","example":"APNS_DEVICE_TOKEN"},"deviceId":{"type":"string"},"appVersion":{"type":"string"},"buildNumber":{"type":"string"}}},"SendPushRequest":{"type":"object","required":["title","body"],"properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"platform":{"type":"string","enum":["ios","android"]},"environment":{"type":"string","default":"production"},"title":{"type":"string"},"body":{"type":"string"},"sound":{"type":"string","default":"default"},"target":{"oneOf":[{"type":"object","properties":{"type":{"const":"broadcast"}}},{"type":"object","required":["type","tokens"],"properties":{"type":{"const":"tokens"},"tokens":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","deviceIds"],"properties":{"type":{"const":"deviceIds"},"deviceIds":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","topic"],"properties":{"type":{"const":"topic"},"topic":{"type":"string"}}},{"type":"object","required":["type","recipientIds"],"properties":{"type":{"const":"recipients"},"recipientIds":{"type":"array","items":{"type":"string"}}}}]},"data":{"type":"object","additionalProperties":true},"dryRun":{"type":"boolean","default":false}}},"LiveActivity":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"environment":{"type":"string"},"tokenHash":{"type":"string"},"tokenPreview":{"type":"string"},"tokenType":{"type":"string","enum":["activityUpdate","pushToStart"]},"activityId":{"type":["string","null"]},"attributesType":{"type":["string","null"]},"deviceId":{"type":["string","null"]},"invalidatedAt":{"type":["string","null"]},"lastError":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegisterLiveActivityRequest":{"type":"object","properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"environment":{"type":"string","enum":["production","sandbox","development"],"default":"production"},"token":{"type":"string","description":"Aliases: pushToken, liveActivityPushToken, activityKitPushToken."},"activityKitPushToStartToken":{"type":"string","description":"ActivityKit push-to-start token from Activity<Attributes>.pushToStartTokenUpdates."},"tokenType":{"type":"string","enum":["activityUpdate","pushToStart"],"description":"Optional. Missing tokenType preserves legacy activityUpdate behavior."},"activityId":{"type":"string"},"attributesType":{"type":"string"},"deviceId":{"type":"string"}}},"SendLiveActivityRequest":{"type":"object","required":["contentState"],"properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"environment":{"type":"string","enum":["production","sandbox","development"],"default":"production"},"event":{"type":"string","enum":["start","update","end"],"default":"update"},"eventId":{"type":"string","description":"Required for event=start. Used for push-to-start idempotency and ActivityKit attributes.eventId."},"activityId":{"type":"string"},"attributesType":{"type":"string","description":"Required for event=start. Example: FireGameActivityAttributes."},"attributes":{"type":"object","additionalProperties":true,"description":"Required payload attributes for event=start. eventId is inserted from eventId if absent."},"target":{"oneOf":[{"type":"object","properties":{"type":{"const":"broadcast"}}},{"type":"object","required":["type","tokens"],"properties":{"type":{"const":"tokens"},"tokens":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","deviceIds"],"properties":{"type":{"const":"deviceIds"},"deviceIds":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","topic"],"properties":{"type":{"const":"topic"},"topic":{"type":"string"}}},{"type":"object","required":["type","recipientIds"],"properties":{"type":{"const":"recipients"},"recipientIds":{"type":"array","items":{"type":"string"}}}}]},"contentState":{"type":"object","additionalProperties":true},"timestamp":{"type":"integer"},"staleDate":{"type":"integer"},"dismissalDate":{"type":"integer"},"priority":{"type":["string","integer"]},"collapseId":{"type":"string"},"expiration":{"type":"integer"},"dryRun":{"type":"boolean","default":false}}},"SmsRecipient":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"recipientKey":{"type":"string"},"phonePreview":{"type":"string"},"label":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegisterSmsRecipientRequest":{"type":"object","required":["recipientId","phoneNumber"],"properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"recipientId":{"type":"string","example":"user-123"},"phoneNumber":{"type":"string","example":"+15125551234"},"label":{"type":"string"}}},"SendSmsRequest":{"type":"object","properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"recipientIds":{"type":"array","items":{"type":"string"}},"target":{"oneOf":[{"type":"object","properties":{"type":{"const":"broadcast"}}},{"type":"object","required":["type","tokens"],"properties":{"type":{"const":"tokens"},"tokens":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","deviceIds"],"properties":{"type":{"const":"deviceIds"},"deviceIds":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","topic"],"properties":{"type":{"const":"topic"},"topic":{"type":"string"}}},{"type":"object","required":["type","recipientIds"],"properties":{"type":{"const":"recipients"},"recipientIds":{"type":"array","items":{"type":"string"}}}}]},"message":{"type":"string"},"messageType":{"type":"string","enum":["TRANSACTIONAL","PROMOTIONAL"],"default":"TRANSACTIONAL"},"dryRun":{"type":"boolean","default":false}}},"EmailRecipient":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"recipientKey":{"type":"string"},"emailPreview":{"type":"string"},"label":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegisterEmailRecipientRequest":{"type":"object","required":["recipientId","email"],"properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"recipientId":{"type":"string","example":"user-123"},"email":{"type":"string","format":"email","example":"person@example.com"},"label":{"type":"string"}}},"SendEmailRequest":{"type":"object","properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"recipientIds":{"type":"array","items":{"type":"string"}},"target":{"oneOf":[{"type":"object","properties":{"type":{"const":"broadcast"}}},{"type":"object","required":["type","tokens"],"properties":{"type":{"const":"tokens"},"tokens":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","deviceIds"],"properties":{"type":{"const":"deviceIds"},"deviceIds":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","topic"],"properties":{"type":{"const":"topic"},"topic":{"type":"string"}}},{"type":"object","required":["type","recipientIds"],"properties":{"type":{"const":"recipients"},"recipientIds":{"type":"array","items":{"type":"string"}}}}]},"subject":{"type":"string"},"message":{"type":"string"},"html":{"type":"string"},"dryRun":{"type":"boolean","default":false}}},"SlackWebhookRecipient":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"recipientKey":{"type":"string"},"webhookPreview":{"type":"string"},"label":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegisterSlackWebhookRecipientRequest":{"type":"object","required":["recipientId","webhookUrl"],"properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"recipientId":{"type":"string","example":"status-alerts"},"webhookUrl":{"type":"string","format":"uri","example":"https://hooks.slack.com/services/T000/B000/SECRET"},"label":{"type":"string"}}},"SendSlackRequest":{"type":"object","properties":{"appId":{"type":"string","description":"KeepSafe Messenger app ID.","example":"app_123"},"bundleId":{"type":"string","description":"Application bundle/package ID.","example":"com.example.app"},"recipientIds":{"type":"array","items":{"type":"string"}},"target":{"oneOf":[{"type":"object","properties":{"type":{"const":"broadcast"}}},{"type":"object","required":["type","tokens"],"properties":{"type":{"const":"tokens"},"tokens":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","deviceIds"],"properties":{"type":{"const":"deviceIds"},"deviceIds":{"type":"array","items":{"type":"string"}}}},{"type":"object","required":["type","topic"],"properties":{"type":{"const":"topic"},"topic":{"type":"string"}}},{"type":"object","required":["type","recipientIds"],"properties":{"type":{"const":"recipients"},"recipientIds":{"type":"array","items":{"type":"string"}}}}]},"message":{"type":"string"},"dryRun":{"type":"boolean","default":false}}},"Event":{"type":"object","properties":{"id":{"type":"string"},"appId":{"type":"string"},"kind":{"type":"string"},"title":{"type":["string","null"]},"body":{"type":["string","null"]},"targetJson":{"type":["string","null"]},"payloadJson":{"type":["string","null"]},"status":{"type":"string"},"recipientCount":{"type":"integer"},"deliveredCount":{"type":"integer"},"skippedCount":{"type":"integer"},"failedCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}}}}}