Files
2025-12-17 01:26:12 +00:00

172 lines
155 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper docs-doc-page docs-version-current plugin-docs plugin-id-status docs-doc-id-deprecated/push-notification-server">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v2.4.1">
<title data-rh="true">PUSH-NOTIFICATION-SERVER | Vac Research</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://vac.dev/status/deprecated/push-notification-server"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="image" content="https://vac.dev/_og/218ac8e3e600c51b89b88a125ad948ebe37687f5.png"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-status-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-status-current"><meta data-rh="true" property="og:title" content="PUSH-NOTIFICATION-SERVER | Vac Research"><meta data-rh="true" name="description" content="Status provides a set of Push notification services that can be used to achieve this functionality."><meta data-rh="true" property="og:description" content="Status provides a set of Push notification services that can be used to achieve this functionality."><link data-rh="true" rel="icon" href="/theme/image/favicon.ico"><link data-rh="true" rel="canonical" href="https://vac.dev/status/deprecated/push-notification-server"><link data-rh="true" rel="alternate" href="https://vac.dev/status/deprecated/push-notification-server" hreflang="en"><link data-rh="true" rel="alternate" href="https://vac.dev/status/deprecated/push-notification-server" hreflang="x-default"><link rel="alternate icon" type="image/png" href="/theme/image/favicon.png">
<link rel="icon" type="image/svg+xml" href="/theme/image/favicon.svg">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.7f69a75a.css">
<link rel="preload" href="/assets/js/runtime~main.db01e95f.js" as="script">
<link rel="preload" href="/assets/js/main.7bd63d25.js" as="script">
<meta property="og:image" content="https://vac.dev/_og/218ac8e3e600c51b89b88a125ad948ebe37687f5.png"><meta name="twitter:image" content="https://vac.dev/_og/218ac8e3e600c51b89b88a125ad948ebe37687f5.png"></head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"dark")}()</script><div id="__docusaurus">
<style data-emotion="css-global 3rtehh">.lsd-button{width:auto;cursor:pointer;padding:6px 24px;}.lsd-button--disabled{cursor:default;opacity:0.34;}.lsd-button--large{padding:10px 40px;}.lsd-button--medium{padding:6px 24px;}.lsd-button--small{padding:6px 12px;}.lsd-button:hover:not(.lsd-button--disabled) .lsd-button__text{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-button--with-icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-button__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:100%;}.lsd-button--large.lsd-button--with-icon{padding:10px 0px 10px 18px;}.lsd-button--large.lsd-button--with-icon .lsd-button__icon{width:42px;}.lsd-button--medium.lsd-button--with-icon{padding:6px 0px 6px 14px;}.lsd-button--medium.lsd-button--with-icon .lsd-button__icon{width:38px;}.lsd-button--small.lsd-button--with-icon{padding:6px 0px 6px 12px;}.lsd-button--small.lsd-button--with-icon .lsd-button__icon{width:34px;}.lsd-button--outlined{background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-button--outlined .lsd-button__text{color:rgb(var(--lsd-text-primary));}.lsd-button--filled{background:rgb(var(--lsd-surface-secondary));border:1px solid rgb(var(--lsd-border-primary));}.lsd-button--filled .lsd-button__text{color:rgb(var(--lsd-text-secondary));}</style><style data-emotion="css-global 10bahxd">.lsd-icon-button{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;cursor:pointer;background:none;padding:0;border:1px solid rgb(var(--lsd-border-primary));}.lsd-icon-button--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-icon-button--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-icon-button--disabled{opacity:0.34;cursor:default;}.lsd-icon-button--large{width:40px;height:40px;}.lsd-icon-button--medium{width:32px;height:32px;}.lsd-icon-button--small{width:28px;height:28px;}</style><style data-emotion="css-global icqph9">.lsd-icon-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-icon-button-group--outlined .lsd-icon-button:not(:last-child){border-right:none;}</style><style data-emotion="css-global 1f43ub2">body *{font-family:var(--lsd-typography-generic-font-family);}.lsd-typography{color:rgb(var(--lsd-text-primary));}.lsd-typography--sans-serif,.lsd-typography--sans-serif *{font-family:sans-serif;}.lsd-typography--serif,.lsd-typography--serif *{font-family:serif;}.lsd-typography--monospace,.lsd-typography--monospace *{font-family:monospace;}.lsd-typography--display1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display1-fontWeight);font-size:var(--lsd-display1-fontSize);line-height:var(--lsd-display1-lineHeight);}.lsd-typography--display2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display2-fontWeight);font-size:var(--lsd-display2-fontSize);line-height:var(--lsd-display2-lineHeight);}.lsd-typography--display3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display3-fontWeight);font-size:var(--lsd-display3-fontSize);line-height:var(--lsd-display3-lineHeight);}.lsd-typography--display4{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display4-fontWeight);font-size:var(--lsd-display4-fontSize);line-height:var(--lsd-display4-lineHeight);}h1,.lsd-typography--h1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h1-fontWeight);font-size:var(--lsd-h1-fontSize);line-height:var(--lsd-h1-lineHeight);}h2,.lsd-typography--h2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h2-fontWeight);font-size:var(--lsd-h2-fontSize);line-height:var(--lsd-h2-lineHeight);}h3,.lsd-typography--h3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h3-fontWeight);font-size:var(--lsd-h3-fontSize);line-height:var(--lsd-h3-lineHeight);}h4,.lsd-typography--h4{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h4-fontWeight);font-size:var(--lsd-h4-fontSize);line-height:var(--lsd-h4-lineHeight);}h5,.lsd-typography--h5{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h5-fontWeight);font-size:var(--lsd-h5-fontSize);line-height:var(--lsd-h5-lineHeight);}h6,.lsd-typography--h6{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h6-fontWeight);font-size:var(--lsd-h6-fontSize);line-height:var(--lsd-h6-lineHeight);}.lsd-typography--subtitle1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle1-fontWeight);font-size:var(--lsd-subtitle1-fontSize);line-height:var(--lsd-subtitle1-lineHeight);}.lsd-typography--subtitle2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle2-fontWeight);font-size:var(--lsd-subtitle2-fontSize);line-height:var(--lsd-subtitle2-lineHeight);}.lsd-typography--subtitle3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle3-fontWeight);font-size:var(--lsd-subtitle3-fontSize);line-height:var(--lsd-subtitle3-lineHeight);}.lsd-typography--subtitle4{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle4-fontWeight);font-size:var(--lsd-subtitle4-fontSize);line-height:var(--lsd-subtitle4-lineHeight);}body,.lsd-typography--body1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-body1-fontWeight);font-size:var(--lsd-body1-fontSize);line-height:var(--lsd-body1-lineHeight);}.lsd-typography--body2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-body2-fontWeight);font-size:var(--lsd-body2-fontSize);line-height:var(--lsd-body2-lineHeight);}.lsd-typography--body3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-body3-fontWeight);font-size:var(--lsd-body3-fontSize);line-height:var(--lsd-body3-lineHeight);}label,.lsd-typography--label1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-label1-fontWeight);font-size:var(--lsd-label1-fontSize);line-height:var(--lsd-label1-lineHeight);}.lsd-typography--label2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-label2-fontWeight);font-size:var(--lsd-label2-fontSize);line-height:var(--lsd-label2-lineHeight);}.lsd-typography--primary{color:rgb(var(--lsd-text-primary));}.lsd-typography--secondary{color:rgb(var(--lsd-text-secondary));}input{color:rgb(var(--lsd-text-primary));font-size:var(--lsd-body1-fontSize);font-weight:var(--lsd-body1-fontWeight);}h1,h2,h3,h4,h5,h6,p,span{margin:0;}</style><style data-emotion="css-global 1yxb6i5">.lsd-icon--primary.lsd-icon--filled,.lsd-icon--primary.lsd-icon--filled *{fill:rgb(var(--lsd-icon-primary));}.lsd-icon--primary $.lsd-icon--stroked,.lsd-icon--primary $.lsd-icon--stroked *{fill:rgb(var(--lsd-icon-primary));}.lsd-icon--secondary.lsd-icon--filled,.lsd-icon--secondary.lsd-icon--filled *{fill:rgb(var(--lsd-icon-secondary));}.lsd-icon--secondary $.lsd-icon--stroked,.lsd-icon--secondary $.lsd-icon--stroked *{fill:rgb(var(--lsd-icon-secondary));}</style><style data-emotion="css-global 1hozxbf">.lsd-tab-item{background:rgb(var(--lsd-surface-primary));border:1px solid transparent;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;}.lsd-tab-item:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-tab-item:not(lsd-tab-item--selected){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-tab-item--text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-tab-item--icon{margin-left:14px;}.lsd-tab-item--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-tab-item--selected:hover{-webkit-text-decoration:none;text-decoration:none;}.lsd-tab-item--with-icon{-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-tab-item--disabled{cursor:default;opacity:0.34;}.lsd-tab-item--disabled:hover{-webkit-text-decoration:none;text-decoration:none;}.lsd-tab-item--small{padding:6px 12px;}.lsd-tab-item--small .lsd-tab-item--icon{margin-left:10px;}.lsd-tab-item--medium{padding:6px 14px;}.lsd-tab-item--medium .lsd-tab-item--icon{margin-left:12px;}.lsd-tab-item--large{padding:10px 18px;}.lsd-tab-item--large .lsd-tab-item--icon{margin-left:14px;}</style><style data-emotion="css-global 1a24j7d">.lsd-tabs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;overflow:auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;max-width:100%;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-tabs>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-tabs .lsd-tab-item{border-bottom:none;}.lsd-tabs--full-width{width:100%;-webkit-box-pack:stretch;-ms-flex-pack:stretch;-webkit-justify-content:stretch;justify-content:stretch;}.lsd-tabs--full-width>*{width:100%;-webkit-flex:1 0;-ms-flex:1 0;flex:1 0;}.lsd-tabs{-ms-overflow-style:none;scrollbar-width:none;}.lsd-tabs::-webkit-scrollbar{display:none;}.lsd-tabs__left-scroll-control{left:0;}.lsd-tabs__right-scroll-control{right:0;}.lsd-tabs__right-scroll-control,.lsd-tabs__left-scroll-control{top:0;-webkit-flex:0 1;-ms-flex:0 1;flex:0 1;position:-webkit-sticky;position:sticky;}</style><style data-emotion="css-global 1v7gjjb">.lsd-dropdown-menu{position:absolute;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));overflow:auto;border:1px solid rgb(var(--lsd-border-primary));border-top:0;}.lsd-dropdown-menu>div{border:0;}.lsd-dropdown-menu>div:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-menu--open{opacity:1;visibility:visible;}.lsd-dropdown-menu--large{max-height:220px;}.lsd-dropdown-menu--medium{max-height:176px;}.lsd-dropdown-menu--small{max-height:154px;}</style><style data-emotion="css-global hyd3xb">.lsd-dropdown:not(.lsd-dropdown--disabled):not(
.lsd-dropdown--error
) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not(
.lsd-dropdown--error
) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global js1ujt">html:not([data-theme]){--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}html[data-theme='light']{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}html[data-theme='dark']{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--light_BL8e" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--dark_OvIx" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><aside class="theme-doc-sidebar-container docSidebarContainer_b6E3"><div class="sidebarViewport_Xe31"><div class="sidebar_UEyd sidebarWithHideableNavbar__00c"><a tabindex="-1" class="sidebarLogo_Ydl9" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--light_BL8e" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--dark_OvIx" height="26"><b></b></a><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_NjKY"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/">Status RFCs</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--active" aria-expanded="true" href="/status/deprecated/3rd-party"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="chevron_How5 lsd-icon lsd-icon--small lsd-icon--filled"><path d="M3.5 8.33875L4.3225 9.16125L7 6.48959L9.6775 9.16125L10.5 8.33875L7 4.83875L3.5 8.33875Z" fill="black"></path></svg><span class="lsd-typography lsd-typography--body2 lsd-typography--primary">deprecated</span></a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/3rd-party">3RD-PARTY</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/IPFS-gateway-for-sticker-Pack">IPFS-gateway-for-Sticker-Pack</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/account">ACCOUNT</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/client">CLIENT</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/dapp-browser-API-usage">Dapp browser API usage</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/eips">EIPS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/ethereum-usage">ETHEREUM-USAGE</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/group-chat">GROUP-CHAT</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/keycard-usage-for-wallet-and-chat-keys">Keycard Usage for Wallet and Chat Keys</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/notifications">NOTIFICATIONS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/payloads">PAYLOADS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/status/deprecated/push-notification-server">PUSH-NOTIFICATION-SERVER</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/secure-transport">SECURE-TRANSPORT</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/waku-mailserver">WAKU-MAILSERVER</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/waku-usage">WAKU-USAGE</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/whisper-mailserver">WHISPER-MAILSERVER</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/status/deprecated/whisper-usage">WHISPER-USAGE</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/status/raw/simple-scaling"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="chevron_How5 lsd-icon lsd-icon--small lsd-icon--filled"><path d="M3.5 8.33875L4.3225 9.16125L7 6.48959L9.6775 9.16125L10.5 8.33875L7 4.83875L3.5 8.33875Z" fill="black"></path></svg><span class="lsd-typography lsd-typography--body2 lsd-typography--primary">raw</span></a></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/24/curation">24/STATUS-CURATION</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/28/featuring">28/STATUS-FEATURING</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/55/1to1-chat">55/STATUS-1TO1-CHAT</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/56/communities">56/STATUS-COMMUNITIES</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/61/community-history-service">61/STATUS-Community-History-Service</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/62/payloads">62/STATUS-PAYLOADS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/63/keycard-usage">63/STATUS-Keycard-Usage</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/65/account-address">65/STATUS-ACCOUNT-ADDRESS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/status/71/push-notification-server">71/STATUS-PUSH-NOTIFICATION-SERVER</a></li></ul></nav></div></div></aside><main class="docMainContainer_gTbr"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_RLvU" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><a class="breadcrumbs__item" href="/status"><span class="lsd-typography lsd-typography--body3">Home</span></a><li class="breadcrumbs__item"><span class="lsd-typography lsd-typography--body3 breadcrumbs__link">deprecated</span><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="lsd-typography lsd-typography--body3 breadcrumbs__link" itemprop="name">PUSH-NOTIFICATION-SERVER</span><meta itemprop="position" content="2"></li></ul></nav><div class="theme-doc-markdown markdown"><header><h1>PUSH-NOTIFICATION-SERVER</h1><div class="tocMobile_imaF"><div class="tocCollapsible_ROek theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_dxRj"><div></div><span class="lsd-typography lsd-typography--body2">On this page</span><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="lsd-icon lsd-icon--small lsd-icon--filled"><path d="M10.5 5.66125L9.6775 4.83875L7 7.51041L4.3225 4.83874L3.5 5.66125L7 9.16125L10.5 5.66125Z" fill="black"></path></svg></button></div></div></header><ul><li>Status: deprecated</li><li>Editor: Filip Dimitrijevic &lt;<a href="mailto:filip@status.im" target="_blank" rel="noopener noreferrer">filip@status.im</a>&gt;</li><li>Contributors:<ul><li>Andrea Maria Piana &lt;<a href="mailto:andreap@status.im" target="_blank" rel="noopener noreferrer">andreap@status.im</a>&gt;</li></ul></li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="reason">Reason<a href="#reason" class="hash-link" aria-label="Direct link to Reason" title="Direct link to Reason"></a></h2><p>Push notifications for iOS devices and some Android devices can only be implemented by relying on <a href="https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1" target="_blank" rel="noopener noreferrer">APN service</a> for iOS or <a href="https://firebase.google.com/" target="_blank" rel="noopener noreferrer">Firebase</a>.</p><p>This is useful for Android devices that do not support foreground services
or that often kill the foreground service.</p><p>iOS only allows certain kind of applications to keep a connection open when in the
background, VoIP for example, which current status client does not qualify for.</p><p>Applications on iOS can also request execution time when they are in the <a href="https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/updating_your_app_with_background_app_refresh" target="_blank" rel="noopener noreferrer">background</a>
but it has a limited set of use cases, for example it won&#x27;t schedule any time
if the application was force quit,
and generally is not responsive enough to implement a push notification system.</p><p>Therefore Status provides a set of Push notification services
that can be used to achieve this functionality.</p><p>Because this can&#x27;t be safely implemented in a privacy preserving manner,
clients MUST be given an option to opt-in to receiving and sending push notifications.
They are disabled by default.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="requirements">Requirements<a href="#requirements" class="hash-link" aria-label="Direct link to Requirements" title="Direct link to Requirements"></a></h2><p>The party releasing the app MUST possess a certificate for the Apple Push Notification service
and its has to run a <a href="https://github.com/appleboy/gorush" target="_blank" rel="noopener noreferrer">gorush</a> publicly accessible server for sending the actual notification.
The party releasing the app, Status in this case, needs to run its own <a href="https://github.com/appleboy/gorush" target="_blank" rel="noopener noreferrer">gorush</a></p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="components">Components<a href="#components" class="hash-link" aria-label="Direct link to Components" title="Direct link to Components"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="gorush-instance">Gorush instance<a href="#gorush-instance" class="hash-link" aria-label="Direct link to Gorush instance" title="Direct link to Gorush instance"></a></h3><p>A <a href="https://github.com/appleboy/gorush" target="_blank" rel="noopener noreferrer">gorush</a> instance MUST be publicly available,
this will be used only by push notification servers.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="push-notification-server">Push notification server<a href="#push-notification-server" class="hash-link" aria-label="Direct link to Push notification server" title="Direct link to Push notification server"></a></h3><p>A push notification server used by clients to register for receiving and sending push notifications.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="registering-client">Registering client<a href="#registering-client" class="hash-link" aria-label="Direct link to Registering client" title="Direct link to Registering client"></a></h3><p>A Status client that wants to receive push notifications</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="sending-client">Sending client<a href="#sending-client" class="hash-link" aria-label="Direct link to Sending client" title="Direct link to Sending client"></a></h3><p>A Status client that wants to send push notifications</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="registering-with-the-push-notification-service">Registering with the push notification service<a href="#registering-with-the-push-notification-service" class="hash-link" aria-label="Direct link to Registering with the push notification service" title="Direct link to Registering with the push notification service"></a></h2><p>A client MAY register with one or more Push Notification services of their choice.</p><p>A <code>PNR message</code> (Push Notification Registration) MUST be sent to the <a href="/status/deprecated/status/deprecated/waku-usage/#partitioned-topic">partitioned topic</a>
for the public key of the node, encrypted with this key.</p><p>The message MUST be wrapped in a <a href="/status/deprecated/status/deprecated/payload/#payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_REGISTRATION</code>.</p><p>The marshaled protobuf payload MUST also be encrypted with AES-GCM
using the DiffieHellman key generated from the client and server identity.</p><p>This is done in order to ensure that the extracted key from the signature will be
considered invalid if it can&#x27;t decrypt the payload.</p><p>The content of the message MUST contain the following <a href="https://developers.google.com/protocol-buffers/" target="_blank" rel="noopener noreferrer">protobuf record</a>:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationRegistration {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> enum TokenType {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> UNKNOWN_TOKEN_TYPE = 0;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> APN_TOKEN = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> FIREBASE_TOKEN = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> TokenType token_type = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string device_token = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string installation_id = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string access_token = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool enabled = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> uint64 version = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated bytes allowed_key_list = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated bytes blocked_chat_list = 8;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool unregister = 9;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes grant = 10;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool allow_from_contacts_only = 11;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string apn_topic = 12;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool block_mentions = 13;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated bytes allowed_mentions_chat_list = 14;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>A push notification server will handle the message according to the following rules:</p><ul><li>it MUST extract the public key of the sender from the signature and verify that
the payload can be decrypted successfully.</li><li>it MUST verify that <code>token_type</code> is supported</li><li>it MUST verify that <code>device_token</code> is non empty</li><li>it MUST verify that <code>installation_id</code> is non empty</li><li>it MUST verify that <code>version</code> is non-zero and greater than the currently stored version for the public key and installation id of the sender, if any</li><li>it MUST verify that <code>grant</code> is non empty and according to the <a href="#server-grant">specs</a></li><li>it MUST verify that <code>access_token</code> is a valid <a href="https://tools.ietf.org/html/rfc4122" target="_blank" rel="noopener noreferrer"><code>uuid</code></a></li><li>it MUST verify that <code>apn_topic</code> is set if <code>token_type</code> is <code>APN_TOKEN</code></li></ul><p>If the message can&#x27;t be decrypted, the message MUST be discarded.</p><p>If <code>token_type</code> is not supported, a response MUST be sent with <code>error</code> set to
<code>UNSUPPORTED_TOKEN_TYPE</code>.</p><p>If <code>token</code>,<code>installation_id</code>,<code>device_tokens</code>,<code>version</code> are empty, a response MUST
be sent with <code>error</code> set to <code>MALFORMED_MESSAGE</code>.</p><p>If the <code>version</code> is equal or less than the currently stored version, a response MUST
be sent with <code>error</code> set to <code>VERSION_MISMATCH</code>.</p><p>If any other error occurs the <code>error</code> should be set to <code>INTERNAL_ERROR</code>.</p><p>If the response is successful <code>success</code> MUST be set to <code>true</code> otherwise a response MUST be sent with <code>success</code> set to <code>false</code>.</p><p><code>request_id</code> should be set to the <code>SHAKE-256</code> of the encrypted payload.</p><p>The response MUST be sent on the <a href="/status/deprecated/status/deprecated/waku-usage##partitioned-topic">partitioned topic</a> of the sender
and MUST not be encrypted using the <a href="/status/deprecated/status/deprecated/secure-transport">secure transport</a> to facilitate the usage of ephemeral keys.</p><p>The payload of the response is:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationRegistrationResponse {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool success = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ErrorType error = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes request_id = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> enum ErrorType {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> UNKNOWN_ERROR_TYPE = 0;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> MALFORMED_MESSAGE = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> VERSION_MISMATCH = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> UNSUPPORTED_TOKEN_TYPE = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> INTERNAL_ERROR = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>The message MUST be wrapped in a <a href="/status/deprecated/status/deprecated/payloads##payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_REGISTRATION_RESPONSE</code>.</p><p>A client SHOULD listen for a response sent on the <a href="/status/deprecated/status/deprecated/waku-usage/#partitioned-topic">partitioned topic</a>
that the key used to register.</p><p>If <code>success</code> is <code>true</code> the client has registered successfully.</p><p>If <code>success</code> is <code>false</code>:</p><ul><li>If <code>MALFORMED_MESSAGE</code> is returned, the request SHOULD NOT be retried without ensuring that it is correctly formed.</li><li>If <code>INTERNAL_ERROR</code> is returned, the request MAY be retried, but the client MUST backoff exponentially</li></ul><p>A client MAY register with multiple Push Notification Servers in order to increase availability.</p><p>A client SHOULD make sure that all the notification services they registered with have the same information about their tokens.</p><p>If no response is returned the request SHOULD be considered failed and MAY be retried with the same server or a different one, but clients MUST exponentially backoff after each trial.</p><p>If the request is successful the token SHOULD be <a href="#advertising-a-push-notification-server">advertised</a> as described below</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="query-topic">Query topic<a href="#query-topic" class="hash-link" aria-label="Direct link to Query topic" title="Direct link to Query topic"></a></h3><p>On successful registration the server MUST be listening to the topic derived from:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0XHexEncode(Shake256(CompressedClientPublicKey))</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>Using the topic derivation algorithm described <a href="/status/deprecated/status/deprecated/waku-usage/#public-chats">here</a>
and listen for client queries.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="server-grant">Server grant<a href="#server-grant" class="hash-link" aria-label="Direct link to Server grant" title="Direct link to Server grant"></a></h3><p>A push notification server needs to demonstrate to a client that it was authorized
by the client to send them push notifications. This is done by building
a grant which is specific to a given client-server pair.
The grant is built as follow:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>When receiving a grant the server MUST be validate that the signature matches the registering client.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="re-registering-with-the-push-notification-server">Re-registering with the push notification server<a href="#re-registering-with-the-push-notification-server" class="hash-link" aria-label="Direct link to Re-registering with the push notification server" title="Direct link to Re-registering with the push notification server"></a></h2><p>A client SHOULD re-register with the node if the APN or FIREBASE token changes.</p><p>When re-registering a client SHOULD ensure that it has the most up-to-date
<code>PushNotificationRegistration</code> and increment <code>version</code> if necessary.</p><p>Once re-registered, a client SHOULD advertise the changes.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="changing-options">Changing options<a href="#changing-options" class="hash-link" aria-label="Direct link to Changing options" title="Direct link to Changing options"></a></h2><p>This is handled in exactly the same way as re-registering above.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="unregistering-from-push-notifications">Unregistering from push notifications<a href="#unregistering-from-push-notifications" class="hash-link" aria-label="Direct link to Unregistering from push notifications" title="Direct link to Unregistering from push notifications"></a></h2><p>To unregister a client MUST send a <code>PushNotificationRegistration</code> request as described
above with <code>unregister</code> set to <code>true</code>, or removing
their device information.</p><p>The server MUST remove all data about this user if <code>unregistering</code> is <code>true</code>,
apart from the <code>hash</code> of the public key and the <code>version</code> of the last options,
in order to make sure that old messages are not processed.</p><p>A client MAY unregister from a server on explicit logout if multiple chat keys
are used on a single device.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="advertising-a-push-notification-server">Advertising a push notification server<a href="#advertising-a-push-notification-server" class="hash-link" aria-label="Direct link to Advertising a push notification server" title="Direct link to Advertising a push notification server"></a></h2><p>Each user registered with one or more push notification servers SHOULD
advertise periodically the push notification services that they have registered with for each device they own.</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationQueryInfo {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string access_token = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string installation_id = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes public_key = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated bytes allowed_user_list = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes grant = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> uint64 version = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes server_public_key = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message ContactCodeAdvertisement {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated PushNotificationQueryInfo push_notification_info = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>The message MUST be wrapped in a <a href="/status/deprecated/status/deprecated/payloads/#payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_QUERY_INFO</code>.</p><p>If no filtering is done based on public keys,
the access token SHOULD be included in the advertisement.
Otherwise it SHOULD be left empty.</p><p>This SHOULD be advertised on the <a href="/status/deprecated/waku-usage##contact-code-topic">contact code topic</a>
and SHOULD be coupled with normal contact-code advertisement.</p><p>Every time a user register or re-register with a push notification service, their
contact-code SHOULD be re-advertised.</p><p>Multiple servers MAY be advertised for the same <code>installation_id</code> for redundancy reasons.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="discovering-a-push-notification-server">Discovering a push notification server<a href="#discovering-a-push-notification-server" class="hash-link" aria-label="Direct link to Discovering a push notification server" title="Direct link to Discovering a push notification server"></a></h2><p>To discover a push notification service for a given user, their <a href="/status/deprecated/status/deprecated/waku-usage/#contact-code-topic">contact code topic</a>
SHOULD be listened to.
A mailserver can be queried for the specific topic to retrieve the most up-to-date
contact code.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="querying-the-push-notification-server">Querying the push notification server<a href="#querying-the-push-notification-server" class="hash-link" aria-label="Direct link to Querying the push notification server" title="Direct link to Querying the push notification server"></a></h2><p>If a token is not present in the latest advertisement for a user, the server
SHOULD be queried directly.</p><p>To query a server a message:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationQuery {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated bytes public_keys = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>The message MUST be wrapped in a <a href="/status/deprecated/status/deprecated/payloads/#payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_QUERY</code>.</p><p>MUST be sent to the server on the topic derived from the hashed public key of the
key we are querying, as <a href="#query-topic">described above</a>.</p><p>An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the <a href="/status/deprecated/status/deprecated/secure-transport">secure transport</a>.</p><p>If the server has information about the client a response MUST be sent:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationQueryInfo {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string access_token = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string installation_id = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes public_key = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated bytes allowed_user_list = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes grant = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> uint64 version = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes server_public_key = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationQueryResponse {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated PushNotificationQueryInfo info = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes message_id = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool success = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>A <code>PushNotificationQueryResponse</code> message MUST be wrapped in a <a href="/status/deprecated/status/deprecated/payloads##payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_QUERY_RESPONSE</code>.</p><p>Otherwise a response MUST NOT be sent.</p><p>If <code>allowed_key_list</code> is not set <code>access_token</code> MUST be set and <code>allowed_key_list</code> MUST NOT
be set.</p><p>If <code>allowed_key_list</code> is set <code>allowed_key_list</code> MUST be set and <code>access_token</code> MUST NOT be set.</p><p>If <code>access_token</code> is returned, the <code>access_token</code> SHOULD be used to send push notifications.</p><p>If <code>allowed_key_list</code> are returned, the client SHOULD decrypt each
token by generating an <code>AES-GCM</code> symmetric key from the DiffieHellman between the
target client and itself
If AES decryption succeeds it will return a valid <a href="https://tools.ietf.org/html/rfc4122" target="_blank" rel="noopener noreferrer"><code>uuid</code></a> which is what is used for access_token.
The token SHOULD be used to send push notifications.</p><p>The response MUST be sent on the <a href="/status/deprecated/status/deprecated/waku-usage/#partitioned-topic">partitioned topic</a> of the sender
and MUST not be encrypted using the <a href="/status/deprecated/status/deprecated/secure-transport">secure transport</a> to facilitate
the usage of ephemeral keys.</p><p>On receiving a response a client MUST verify <code>grant</code> to ensure that the server
has been authorized to send push notification to a given client.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="sending-a-push-notification">Sending a push notification<a href="#sending-a-push-notification" class="hash-link" aria-label="Direct link to Sending a push notification" title="Direct link to Sending a push notification"></a></h2><p>When sending a push notification, only the <code>installation_id</code> for the devices targeted
by the message SHOULD be used.</p><p>If a message is for all the user devices, all the <code>installation_id</code> known to the client MAY be used.</p><p>The number of devices MAY be capped in order to reduce resource consumption.</p><p>At least 3 devices SHOULD be targeted, ordered by last activity.</p><p>For any device that a token is available, or that a token is successfully queried,
a push notification message SHOULD be sent to the corresponding push notification server.</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotification {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string access_token = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string chat_id = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes public_key = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string installation_id = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes message = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> PushNotificationType type = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> enum PushNotificationType {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> UNKNOWN_PUSH_NOTIFICATION_TYPE = 0;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> MESSAGE = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> MENTION = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes author = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationRequest {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated PushNotification requests = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes message_id = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>A <code>PushNotificationRequest</code> message MUST be wrapped in a <a href="/status/deprecated/payloads##payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_REQUEST</code>.</p><p>Where <code>message</code> is the encrypted payload of the message and <code>chat_id</code> is the
<code>SHAKE-256</code> of the <code>chat_id</code>.
<code>message_id</code> is the id of the message
<code>author</code> is the <code>SHAKE-256</code> of the public key of the sender.</p><p>If multiple server are available for a given push notification, only one notification
MUST be sent.</p><p>If no response is received
a client SHOULD wait at least 3 seconds, after which the request MAY be retried against a different server</p><p>This message SHOULD be sent using an ephemeral key.</p><p>On receiving the message, the push notification server MUST validate the access token.
If the access token is valid, a notification MUST be sent to the gorush instance with the
following data:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">{</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;notifications&quot;: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;tokens&quot;: [&quot;token_a&quot;, &quot;token_b&quot;],</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;platform&quot;: 1,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;message&quot;: &quot;You have a new message&quot;,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;data&quot;: {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;chat_id&quot;: chat_id,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;message&quot;: message,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> &quot;installation_ids&quot;: [installation_id_1, installation_id_2]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>Where platform is <code>1</code> for IOS and <code>2</code> for Firebase, according to the <a href="https://github.com/appleboy/gorush" target="_blank" rel="noopener noreferrer">gorush documentation</a></p><p>A server MUST return a response message:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationReport {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool success = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ErrorType error = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> enum ErrorType {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> UNKNOWN_ERROR_TYPE = 0;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> WRONG_TOKEN = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> INTERNAL_ERROR = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> NOT_REGISTERED = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes public_key = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> string installation_id = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message PushNotificationResponse {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes message_id = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated PushNotificationReport reports = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>A <code>PushNotificationResponse</code> message MUST be wrapped in a <a href="/status/deprecated/payloads##payload-wrapper"><code>ApplicationMetadataMessage</code></a> with type set to <code>PUSH_NOTIFICATION_RESPONSE</code>.</p><p>Where <code>message_id</code> is the <code>message_id</code> sent by the client.</p><p>The response MUST be sent on the <a href="/status/deprecated/waku-usage##partitioned-topic">partitioned topic</a> of the sender
and MUST not be encrypted using the <a href="/status/deprecated/secure-transport">secure transport</a> to facilitate
the usage of ephemeral keys.</p><p>If the request is accepted <code>success</code> MUST be set to <code>true</code>.
Otherwise <code>success</code> MUST be set to <code>false</code>.</p><p>If <code>error</code> is <code>BAD_TOKEN</code> the client MAY query again the server for the token and
retry the request.</p><p>If <code>error</code> is <code>INTERNAL_ERROR</code> the client MAY retry the request.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="flow">Flow<a href="#flow" class="hash-link" aria-label="Direct link to Flow" title="Direct link to Flow"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="registration-process">Registration process<a href="#registration-process" class="hash-link" aria-label="Direct link to Registration process" title="Direct link to Registration process"></a></h3><ul><li>A client will generate a notification token through <code>APN</code> or <code>Firebase</code>.</li><li>The client will <a href="#registering-with-the-push-notification-service">register</a> with one or more push notification server of their choosing.</li><li>The server should process the response and respond according to the success of the operation</li><li>If the request is not successful it might be retried, and adjusted according to the response. A different server can be also used.</li><li>Once the request is successful the client should <a href="#advertising-a-push-notification-server">advertise</a> the new coordinates</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="sending-a-notification">Sending a notification<a href="#sending-a-notification" class="hash-link" aria-label="Direct link to Sending a notification" title="Direct link to Sending a notification"></a></h3><ul><li>A client should prepare a message and extract the targeted installation-ids</li><li>It should retrieve the most up to date information for a given user, either by
querying a push notification server, a mailserver if not listening already to the given topic, or checking
the database locally</li><li>It should then <a href="#sending-a-push-notification">send</a> a push notification according
to the rules described</li><li>The server should then send a request to the gorush server including all the required
information</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="receiving-a-push-notification">Receiving a push notification<a href="#receiving-a-push-notification" class="hash-link" aria-label="Direct link to Receiving a push notification" title="Direct link to Receiving a push notification"></a></h3><ul><li>On receiving the notification, a client can open the right account by checking the
<code>installation_id</code> included. The <code>chat_id</code> MAY be used to open the chat if present.</li><li><code>message</code> can be decrypted and presented to the user. Otherwise messages can be pulled from the mailserver if the <code>message_id</code> is no already present.</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="protobuf-description">Protobuf description<a href="#protobuf-description" class="hash-link" aria-label="Direct link to Protobuf description" title="Direct link to Protobuf description"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationregistration">PushNotificationRegistration<a href="#pushnotificationregistration" class="hash-link" aria-label="Direct link to PushNotificationRegistration" title="Direct link to PushNotificationRegistration"></a></h3><p><code>token_type</code>: the type of token. Currently supported is <code>APN_TOKEN</code> for Apple Push
<code>device_token</code>: the actual push notification token sent by <code>Firebase</code> or <code>APN</code>
and <code>FIREBASE_TOKEN</code> for firebase.
<code>installation_id</code>: the <a href="/status/deprecated/account"><code>installation_id</code></a> of the device
<code>access_token</code>: the access token that will be given to clients to send push notifications
<code>enabled</code>: whether the device wants to be sent push notifications
<code>version</code>: a monotonically increasing number identifying the current <code>PushNotificationRegistration</code>. Any time anything is changed in the record it MUST be increased by the client, otherwise the request will not be accepted.
<code>allowed_key_list</code>: a list of <code>access_token</code> encrypted with the AES key generated
by DiffieHellman between the publisher and the allowed
contact.
<code>blocked_chat_list</code>: a list of <code>SHA2-256</code> hashes of chat ids.
Any chat id in this list will not trigger a notification.
<code>unregister</code>: whether the account should be unregistered
<code>grant</code>: the grant for this specific server
<code>allow_from_contacts_only</code>: whether the client only wants push notifications from contacts
<code>apn_topic</code>: the APN topic for the push notification
<code>block_mentions</code>: whether the client does not want to be notified on mentions
<code>allowed_mentions_chat_list</code>: a list of <code>SHA2-256</code> hashes of chat ids where we want to receive mentions</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="data-disclosed">Data disclosed<a href="#data-disclosed" class="hash-link" aria-label="Direct link to Data disclosed" title="Direct link to Data disclosed"></a></h4><ul><li>Type of device owned by a given user</li><li>The <code>FIREBASE</code> or <code>APN</code> push notification token</li><li>Hash of the chat_id a user is not interested in for notifications</li><li>The times a push notification record has been modified by the user</li><li>The number of contacts a client has, in case <code>allowed_key_list</code> is set</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationregistrationresponse">PushNotificationRegistrationResponse<a href="#pushnotificationregistrationresponse" class="hash-link" aria-label="Direct link to PushNotificationRegistrationResponse" title="Direct link to PushNotificationRegistrationResponse"></a></h3><p><code>success</code>: whether the registration was successful
<code>error</code>: the error type, if any
<code>request_id</code>: the <code>SHAKE-256</code> hash of the <code>signature</code> of the request
<code>preferences</code>: the server stored preferences in case of an error</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="contactcodeadvertisement">ContactCodeAdvertisement<a href="#contactcodeadvertisement" class="hash-link" aria-label="Direct link to ContactCodeAdvertisement" title="Direct link to ContactCodeAdvertisement"></a></h3><p><code>push_notification_info</code>: the information for each device advertised</p><p>Data disclosed</p><ul><li>The chat key of the sender</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationquery">PushNotificationQuery<a href="#pushnotificationquery" class="hash-link" aria-label="Direct link to PushNotificationQuery" title="Direct link to PushNotificationQuery"></a></h3><p><code>public_keys</code>: the <code>SHAKE-256</code> of the public keys the client is interested in</p><p>Data disclosed</p><ul><li>The hash of the public keys the client is interested in</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationqueryinfo">PushNotificationQueryInfo<a href="#pushnotificationqueryinfo" class="hash-link" aria-label="Direct link to PushNotificationQueryInfo" title="Direct link to PushNotificationQueryInfo"></a></h3><p><code>access_token</code>: the access token used to send a push notification
<code>installation_id</code>: the <code>installation_id</code> of the device associated with the <code>access_token</code>
<code>public_key</code>: the <code>SHAKE-256</code> of the public key associated with this <code>access_token</code> and <code>installation_id</code>
<code>allowed_key_list</code>: a list of encrypted access tokens to be returned
to the client in case there&#x27;s any filtering on public keys in place.
<code>grant</code>: the grant used to register with this server.
<code>version</code>: the version of the registration on the server.
<code>server_public_key</code>: the compressed public key of the server.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationqueryresponse">PushNotificationQueryResponse<a href="#pushnotificationqueryresponse" class="hash-link" aria-label="Direct link to PushNotificationQueryResponse" title="Direct link to PushNotificationQueryResponse"></a></h3><p><code>info</code>: a list of <code>PushNotificationQueryInfo</code>.
<code>message_id</code>: the message id of the <code>PushNotificationQueryInfo</code> the server is replying to.
<code>success</code>: whether the query was successful.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotification">PushNotification<a href="#pushnotification" class="hash-link" aria-label="Direct link to PushNotification" title="Direct link to PushNotification"></a></h3><p><code>access_token</code>: the access token used to send a push notification.
<code>chat_id</code>: the <code>SHAKE-256</code> of the <code>chat_id</code>.
<code>public_key</code>: the <code>SHAKE-256</code> of the compressed public key of the receiving client.
<code>installation_id</code>: the installation id of the receiving client.
<code>message</code>: the encrypted message that is being notified on.
<code>type</code>: the type of the push notification, either <code>MESSAGE</code> or <code>MENTION</code>
<code>author</code>: the <code>SHAKE-256</code> of the public key of the sender</p><p>Data disclosed</p><ul><li>The <code>SHAKE-256</code> of the <code>chat_id</code> the notification is to be sent for</li><li>The cypher text of the message</li><li>The <code>SHAKE-256</code> of the public key of the sender</li><li>The type of notification</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationrequest">PushNotificationRequest<a href="#pushnotificationrequest" class="hash-link" aria-label="Direct link to PushNotificationRequest" title="Direct link to PushNotificationRequest"></a></h3><p><code>requests</code>: a list of <code>PushNotification</code>
<code>message_id</code>: the <a href="/status/deprecated/payloads">status message id</a></p><p>Data disclosed</p><ul><li>The status message id for which the notification is for</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationresponse">PushNotificationResponse<a href="#pushnotificationresponse" class="hash-link" aria-label="Direct link to PushNotificationResponse" title="Direct link to PushNotificationResponse"></a></h3><p><code>message_id</code>: the <code>message_id</code> being notified on.
<code>reports</code>: a list of <code>PushNotificationReport</code></p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pushnotificationreport">PushNotificationReport<a href="#pushnotificationreport" class="hash-link" aria-label="Direct link to PushNotificationReport" title="Direct link to PushNotificationReport"></a></h3><p><code>success</code>: whether the push notification was successful.
<code>error</code>: the type of the error in case of failure.
<code>public_key</code>: the public key of the user being notified.
<code>installation_id</code>: the installation id of the user being notified.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="anonymous-mode-of-operations">Anonymous mode of operations<a href="#anonymous-mode-of-operations" class="hash-link" aria-label="Direct link to Anonymous mode of operations" title="Direct link to Anonymous mode of operations"></a></h2><p>An anonymous mode of operations MAY be provided by the client, where the
responsibility of propagating information about the user is left to the client,
in order to preserve privacy.</p><p>A client in anonymous mode can register with the server using a key different
from their chat key.
This will hide their real chat key.</p><p>This public key is effectively a secret and SHOULD only be disclosed to clients that you the user wants to be notified by.</p><p>A client MAY advertise the access token on the contact-code topic of the key generated.
A client MAY share their public key through <a href="/status/deprecated/payloads##contact-update">contact updates</a></p><p>A client receiving a push notification public key SHOULD listen to the contact code
topic of the push notification public key for updates.</p><p>The method described above effectively does not share the identity of the sender
nor the receiver to the server, but MAY result in missing push notifications as
the propagation of the secret is left to the client.</p><p>This can be mitigated by <a href="/status/deprecated/payloads">device syncing</a>, but not completely
addressed.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-considerations">Security considerations<a href="#security-considerations" class="hash-link" aria-label="Direct link to Security considerations" title="Direct link to Security considerations"></a></h2><p>If no anonymous mode is used, when registering with a push notification service a client discloses:</p><ul><li>The chat key</li><li>The devices that will receive notifications</li></ul><p>A client MAY disclose:</p><ul><li>The hash of the chat_ids they want to filter out</li></ul><p>When running in anonymous mode, the client&#x27;s chat key is not disclosed.</p><p>When querying a push notification server a client will disclose:</p><ul><li>That it is interested in sending push notification to another client,
but the querying client&#x27;s chat key is not disclosed</li></ul><p>When sending a push notification a client discloses:</p><ul><li>The <code>SHAKE-256</code> of the chat id</li></ul><p>[//]: This section can be removed, for now leaving it here in order to help with the
review process. Point can be integrated, suggestion welcome.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="faq">FAQ<a href="#faq" class="hash-link" aria-label="Direct link to FAQ" title="Direct link to FAQ"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-having-acl-done-at-the-server-side-and-not-the-client">Why having ACL done at the server side and not the client?<a href="#why-having-acl-done-at-the-server-side-and-not-the-client" class="hash-link" aria-label="Direct link to Why having ACL done at the server side and not the client?" title="Direct link to Why having ACL done at the server side and not the client?"></a></h3><p>We looked into silent notification for
<a href="https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app" target="_blank" rel="noopener noreferrer">IOS</a> (android has no equivalent)
but can&#x27;t be used as it&#x27;s expected to receive maximum 2/3 per hour, so not our use case. There
are also issue when the user force quit the app.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-using-an-access-token">Why using an access token?<a href="#why-using-an-access-token" class="hash-link" aria-label="Direct link to Why using an access token?" title="Direct link to Why using an access token?"></a></h3><p>The access token is used to decouple the requesting information from the user from
actually sending the push notification.</p><p>Some ACL is necessary otherwise it would be too easy to spam users (it&#x27;s still fairly
trivial, but with this method you could allow only contacts to send you push notifications).</p><p>Therefore your identity must be revealed to the server either when sending or querying.</p><p>By using an access token we increase deniability, as the server would know
who requested the token but not necessarily who sent a push notification.
Correlation between the two can be trivial in some cases.</p><p>This also allows a mode of use as we had before, where the server does not propagate
info at all, and it&#x27;s left to the user to propagate the token, through contact requests
for example.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-advertise-with-the-bundle">Why advertise with the bundle?<a href="#why-advertise-with-the-bundle" class="hash-link" aria-label="Direct link to Why advertise with the bundle?" title="Direct link to Why advertise with the bundle?"></a></h3><p>Advertising with the bundle allows us to piggy-back on an already implemented behavior
and save some bandwidth in cases where is not filtering by public keys</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="whats-the--bandwidth-impact-for-this">What&#x27;s the bandwidth impact for this?<a href="#whats-the--bandwidth-impact-for-this" class="hash-link" aria-label="Direct link to What&#x27;s the bandwidth impact for this?" title="Direct link to What&#x27;s the bandwidth impact for this?"></a></h3><p>Generally speaking, for each 1-to-1 message and group chat message you will sending
1 and <code>number of participants</code> push notifications. This can be optimized if
multiple users are using the same push notification server. Queries have also
a bandwidth impact but they are made only when actually needed</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="whats-the-information-disclosed">What&#x27;s the information disclosed?<a href="#whats-the-information-disclosed" class="hash-link" aria-label="Direct link to What&#x27;s the information disclosed?" title="Direct link to What&#x27;s the information disclosed?"></a></h3><p>The data disclosed with each message sent by the client is above, but for a summary:</p><p>When you register with a push notification service you may disclose:</p><p>1) Your chat key
2) Which devices you have
3) The hash of the chat_ids you want to filter out
4) The hash of the public keys you are interested/not interested in</p><p>When you query a notification service you may disclose:</p><p>1) Your chat key
2) The fact that you are interested in sending push notification to a given user</p><p>Effectively this is fairly revealing if the user has a whitelist implemented.
Therefore sending notification should be optional.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-prevents-a-user-from-generating-a-random-key-and-getting-an-access-token-and-spamming">What prevents a user from generating a random key and getting an access token and spamming?<a href="#what-prevents-a-user-from-generating-a-random-key-and-getting-an-access-token-and-spamming" class="hash-link" aria-label="Direct link to What prevents a user from generating a random key and getting an access token and spamming?" title="Direct link to What prevents a user from generating a random key and getting an access token and spamming?"></a></h3><p>Nothing really, that&#x27;s the same as the status app as a whole. the only mechanism that prevents
this is using a white-list as described above,
but that implies disclosing your true identity to the push notification server.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-not-0-knowledge-proofsquantum-computing">Why not 0-knowledge proofs/quantum computing<a href="#why-not-0-knowledge-proofsquantum-computing" class="hash-link" aria-label="Direct link to Why not 0-knowledge proofs/quantum computing" title="Direct link to Why not 0-knowledge proofs/quantum computing"></a></h3><p>We start simple, we can iterate</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="how-to-handle-backwardforward-compatibility">How to handle backward/forward compatibility<a href="#how-to-handle-backwardforward-compatibility" class="hash-link" aria-label="Direct link to How to handle backward/forward compatibility" title="Direct link to How to handle backward/forward compatibility"></a></h3><p>Most of the request have a target, so protocol negotiation can happen. We cannot negotiated
the advertisement as that&#x27;s effectively a broadcast, but those info should not change and we can
always accrete the message.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-ack_key">Why ack_key?<a href="#why-ack_key" class="hash-link" aria-label="Direct link to Why ack_key?" title="Direct link to Why ack_key?"></a></h3><p>That&#x27;s necessary to avoid duplicated push notifications and allow for the retry
in case the notification is not successful.</p><p>Deduplication of the push notification is done on the client side, to reduce a bit
of centralization and also in order not to have to modify gorush.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="can-i-run-my-own-node">Can I run my own node?<a href="#can-i-run-my-own-node" class="hash-link" aria-label="Direct link to Can I run my own node?" title="Direct link to Can I run my own node?"></a></h3><p>Sure, the methods allow that</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="can-i-register-with-multiple-nodes-for-redundancy">Can I register with multiple nodes for redundancy<a href="#can-i-register-with-multiple-nodes-for-redundancy" class="hash-link" aria-label="Direct link to Can I register with multiple nodes for redundancy" title="Direct link to Can I register with multiple nodes for redundancy"></a></h3><p>Yep</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-does-my-node-disclose">What does my node disclose?<a href="#what-does-my-node-disclose" class="hash-link" aria-label="Direct link to What does my node disclose?" title="Direct link to What does my node disclose?"></a></h3><p>Your node will disclose the IP address is running from, as it makes an HTTP post to
gorush. A waku adapter could be used, but please not now.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="does-this-have-high-reliability-requirements">Does this have high-reliability requirements?<a href="#does-this-have-high-reliability-requirements" class="hash-link" aria-label="Direct link to Does this have high-reliability requirements?" title="Direct link to Does this have high-reliability requirements?"></a></h3><p>The gorush server yes, no way around it.</p><p>The rest, kind of, at least one node having your token needs to be up for you to receive notifications.
But you can register with multiple servers (desktop, status, etc) if that&#x27;s a concern.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="can-someone-else-ie-not-status-run-this">Can someone else (i.e not status) run this?<a href="#can-someone-else-ie-not-status-run-this" class="hash-link" aria-label="Direct link to Can someone else (i.e not status) run this?" title="Direct link to Can someone else (i.e not status) run this?"></a></h3><p>Push notification servers can be run by anyone. Gorush can be run by anyone I take,
but we are in charge of the certificate, so they would not be able to notify status-clients.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="changelog">Changelog<a href="#changelog" class="hash-link" aria-label="Direct link to Changelog" title="Direct link to Changelog"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="version-01">Version 0.1<a href="#version-01" class="hash-link" aria-label="Direct link to Version 0.1" title="Direct link to Version 0.1"></a></h3><p><a href="https://github.com/status-im/specs/commit/" target="_blank" rel="noopener noreferrer">Released</a></p><ul><li>Initial version</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="copyright">Copyright<a href="#copyright" class="hash-link" aria-label="Direct link to Copyright" title="Direct link to Copyright"></a></h2><p>Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/" target="_blank" rel="noopener noreferrer">CC0</a>.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="references">References<a href="#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References"></a></h2><ul><li><a href="https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1" target="_blank" rel="noopener noreferrer">APN Service</a></li><li><a href="https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/updating_your_app_with_background_app_refresh" target="_blank" rel="noopener noreferrer">Background Execution on iOS</a></li><li><a href="https://firebase.google.com/" target="_blank" rel="noopener noreferrer">Firebase</a></li><li><a href="https://github.com/appleboy/gorush" target="_blank" rel="noopener noreferrer">Gorush</a></li><li><a href="https://tools.ietf.org/html/rfc4122" target="_blank" rel="noopener noreferrer">UUID Specification</a></li><li><a href="/status/deprecated/secure-transport">Secure Transport</a></li><li><a href="https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app" target="_blank" rel="noopener noreferrer">Silent Notifications on iOS</a></li><li><a href="/status/deprecated/waku-usage">Waku Usage</a></li><li><a href="https://github.com/ensdomains/ens" target="_blank" rel="noopener noreferrer">ENS Contract</a></li><li><a href="/status/deprecated/payloads">Payloads</a></li></ul></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/status/deprecated/payloads"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">PAYLOADS</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/status/deprecated/secure-transport"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">SECURE-TRANSPORT</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></div></div><div class="gap1_XuuQ"></div><div class="toc_pP_5"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#reason" class="table-of-contents__link toc-highlight">Reason</a></li><li><a href="#requirements" class="table-of-contents__link toc-highlight">Requirements</a></li><li><a href="#components" class="table-of-contents__link toc-highlight">Components</a><ul><li><a href="#gorush-instance" class="table-of-contents__link toc-highlight">Gorush instance</a></li><li><a href="#push-notification-server" class="table-of-contents__link toc-highlight">Push notification server</a></li><li><a href="#registering-client" class="table-of-contents__link toc-highlight">Registering client</a></li><li><a href="#sending-client" class="table-of-contents__link toc-highlight">Sending client</a></li></ul></li><li><a href="#registering-with-the-push-notification-service" class="table-of-contents__link toc-highlight">Registering with the push notification service</a><ul><li><a href="#query-topic" class="table-of-contents__link toc-highlight">Query topic</a></li><li><a href="#server-grant" class="table-of-contents__link toc-highlight">Server grant</a></li></ul></li><li><a href="#re-registering-with-the-push-notification-server" class="table-of-contents__link toc-highlight">Re-registering with the push notification server</a></li><li><a href="#changing-options" class="table-of-contents__link toc-highlight">Changing options</a></li><li><a href="#unregistering-from-push-notifications" class="table-of-contents__link toc-highlight">Unregistering from push notifications</a></li><li><a href="#advertising-a-push-notification-server" class="table-of-contents__link toc-highlight">Advertising a push notification server</a></li><li><a href="#discovering-a-push-notification-server" class="table-of-contents__link toc-highlight">Discovering a push notification server</a></li><li><a href="#querying-the-push-notification-server" class="table-of-contents__link toc-highlight">Querying the push notification server</a></li><li><a href="#sending-a-push-notification" class="table-of-contents__link toc-highlight">Sending a push notification</a></li><li><a href="#flow" class="table-of-contents__link toc-highlight">Flow</a><ul><li><a href="#registration-process" class="table-of-contents__link toc-highlight">Registration process</a></li><li><a href="#sending-a-notification" class="table-of-contents__link toc-highlight">Sending a notification</a></li><li><a href="#receiving-a-push-notification" class="table-of-contents__link toc-highlight">Receiving a push notification</a></li></ul></li><li><a href="#protobuf-description" class="table-of-contents__link toc-highlight">Protobuf description</a><ul><li><a href="#pushnotificationregistration" class="table-of-contents__link toc-highlight">PushNotificationRegistration</a></li><li><a href="#pushnotificationregistrationresponse" class="table-of-contents__link toc-highlight">PushNotificationRegistrationResponse</a></li><li><a href="#contactcodeadvertisement" class="table-of-contents__link toc-highlight">ContactCodeAdvertisement</a></li><li><a href="#pushnotificationquery" class="table-of-contents__link toc-highlight">PushNotificationQuery</a></li><li><a href="#pushnotificationqueryinfo" class="table-of-contents__link toc-highlight">PushNotificationQueryInfo</a></li><li><a href="#pushnotificationqueryresponse" class="table-of-contents__link toc-highlight">PushNotificationQueryResponse</a></li><li><a href="#pushnotification" class="table-of-contents__link toc-highlight">PushNotification</a></li><li><a href="#pushnotificationrequest" class="table-of-contents__link toc-highlight">PushNotificationRequest</a></li><li><a href="#pushnotificationresponse" class="table-of-contents__link toc-highlight">PushNotificationResponse</a></li><li><a href="#pushnotificationreport" class="table-of-contents__link toc-highlight">PushNotificationReport</a></li></ul></li><li><a href="#anonymous-mode-of-operations" class="table-of-contents__link toc-highlight">Anonymous mode of operations</a></li><li><a href="#security-considerations" class="table-of-contents__link toc-highlight">Security considerations</a></li><li><a href="#faq" class="table-of-contents__link toc-highlight">FAQ</a><ul><li><a href="#why-having-acl-done-at-the-server-side-and-not-the-client" class="table-of-contents__link toc-highlight">Why having ACL done at the server side and not the client?</a></li><li><a href="#why-using-an-access-token" class="table-of-contents__link toc-highlight">Why using an access token?</a></li><li><a href="#why-advertise-with-the-bundle" class="table-of-contents__link toc-highlight">Why advertise with the bundle?</a></li><li><a href="#whats-the--bandwidth-impact-for-this" class="table-of-contents__link toc-highlight">What&#39;s the bandwidth impact for this?</a></li><li><a href="#whats-the-information-disclosed" class="table-of-contents__link toc-highlight">What&#39;s the information disclosed?</a></li><li><a href="#what-prevents-a-user-from-generating-a-random-key-and-getting-an-access-token-and-spamming" class="table-of-contents__link toc-highlight">What prevents a user from generating a random key and getting an access token and spamming?</a></li><li><a href="#why-not-0-knowledge-proofsquantum-computing" class="table-of-contents__link toc-highlight">Why not 0-knowledge proofs/quantum computing</a></li><li><a href="#how-to-handle-backwardforward-compatibility" class="table-of-contents__link toc-highlight">How to handle backward/forward compatibility</a></li><li><a href="#why-ack_key" class="table-of-contents__link toc-highlight">Why ack_key?</a></li><li><a href="#can-i-run-my-own-node" class="table-of-contents__link toc-highlight">Can I run my own node?</a></li><li><a href="#can-i-register-with-multiple-nodes-for-redundancy" class="table-of-contents__link toc-highlight">Can I register with multiple nodes for redundancy</a></li><li><a href="#what-does-my-node-disclose" class="table-of-contents__link toc-highlight">What does my node disclose?</a></li><li><a href="#does-this-have-high-reliability-requirements" class="table-of-contents__link toc-highlight">Does this have high-reliability requirements?</a></li><li><a href="#can-someone-else-ie-not-status-run-this" class="table-of-contents__link toc-highlight">Can someone else (i.e not status) run this?</a></li></ul></li><li><a href="#changelog" class="table-of-contents__link toc-highlight">Changelog</a><ul><li><a href="#version-01" class="table-of-contents__link toc-highlight">Version 0.1</a></li></ul></li><li><a href="#copyright" class="table-of-contents__link toc-highlight">Copyright</a></li><li><a href="#references" class="table-of-contents__link toc-highlight">References</a></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--light_BL8e footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--dark_OvIx footer__logo" width="22"></a></div><div class="footer__copyright">Vac @2025<br>All Rights Reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://x.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work with us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms &amp; conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><span class="footer__bottom text--center">Built by <a href="https://free.technology/" target="_blank" class="footerLink_sh7M">IFT</a></span><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div>
<script src="/assets/js/runtime~main.db01e95f.js"></script>
<script src="/assets/js/main.7bd63d25.js"></script>
</body>
</html>