{"components":{"schemas":{"Accepted":{"properties":{"accepted":{"type":"boolean"}},"type":"object"},"CreateNotificationRequest":{"properties":{"actions":{"items":{"properties":{"icon":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"apns_category":{"description":"iOS only. Sets aps.category verbatim so an app that registered a matching UNNotificationCategory renders the action buttons. Overrides the server-minted category for this message.","type":"string"},"badge":{"type":"integer"},"body":{"type":"string"},"click_action":{"type":"string"},"data":{"type":"object"},"deep_link":{"type":"string"},"delivery":{"description":"voip = incoming-call ring: sent only to kind=voip devices as an APNs PushKit push (apns-push-type voip, topic <bundle_id>.voip, expiration 0) / data-only HIGH-priority FCM message. title/body become optional; data must carry the opaque call payload (e.g. {\"incomingCall\": {...}}). Default: standard.","enum":["standard","voip"],"type":"string"},"email_to":{"description":"Also deliver as email to these addresses.","items":{"format":"email","type":"string"},"type":"array"},"expires_at":{"format":"date-time","type":"string"},"priority":{"enum":["high","normal"],"type":"string"},"recurrence":{"description":"5-field cron; makes this a recurring series.","type":"string"},"recurrence_tz":{"description":"IANA zone for the cron (default Etc/UTC).","type":"string"},"recurrence_until":{"format":"date-time","type":"string"},"scheduled_at":{"format":"date-time","type":"string"},"silent":{"type":"boolean"},"sound":{"type":"string"},"target":{"$ref":"#/components/schemas/NotificationTarget"},"template":{"description":"Template slug (Pro+). Use instead of title/body.","type":"string"},"title":{"type":"string"},"vars":{"description":"Template variables.","type":"object"}},"required":["target"],"type":"object"},"Device":{"description":"A registered device. The push token is never returned.","properties":{"apns_environment":{"enum":["sandbox","production"],"nullable":true,"type":"string"},"id":{"type":"string"},"inserted_at":{"format":"date-time","type":"string"},"kind":{"enum":["standard","voip"],"type":"string"},"last_seen_at":{"format":"date-time","nullable":true,"type":"string"},"platform":{"enum":["ios","android","web"],"type":"string"},"status":{"enum":["active","inactive"],"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"timezone":{"nullable":true,"type":"string"},"user_id":{"nullable":true,"type":"string"}},"type":"object"},"DeviceList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Device"},"type":"array"},"total":{"type":"integer"}},"type":"object"},"DeviceRegistered":{"properties":{"created":{"type":"boolean"},"id":{"type":"string"}},"type":"object"},"DeviceRevoked":{"properties":{"id":{"type":"string"},"status":{"enum":["inactive"],"type":"string"}},"type":"object"},"DeviceTags":{"properties":{"id":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"}},"type":"object"},"DeviceTokenBody":{"properties":{"token":{"description":"The provider token to revoke","type":"string"}},"required":["token"],"type":"object"},"Error":{"properties":{"error":{"properties":{"code":{"type":"string"},"details":{"type":"object"},"message":{"type":"string"}},"type":"object"}},"type":"object"},"EventRequest":{"properties":{"action_id":{"type":"string"},"device_id":{"type":"string"},"happened_at":{"format":"date-time","type":"string"},"notification_id":{"type":"string"},"type":{"enum":["opened","clicked"],"type":"string"}},"required":["notification_id","device_id","type"],"type":"object"},"InboxItem":{"properties":{"body":{"type":"string"},"data":{"type":"object"},"deep_link":{"nullable":true,"type":"string"},"id":{"type":"string"},"inserted_at":{"format":"date-time","type":"string"},"notification_id":{"type":"string"},"read":{"type":"boolean"},"read_at":{"format":"date-time","nullable":true,"type":"string"},"title":{"type":"string"}},"type":"object"},"InboxList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/InboxItem"},"type":"array"}},"type":"object"},"MarkedRead":{"properties":{"marked_read":{"type":"integer"}},"type":"object"},"Notification":{"properties":{"body":{"nullable":true,"type":"string"},"counters":{"properties":{"total_clicked":{"type":"integer"},"total_delivered":{"type":"integer"},"total_failed":{"type":"integer"},"total_opened":{"type":"integer"},"total_sent":{"type":"integer"},"total_targets":{"type":"integer"}},"type":"object"},"delivery":{"enum":["standard","voip"],"type":"string"},"email_to":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"recurrence":{"nullable":true,"type":"string"},"scheduled_at":{"format":"date-time","nullable":true,"type":"string"},"series_id":{"nullable":true,"type":"string"},"status":{"type":"string"},"target_kind":{"type":"string"},"title":{"nullable":true,"type":"string"}},"type":"object"},"NotificationCreated":{"properties":{"id":{"type":"string"},"status":{"type":"string"}},"type":"object"},"NotificationTarget":{"description":"Exactly one of: all / device_ids / user_ids / tags / segment.","properties":{"all":{"type":"boolean"},"device_ids":{"items":{"type":"string"},"type":"array"},"match":{"enum":["any","all"],"type":"string"},"segment":{"$ref":"#/components/schemas/Segment"},"tags":{"items":{"type":"string"},"type":"array"},"user_ids":{"items":{"type":"string"},"type":"array"}},"type":"object"},"RegisterDeviceRequest":{"properties":{"environment":{"description":"iOS APNs environment (auto-detected by the SDKs).","enum":["sandbox","production"],"type":"string"},"kind":{"description":"voip = iOS PushKit VoIP token / Android incoming-call device. Only delivery=voip notifications are sent to it. Not valid for platform=web. Default: standard.","enum":["standard","voip"],"type":"string"},"metadata":{"description":"Filterable in segment targets.","type":"object"},"platform":{"enum":["ios","android","web"],"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"timezone":{"description":"IANA zone for quiet-hours delivery.","type":"string"},"token":{"type":"string"},"user_id":{"type":"string"},"web_push_auth":{"type":"string"},"web_push_p256dh":{"type":"string"}},"required":["token","platform"],"type":"object"},"Segment":{"properties":{"conditions":{"items":{"properties":{"field":{"description":"platform | user_id | timezone | tag | metadata.<key>","type":"string"},"op":{"enum":["eq","neq","in","exists","contains","gt","lt"],"type":"string"},"value":{"description":"String, number, or array depending on op."}},"type":"object"},"type":"array"},"match":{"enum":["all","any"],"type":"string"}},"required":["conditions"],"type":"object"},"UnreadCount":{"properties":{"unread_count":{"type":"integer"}},"type":"object"},"UpdateDeviceRequest":{"description":"Replace (`tags`) or incrementally edit (`add_tags`/`remove_tags`).","properties":{"add_tags":{"items":{"type":"string"},"type":"array"},"remove_tags":{"items":{"type":"string"},"type":"array"},"tags":{"items":{"type":"string"},"type":"array"}},"type":"object"},"UserIdBody":{"properties":{"user_id":{"type":"string"}},"required":["user_id"],"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"description":"Secret key. `Authorization: ApiKey np_...` (or `Bearer np_...`).","scheme":"bearer","type":"http"},"PublicKeyAuth":{"description":"Publishable key. `Authorization: Public pk_...`.","scheme":"bearer","type":"http"}}},"info":{"description":"Push notification delivery (APNs / FCM / Web Push), device registration, engagement tracking, and the in-app inbox.","title":"nitroping API","version":"0.1.0"},"openapi":"3.1.0","paths":{"/api/v1/devices":{"delete":{"description":"Logout flow: deactivate the device matching the given provider token. Use DELETE /api/v1/devices/{id} when you have the id.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRevoked"}}},"description":"DeviceRevoked"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Revoke a device by token (secret key)","tags":["Devices"]},"get":{"description":"Lists the app's devices. Never returns the push token. Filter by user_id to fetch one end-user's registered devices.","parameters":[{"in":"query","name":"user_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"platform","required":false,"schema":{"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"type":"string"}},{"in":"query","name":"page","required":false,"schema":{"type":"string"}},{"in":"query","name":"page_size","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceList"}}},"description":"DeviceList"}},"security":[{"ApiKeyAuth":[]}],"summary":"List devices (secret key)","tags":["Devices"]},"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRegistered"}}},"description":"DeviceRegistered"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRegistered"}}},"description":"DeviceRegistered"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Register / refresh a device (secret key)","tags":["Devices"]}},"/api/v1/devices/{id}":{"delete":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRevoked"}}},"description":"DeviceRevoked"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Revoke a device by id (secret key)","tags":["Devices"]},"patch":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTags"}}},"description":"DeviceTags"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Update a device's tags (secret key)","tags":["Devices"]}},"/api/v1/events":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventRequest"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Accepted"}}},"description":"Accepted"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"summary":"Report an engagement event (opened/clicked)","tags":["Events"]}},"/api/v1/notifications":{"post":{"parameters":[{"description":"Replay-safe key; identical retries return the original result.","in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateNotificationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationCreated"}}},"description":"NotificationCreated"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Create & send (or schedule) a notification","tags":["Notifications"]}},"/api/v1/notifications/{id}":{"delete":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Notification"}}},"description":"Notification"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Cancel a pending/scheduled notification (stops a series)","tags":["Notifications"]},"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Notification"}}},"description":"Notification"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"ApiKeyAuth":[]}],"summary":"Fetch a notification + counters","tags":["Notifications"]}},"/api/v1/public/devices":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRegistered"}}},"description":"DeviceRegistered"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRegistered"}}},"description":"DeviceRegistered"}},"security":[{"PublicKeyAuth":[]}],"summary":"Register a device with a public (pk_) key","tags":["Devices"]}},"/api/v1/public/inbox":{"get":{"parameters":[{"in":"query","name":"user_id","required":true,"schema":{"type":"string"}},{"in":"query","name":"unread_only","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxList"}}},"description":"InboxList"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"PublicKeyAuth":[]}],"summary":"List a user's in-app inbox","tags":["Inbox"]}},"/api/v1/public/inbox/read_all":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkedRead"}}},"description":"MarkedRead"}},"security":[{"PublicKeyAuth":[]}],"summary":"Mark all of a user's inbox items read","tags":["Inbox"]}},"/api/v1/public/inbox/unread_count":{"get":{"parameters":[{"in":"query","name":"user_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCount"}}},"description":"UnreadCount"}},"security":[{"PublicKeyAuth":[]}],"summary":"Unread count for a user","tags":["Inbox"]}},"/api/v1/public/inbox/{id}/read":{"post":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxItem"}}},"description":"InboxItem"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"}},"security":[{"PublicKeyAuth":[]}],"summary":"Mark one inbox item read","tags":["Inbox"]}}},"security":[{"ApiKeyAuth":[]}],"servers":[{"description":"Production","url":"https://nitroping.dev"}],"tags":[{"name":"Notifications"},{"name":"Devices"},{"name":"Events"},{"name":"Inbox"}]}