-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsse.html
More file actions
226 lines (224 loc) · 142 KB
/
Copy pathsse.html
File metadata and controls
226 lines (224 loc) · 142 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Server-Sent Events Guide | NpgsqlRest</title>
<meta name="description" content="Push real-time updates from PostgreSQL to the browser with NpgsqlRest. How SSE endpoints work, how RAISE statements broadcast events, scopes and levels, per-recipient targeting, and a complete chat example.">
<meta name="generator" content="VitePress v1.6.4">
<link rel="preload stylesheet" href="/assets/style.LpuNvTwL.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.VN9qkxsN.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/theme.CbCjZi0Y.js">
<link rel="modulepreload" href="/assets/chunks/framework.CgT1UzWm.js">
<link rel="modulepreload" href="/assets/guide_sse.md.CCeiNuHG.lean.js">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="/favicon.ico">
<meta property="og:url" content="https://npgsqlrest.github.io">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="NpgsqlRest - Automatic PostgreSQL Web Server">
<meta name="twitter:description" content="Create REST APIs for PostgreSQL databases in minutes. Zero code, zero config, automatic endpoints from your database schema.">
<script defer data-id="101498393" src="//static.getclicky.com/js"></script>
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
<meta name="keywords" content="npgsqlrest sse, server-sent events postgresql, real-time postgresql, raise notice sse, eventsource postgresql, postgresql push notifications">
<meta property="og:title" content="NpgsqlRest Server-Sent Events Guide">
<meta property="og:description" content="Push real-time updates from PostgreSQL to the browser with Server-Sent Events.">
<meta property="og:type" content="article">
</head>
<body>
<div id="app"><div class="Layout" data-v-5d98c3a5><!--[--><!--]--><!--[--><span tabindex="-1" data-v-0b0ada53></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-0b0ada53>Skip to content</a><!--]--><!----><header class="VPNav" data-v-5d98c3a5 data-v-ae24b3ad><div class="VPNavBar" data-v-ae24b3ad data-v-6aa21345><div class="wrapper" data-v-6aa21345><div class="container" data-v-6aa21345><div class="title" data-v-6aa21345><div class="VPNavBarTitle has-sidebar" data-v-6aa21345 data-v-1168a8e4><a class="title" href="/" data-v-1168a8e4><!--[--><!--]--><!--[--><img class="VPImage logo" src="/favicon.ico" alt data-v-8426fc1a><!--]--><span data-v-1168a8e4>NpgsqlRest</span><!--[--><!--]--></a></div></div><div class="content" data-v-6aa21345><div class="content-body" data-v-6aa21345><!--[--><!--]--><div class="VPNavBarSearch search" data-v-6aa21345><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-6aa21345 data-v-dc692963><span id="main-nav-aria-label" class="visually-hidden" data-v-dc692963> Main Navigation </span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup active" data-v-dc692963 data-v-cf11d7a2><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-cf11d7a2><span class="text" data-v-cf11d7a2><!----><span data-v-cf11d7a2>Guide</span><span class="vpi-chevron-down text-icon" data-v-cf11d7a2></span></span></button><div class="menu" data-v-cf11d7a2><div class="VPMenu" data-v-cf11d7a2 data-v-b98bc113><div class="items" data-v-b98bc113><!--[--><!--[--><div class="VPMenuGroup" data-v-b98bc113 data-v-69e747b5><p class="title" data-v-69e747b5>Getting Started</p><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/" data-v-35975db6><!--[--><span data-v-35975db6>Overview</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/installation.html" data-v-35975db6><!--[--><span data-v-35975db6>Installation</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/quick-start.html" data-v-35975db6><!--[--><span data-v-35975db6>Quick Start</span><!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-b98bc113 data-v-69e747b5><p class="title" data-v-69e747b5>Topics</p><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/sql-files.html" data-v-35975db6><!--[--><span data-v-35975db6>SQL File Endpoints</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/configuration.html" data-v-35975db6><!--[--><span data-v-35975db6>Configuration Guide</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/annotations.html" data-v-35975db6><!--[--><span data-v-35975db6>Comment Annotations Guide</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/authentication.html" data-v-35975db6><!--[--><span data-v-35975db6>Authentication</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link active" href="/guide/sse.html" data-v-35975db6><!--[--><span data-v-35975db6>Server-Sent Events</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/http-types.html" data-v-35975db6><!--[--><span data-v-35975db6>HTTP Custom Types</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/proxy.html" data-v-35975db6><!--[--><span data-v-35975db6>Proxy Endpoints</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/testing.html" data-v-35975db6><!--[--><span data-v-35975db6>Testing</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/logging.html" data-v-35975db6><!--[--><span data-v-35975db6>Logging</span><!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-b98bc113 data-v-69e747b5><p class="title" data-v-69e747b5>Reference</p><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/faq.html" data-v-35975db6><!--[--><span data-v-35975db6>FAQ & Troubleshooting</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-35975db6><a class="VPLink link" href="/guide/changelog/" data-v-35975db6><!--[--><span data-v-35975db6>Changelog</span><!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/examples/" tabindex="0" data-v-dc692963 data-v-e56f3d57><!--[--><span data-v-e56f3d57>Examples</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-dc692963 data-v-cf11d7a2><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-cf11d7a2><span class="text" data-v-cf11d7a2><!----><span data-v-cf11d7a2>Reference</span><span class="vpi-chevron-down text-icon" data-v-cf11d7a2></span></span></button><div class="menu" data-v-cf11d7a2><div class="VPMenu" data-v-cf11d7a2 data-v-b98bc113><div class="items" data-v-b98bc113><!--[--><!--[--><div class="VPMenuLink" data-v-b98bc113 data-v-35975db6><a class="VPLink link" href="/annotations/" data-v-35975db6><!--[--><span data-v-35975db6>Annotations</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b98bc113 data-v-35975db6><a class="VPLink link" href="/config/" data-v-35975db6><!--[--><span data-v-35975db6>Configuration</span><!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/blog/" tabindex="0" data-v-dc692963 data-v-e56f3d57><!--[--><span data-v-e56f3d57>Blog</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-6aa21345 data-v-6c893767><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-6c893767 data-v-5337faa4 data-v-1d5665e3><span class="check" data-v-1d5665e3><span class="icon" data-v-1d5665e3><!--[--><span class="vpi-sun sun" data-v-5337faa4></span><span class="vpi-moon moon" data-v-5337faa4></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-6aa21345 data-v-0394ad82 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/NpgsqlRest/NpgsqlRest" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><span class="vpi-social-github"></span></a><a class="VPSocialLink no-icon" href="https://patreon.com/vbconsulting" aria-label="Patreon" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 7.463 3.097 9.746 2.602 2.124 6.19 2.078 9.402 1.836 1.883-.142 3.939-.358 5.477-1.528 1.564-1.19 1.873-3.298 1.972-5.151.134-2.51.187-5.016-.037-7.233zm-2.55 7.703c-.078 1.593-.383 3.473-1.795 4.334-1.351.824-3.151.973-4.686 1.083-2.891.207-6.063.276-8.514-1.399C3.106 17.39 2.924 14.34 2.95 11.67c.03-3.206.678-6.721 3.654-8.375 2.756-1.531 6.556-1.727 9.544-.872 2.339.669 4.351 2.678 4.355 5.217.007 2.583-.016 5.168-.095 7.273z"/><path d="M16.088 5.19c-1.008-.542-2.607-.48-3.441.388-.568.591-.773 1.389-.8 2.172-.034.993.068 2.013.361 2.953.307.985 1.034 1.848 2.077 2.012.878.138 1.83-.088 2.458-.732.7-.718.88-1.81.877-2.779-.003-.989-.084-1.99-.423-2.91-.268-.726-.654-1.328-1.109-1.104zm-.294 5.482c-.182.462-.581.771-1.091.696-.532-.078-.859-.533-1.04-1.005-.248-.647-.327-1.375-.312-2.06.01-.46.095-.939.371-1.313.345-.467.993-.447 1.426-.115.41.315.607.835.74 1.32.18.66.211 1.675-.094 2.477zM8.4 10.394c.233 1.084.755 2.299 1.907 2.579.934.227 1.993-.165 2.434-1.048.455-.91.346-1.995.166-2.972-.165-.893-.46-1.885-1.207-2.445-.745-.559-1.832-.457-2.479.192-.84.843-.958 2.138-.955 3.277.001.147.119.364.134.417zm1.363-2.808c.302-.321.805-.336 1.14-.054.445.375.618 1.015.75 1.558.131.54.212 1.156.082 1.703-.1.423-.378.821-.84.882-.469.062-.886-.306-1.088-.704-.326-.644-.401-1.426-.381-2.148.013-.465.104-.993.337-1.237z"/></svg></a><a class="VPSocialLink no-icon" href="https://buymeacoffee.com/vbilopavu" aria-label="Buy Me a Coffee" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.216 6.415l-.132-.666c-.119-.598-.388-1.163-1.001-1.379-.197-.069-.42-.098-.57-.241-.152-.143-.196-.366-.231-.572-.065-.378-.125-.756-.192-1.133-.057-.325-.102-.69-.25-.987-.195-.4-.597-.634-.996-.788a5.723 5.723 0 00-.626-.194c-1-.263-2.05-.36-3.077-.416a25.834 25.834 0 00-3.7.062c-.915.083-1.88.184-2.75.5-.318.116-.646.256-.888.501-.297.302-.393.77-.177 1.146.154.267.415.456.692.58.36.162.737.284 1.123.366 1.075.238 2.189.331 3.287.37 1.218.05 2.437.01 3.65-.118.299-.033.598-.073.896-.119.352-.054.578-.513.474-.834-.124-.383-.457-.531-.834-.473-.466.074-.96.108-1.382.146-1.177.08-2.358.082-3.536.006a22.228 22.228 0 01-1.157-.107c-.086-.01-.18-.025-.258-.036-.243-.036-.484-.08-.724-.13-.111-.027-.111-.185 0-.212h.005c.277-.06.557-.108.838-.147h.002c.131-.009.263-.032.394-.048a25.076 25.076 0 013.426-.12c.674.019 1.347.067 2.017.144l.228.031c.267.04.533.088.798.145.392.085.895.113 1.07.542.055.137.08.288.111.431l.319 1.484a.237.237 0 01-.199.284h-.003c-.037.006-.075.01-.112.015a36.704 36.704 0 01-4.743.295 37.059 37.059 0 01-4.699-.304c-.14-.017-.293-.042-.417-.06-.326-.048-.649-.108-.973-.161-.393-.065-.768-.032-1.123.161-.29.16-.527.404-.675.701-.154.316-.199.66-.267 1-.069.34-.176.707-.135 1.056.087.753.613 1.365 1.37 1.502a39.69 39.69 0 0011.343.376.483.483 0 01.535.53l-.071.697-1.018 9.907c-.041.41-.047.832-.125 1.237-.122.637-.553 1.028-1.182 1.171-.577.131-1.165.2-1.756.205-.656.004-1.31-.025-1.966-.022-.699.004-1.556-.06-2.095-.58-.475-.458-.54-1.174-.605-1.793l-.731-7.013-.322-3.094c-.037-.351-.286-.695-.678-.678-.336.015-.718.3-.678.679l.228 2.185.949 9.112c.147 1.344 1.174 2.068 2.446 2.272.742.12 1.503.144 2.257.156.966.016 1.942.053 2.892-.122 1.408-.258 2.465-1.198 2.616-2.657.34-3.332.683-6.663 1.024-9.995l.215-2.087a.484.484 0 01.39-.426c.402-.078.787-.212 1.074-.518.455-.488.546-1.124.385-1.766zm-1.478.772c-.145.137-.363.201-.578.233-2.416.359-4.866.54-7.308.46-1.748-.06-3.477-.254-5.207-.498-.17-.024-.353-.055-.47-.18-.22-.236-.111-.71-.054-.995.052-.26.152-.609.463-.646.484-.057 1.046.148 1.526.22.577.088 1.156.159 1.737.212 2.48.226 5.002.19 7.472-.14.45-.06.899-.13 1.345-.21.399-.072.84-.206 1.08.206.166.281.188.657.162.974a.544.544 0 01-.169.364z"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-6aa21345 data-v-bb2aa2f0 data-v-cf11d7a2><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-cf11d7a2><span class="vpi-more-horizontal icon" data-v-cf11d7a2></span></button><div class="menu" data-v-cf11d7a2><div class="VPMenu" data-v-cf11d7a2 data-v-b98bc113><!----><!--[--><!--[--><!----><div class="group" data-v-bb2aa2f0><div class="item appearance" data-v-bb2aa2f0><p class="label" data-v-bb2aa2f0>Appearance</p><div class="appearance-action" data-v-bb2aa2f0><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-bb2aa2f0 data-v-5337faa4 data-v-1d5665e3><span class="check" data-v-1d5665e3><span class="icon" data-v-1d5665e3><!--[--><span class="vpi-sun sun" data-v-5337faa4></span><span class="vpi-moon moon" data-v-5337faa4></span><!--]--></span></span></button></div></div></div><div class="group" data-v-bb2aa2f0><div class="item social-links" data-v-bb2aa2f0><div class="VPSocialLinks social-links-list" data-v-bb2aa2f0 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/NpgsqlRest/NpgsqlRest" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><span class="vpi-social-github"></span></a><a class="VPSocialLink no-icon" href="https://patreon.com/vbconsulting" aria-label="Patreon" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 7.463 3.097 9.746 2.602 2.124 6.19 2.078 9.402 1.836 1.883-.142 3.939-.358 5.477-1.528 1.564-1.19 1.873-3.298 1.972-5.151.134-2.51.187-5.016-.037-7.233zm-2.55 7.703c-.078 1.593-.383 3.473-1.795 4.334-1.351.824-3.151.973-4.686 1.083-2.891.207-6.063.276-8.514-1.399C3.106 17.39 2.924 14.34 2.95 11.67c.03-3.206.678-6.721 3.654-8.375 2.756-1.531 6.556-1.727 9.544-.872 2.339.669 4.351 2.678 4.355 5.217.007 2.583-.016 5.168-.095 7.273z"/><path d="M16.088 5.19c-1.008-.542-2.607-.48-3.441.388-.568.591-.773 1.389-.8 2.172-.034.993.068 2.013.361 2.953.307.985 1.034 1.848 2.077 2.012.878.138 1.83-.088 2.458-.732.7-.718.88-1.81.877-2.779-.003-.989-.084-1.99-.423-2.91-.268-.726-.654-1.328-1.109-1.104zm-.294 5.482c-.182.462-.581.771-1.091.696-.532-.078-.859-.533-1.04-1.005-.248-.647-.327-1.375-.312-2.06.01-.46.095-.939.371-1.313.345-.467.993-.447 1.426-.115.41.315.607.835.74 1.32.18.66.211 1.675-.094 2.477zM8.4 10.394c.233 1.084.755 2.299 1.907 2.579.934.227 1.993-.165 2.434-1.048.455-.91.346-1.995.166-2.972-.165-.893-.46-1.885-1.207-2.445-.745-.559-1.832-.457-2.479.192-.84.843-.958 2.138-.955 3.277.001.147.119.364.134.417zm1.363-2.808c.302-.321.805-.336 1.14-.054.445.375.618 1.015.75 1.558.131.54.212 1.156.082 1.703-.1.423-.378.821-.84.882-.469.062-.886-.306-1.088-.704-.326-.644-.401-1.426-.381-2.148.013-.465.104-.993.337-1.237z"/></svg></a><a class="VPSocialLink no-icon" href="https://buymeacoffee.com/vbilopavu" aria-label="Buy Me a Coffee" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.216 6.415l-.132-.666c-.119-.598-.388-1.163-1.001-1.379-.197-.069-.42-.098-.57-.241-.152-.143-.196-.366-.231-.572-.065-.378-.125-.756-.192-1.133-.057-.325-.102-.69-.25-.987-.195-.4-.597-.634-.996-.788a5.723 5.723 0 00-.626-.194c-1-.263-2.05-.36-3.077-.416a25.834 25.834 0 00-3.7.062c-.915.083-1.88.184-2.75.5-.318.116-.646.256-.888.501-.297.302-.393.77-.177 1.146.154.267.415.456.692.58.36.162.737.284 1.123.366 1.075.238 2.189.331 3.287.37 1.218.05 2.437.01 3.65-.118.299-.033.598-.073.896-.119.352-.054.578-.513.474-.834-.124-.383-.457-.531-.834-.473-.466.074-.96.108-1.382.146-1.177.08-2.358.082-3.536.006a22.228 22.228 0 01-1.157-.107c-.086-.01-.18-.025-.258-.036-.243-.036-.484-.08-.724-.13-.111-.027-.111-.185 0-.212h.005c.277-.06.557-.108.838-.147h.002c.131-.009.263-.032.394-.048a25.076 25.076 0 013.426-.12c.674.019 1.347.067 2.017.144l.228.031c.267.04.533.088.798.145.392.085.895.113 1.07.542.055.137.08.288.111.431l.319 1.484a.237.237 0 01-.199.284h-.003c-.037.006-.075.01-.112.015a36.704 36.704 0 01-4.743.295 37.059 37.059 0 01-4.699-.304c-.14-.017-.293-.042-.417-.06-.326-.048-.649-.108-.973-.161-.393-.065-.768-.032-1.123.161-.29.16-.527.404-.675.701-.154.316-.199.66-.267 1-.069.34-.176.707-.135 1.056.087.753.613 1.365 1.37 1.502a39.69 39.69 0 0011.343.376.483.483 0 01.535.53l-.071.697-1.018 9.907c-.041.41-.047.832-.125 1.237-.122.637-.553 1.028-1.182 1.171-.577.131-1.165.2-1.756.205-.656.004-1.31-.025-1.966-.022-.699.004-1.556-.06-2.095-.58-.475-.458-.54-1.174-.605-1.793l-.731-7.013-.322-3.094c-.037-.351-.286-.695-.678-.678-.336.015-.718.3-.678.679l.228 2.185.949 9.112c.147 1.344 1.174 2.068 2.446 2.272.742.12 1.503.144 2.257.156.966.016 1.942.053 2.892-.122 1.408-.258 2.465-1.198 2.616-2.657.34-3.332.683-6.663 1.024-9.995l.215-2.087a.484.484 0 01.39-.426c.402-.078.787-.212 1.074-.518.455-.488.546-1.124.385-1.766zm-1.478.772c-.145.137-.363.201-.578.233-2.416.359-4.866.54-7.308.46-1.748-.06-3.477-.254-5.207-.498-.17-.024-.353-.055-.47-.18-.22-.236-.111-.71-.054-.995.052-.26.152-.609.463-.646.484-.057 1.046.148 1.526.22.577.088 1.156.159 1.737.212 2.48.226 5.002.19 7.472-.14.45-.06.899-.13 1.345-.21.399-.072.84-.206 1.08.206.166.281.188.657.162.974a.544.544 0 01-.169.364z"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-6aa21345 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><div class="divider" data-v-6aa21345><div class="divider-line" data-v-6aa21345></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-5d98c3a5 data-v-a6f0e41e><div class="container" data-v-a6f0e41e><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-a6f0e41e><span class="vpi-align-left menu-icon" data-v-a6f0e41e></span><span class="menu-text" data-v-a6f0e41e>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-a6f0e41e data-v-8a42e2b4><button data-v-8a42e2b4>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-5d98c3a5 data-v-319d5ca6><div class="curtain" data-v-319d5ca6></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-319d5ca6><span class="visually-hidden" id="sidebar-aria-label" data-v-319d5ca6> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>Getting Started</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Overview</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/installation.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Installation</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/quick-start.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Quick Start</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0 has-active" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>Topics</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/sql-files.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>SQL File Endpoints</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/configuration.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Configuration Guide</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/annotations.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Comment Annotations Guide</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/authentication.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Authentication</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/sse.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Server-Sent Events</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/http-types.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>HTTP Custom Types</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/proxy.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Proxy Endpoints</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/testing.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Testing</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/logging.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Logging</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>Reference</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/faq.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>FAQ & Troubleshooting</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/guide/changelog/" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Changelog</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/examples/" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Examples</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/annotations/" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Annotations Reference</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8 data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/config/" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>Configuration Reference</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-5d98c3a5 data-v-1428d186><div class="VPDoc has-sidebar has-aside" data-v-1428d186 data-v-39a288b8><!--[--><!--]--><div class="container" data-v-39a288b8><div class="aside" data-v-39a288b8><div class="aside-curtain" data-v-39a288b8></div><div class="aside-container" data-v-39a288b8><div class="aside-content" data-v-39a288b8><div class="VPDocAside" data-v-39a288b8 data-v-3f215769><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-3f215769 data-v-a5bbad30><div class="content" data-v-a5bbad30><div class="outline-marker" data-v-a5bbad30></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-a5bbad30>On this page</div><ul class="VPDocOutlineItem root" data-v-a5bbad30 data-v-b933a997><!--[--><!--]--></ul></div></nav><!--[--><!--[--><!--[--><!--[--><div class="comments-outline-link" data-v-6357a5e2><a href="#comments" class="outline-link" data-v-6357a5e2>Comments</a></div><!--]--><!--]--><!--]--><!--]--><div class="spacer" data-v-3f215769></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-39a288b8><div class="content-container" data-v-39a288b8><!--[--><!--]--><main class="main" data-v-39a288b8><div style="position:relative;" class="vp-doc _guide_sse" data-v-39a288b8><div><h1 id="server-sent-events-sse" tabindex="-1">Server-Sent Events (SSE) <a class="header-anchor" href="#server-sent-events-sse" aria-label="Permalink to "Server-Sent Events (SSE)""></a></h1><p>NpgsqlRest can stream real-time updates from PostgreSQL to connected clients over <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events" target="_blank" rel="noreferrer">Server-Sent Events</a> — a one-way HTTP stream the browser consumes with the native <code>EventSource</code> API. You don't write any streaming code: a procedure simply emits events with PostgreSQL's <code>RAISE</code> statement, and NpgsqlRest broadcasts them to subscribers.</p><p>This guide covers:</p><ol><li><a href="#how-sse-works">How SSE works in NpgsqlRest</a></li><li><a href="#creating-a-publisher-endpoint">Creating a publisher endpoint</a></li><li><a href="#subscribing-from-the-browser">Subscribing from the browser</a></li><li><a href="#who-receives-events-scope">Who receives events: scope</a></li><li><a href="#which-raise-level-fires-event-level">Which RAISE level fires: event level</a></li><li><a href="#targeting-specific-recipients">Targeting specific recipients</a></li><li><a href="#splitting-publish-from-subscribe">Splitting publish from subscribe</a></li><li><a href="#configuration">Configuration</a></li><li><a href="#a-complete-example-real-time-chat">A complete example: real-time chat</a></li></ol><div class="tip custom-block"><p class="custom-block-title">Reference pages</p><p>This is the conceptual walkthrough. For exact options see <a href="./../annotations/sse.html"><code>@sse</code></a>, <a href="./../annotations/sse-events-level.html"><code>@sse_events_level</code></a>, and <a href="./../annotations/sse-events-scope.html"><code>@sse_events_scope</code></a>.</p></div><h2 id="how-sse-works" tabindex="-1">How SSE works <a class="header-anchor" href="#how-sse-works" aria-label="Permalink to "How SSE works""></a></h2><p>The model is deliberately small. Mark a routine with <a href="./../annotations/sse.html"><code>@sse</code></a> and it becomes a <strong>publisher</strong>: any <code>RAISE INFO/NOTICE/WARNING</code> inside its body is turned into an SSE event and broadcast to connected clients. The annotation also registers a <strong>subscribe URL</strong> that a browser connects to with <code>EventSource</code>.</p><div class="language-mermaid vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">mermaid</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">flowchart TD</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> C["Client C</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> POST /api/send-message"] --> EP["@sse publisher endpoint</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> INSERT message + RAISE INFO '...'"]</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> EP --> BC["NpgsqlRest broadcaster</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> (one per process)"]</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> BC -->|"SSE event (scope-filtered)"| A["Client A</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> EventSource /api/send-message/info"]</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> BC -->|"SSE event (scope-filtered)"| B["Client B</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> EventSource /api/send-message/info"]</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>Key points:</p><ul><li>There is <strong>one process-wide broadcaster</strong>. Every <code>EventSource</code> connection reads from the same stream; the subscribe URL is an entry point, not a per-topic channel.</li><li><strong>Who</strong> receives a given event is decided per event by its <a href="#who-receives-events-scope">scope</a> (everyone, authorized users, a matching security context, or a specific user).</li><li><strong>Which</strong> <code>RAISE</code> statements become events is decided by the <a href="#which-raise-level-fires-event-level">event level</a> — and level matching is <strong>exact</strong>, not "this level and above".</li><li>A connected client is a <strong>pure listener</strong> — connecting never runs the procedure body.</li></ul><h2 id="creating-a-publisher-endpoint" tabindex="-1">Creating a publisher endpoint <a class="header-anchor" href="#creating-a-publisher-endpoint" aria-label="Permalink to "Creating a publisher endpoint""></a></h2><p>Add <code>@sse</code> to any endpoint and emit events with <code>RAISE</code>. Here is the message-sending half of a chat app — it inserts a row and broadcasts the new message as JSON:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-ZafrC" id="tab-ymvGCt5" checked><label data-title="Function" for="tab-ymvGCt5">Function</label><input type="radio" name="group-ZafrC" id="tab-8rk-zqn"><label data-title="SQL file" for="tab-8rk-zqn">SQL file</label></div><div class="blocks"><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">create</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> send_message(</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_text </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _user_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> null</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _user_name </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> null</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">language</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> plpgsql</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">as</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $$</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">declare</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">timestamptz</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">begin</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> insert into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> messages (user_id, username, message_text)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> values</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> (_user_id::</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_name, _message_text)</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> returning message_id, created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_id, _created_at;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;"> -- broadcast the new message to all connected, authorized clients</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> raise info </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'%'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, json_build_object(</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'message_id'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _message_id,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'user_id'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_id::</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'username'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_name,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'message_text'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _message_text,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'created_at'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _created_at</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> );</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">end</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">$$;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">comment </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">on</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> send_message(</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">) </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">is</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> '</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">HTTP POST</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@authorize</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@user_parameters</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse_scope authorize'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br></div></div></details><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- sql/send-message.sql</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">/*</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">HTTP POST</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@authorize</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@user_parameters</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@sse</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@sse_scope authorize</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@param $1 message_text text</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@param $2 _user_id text = null</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@param $3 _user_name text = null</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@void</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">*/</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">do $$</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">declare</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">timestamptz</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">begin</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> insert into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> messages (user_id, username, message_text)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> values</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> (current_setting(</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'request.user_id'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, true)::</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> current_setting(</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'request.user_name'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, true),</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;">1</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">)</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> returning message_id, created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_id, _created_at;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> raise info </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'%'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, json_build_object(</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'message_id'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _message_id,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'message_text'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, $</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;">1</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'created_at'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _created_at</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> );</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">end</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">$$;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br></div></div></details></div></div><ul><li><code>@sse</code> makes this a publisher and registers the subscribe URL (see below). Its <strong>default event level is <code>info</code></strong>, so <code>RAISE INFO</code> is what gets broadcast here.</li><li><code>@sse_scope authorize</code> means only authenticated clients receive the broadcast — see <a href="#who-receives-events-scope">scope</a>.</li><li>The body still runs normally when the endpoint is called (the <code>INSERT</code> happens); the <code>RAISE</code> is the <em>additional</em> broadcast.</li><li>Emit a payload by formatting it into the <code>RAISE</code> message — JSON is the natural choice for structured events.</li></ul><h2 id="subscribing-from-the-browser" tabindex="-1">Subscribing from the browser <a class="header-anchor" href="#subscribing-from-the-browser" aria-label="Permalink to "Subscribing from the browser""></a></h2><p><code>@sse</code> registers a connection URL at <strong><code><endpoint-path>/<level></code></strong> — for the <code>send_message</code> endpoint above, with its default <code>info</code> level, that's <code>GET /api/send-message/info</code>.</p><p>You don't build that URL by hand. Set <code>ClientCodeGen.ExportEventSources: true</code> and NpgsqlRest generates a typed <code>EventSource</code> factory for each SSE endpoint as part of the <a href="./../config/codegen.html">TypeScript client</a>. For <code>send_message</code> you get a <code>createSendMessageEventSource()</code> function — use it directly:</p><details class="code-collapsible" open><summary>js</summary><div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">import</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> {</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> createSendMessageEventSource </span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">}</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> from</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> './example8Api'</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;"> // generated client</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">const</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> events </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> createSendMessageEventSource</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">()</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">events</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">onmessage</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> (</span><span style="--shiki-light:#E64553;--shiki-light-font-style:italic;--shiki-dark:#EBA0AC;--shiki-dark-font-style:italic;">e</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">)</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> =></span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> {</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> const</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> msg </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> JSON</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">parse</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(e</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">data)</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> console</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">log</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">`</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">${</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">msg</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">username</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">}</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">: </span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">${</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">msg</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">message_text</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">}</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">`</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">)</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">};</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></details><p>Connecting <strong>does not</strong> run the procedure — the client just listens. Any time <em>another</em> request triggers the procedure (or any publisher that emits on this stream), the event arrives here.</p><div class="tip custom-block"><p class="custom-block-title">One-call subscribe + send</p><p>The generated POST function for the same endpoint can open the stream for you too: pass an <code>onMessage</code> callback as <code>sendMessage(request, onMessage)</code> and the client subscribes, sends, and tidies up the <code>EventSource</code> in a single call.</p></div><h2 id="who-receives-events-scope" tabindex="-1">Who receives events: scope <a class="header-anchor" href="#who-receives-events-scope" aria-label="Permalink to "Who receives events: scope""></a></h2><p>Scope answers <em>which connected clients should receive this event</em>. Set the default for an endpoint with <a href="./../annotations/sse-events-scope.html"><code>@sse_scope</code></a> (alias <code>@sse_events_scope</code>):</p><div class="table-container"><div class="table-wrapper"><table tabindex="0"><thead><tr><th>Scope</th><th>Who receives the event</th></tr></thead><tbody><tr><td><code>all</code></td><td>Every connected client.</td></tr><tr><td><code>authorize</code></td><td>Only authenticated clients. Optionally restrict to roles / usernames / user IDs: <code>@sse_scope authorize admin, manager</code>.</td></tr><tr><td><code>matching</code></td><td>Clients whose security context matches the emitting request (by roles, usernames, and user IDs).</td></tr></tbody></table></div></div><details class="code-collapsible" open><summary>code</summary><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span>@sse_scope all</span></span>
<span class="line"><span>@sse_scope authorize</span></span>
<span class="line"><span>@sse_scope authorize admin, manager</span></span>
<span class="line"><span>@sse_scope matching</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div></details><p>The scope set on the annotation is the <strong>default</strong> for events from that endpoint. Individual events can override it at runtime — see <a href="#targeting-specific-recipients">targeting</a>.</p><h2 id="which-raise-level-fires-event-level" tabindex="-1">Which RAISE level fires: event level <a class="header-anchor" href="#which-raise-level-fires-event-level" aria-label="Permalink to "Which RAISE level fires: event level""></a></h2><p>An SSE endpoint listens at <strong>one</strong> PostgreSQL notice level. Only <code>RAISE</code> statements at that exact level become events:</p><div class="table-container"><div class="table-wrapper"><table tabindex="0"><thead><tr><th>Endpoint level</th><th style="text-align:center;"><code>RAISE INFO</code></th><th style="text-align:center;"><code>RAISE NOTICE</code></th><th style="text-align:center;"><code>RAISE WARNING</code></th></tr></thead><tbody><tr><td><code>info</code> (default)</td><td style="text-align:center;">✅ broadcast</td><td style="text-align:center;">—</td><td style="text-align:center;">—</td></tr><tr><td><code>notice</code></td><td style="text-align:center;">—</td><td style="text-align:center;">✅ broadcast</td><td style="text-align:center;">—</td></tr><tr><td><code>warning</code></td><td style="text-align:center;">—</td><td style="text-align:center;">—</td><td style="text-align:center;">✅ broadcast</td></tr></tbody></table></div></div><p>The level is <strong>exact, not hierarchical</strong> — an <code>info</code> endpoint does <em>not</em> also forward <code>notice</code> or <code>warning</code>. Set the level inline on <code>@sse</code> or with the dedicated annotation:</p><details class="code-collapsible" open><summary>code</summary><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span>@sse -- default level: info → subscribe at <path>/info</span></span>
<span class="line"><span>@sse my_events on notice -- custom path + notice level → subscribe at <path>/my_events</span></span>
<span class="line"><span>@sse_events_level notice -- set the level separately</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div></details><p>The process-wide default level is <code>DefaultServerSentEventsEventNoticeLevel</code> (default <code>INFO</code>); see <a href="#configuration">configuration</a>.</p><h2 id="targeting-specific-recipients" tabindex="-1">Targeting specific recipients <a class="header-anchor" href="#targeting-specific-recipients" aria-label="Permalink to "Targeting specific recipients""></a></h2><p>Beyond the endpoint's default scope, a single event can pick its own audience at runtime using <code>RAISE … USING hint</code>. The hint string is a scope expression:</p><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- broadcast to everyone, regardless of the endpoint's default scope</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">raise notice </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'System maintenance in 5 minutes'</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> using</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> hint </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'all'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- only admins</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">raise notice </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'%'</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> using</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> hint </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'authorize admin'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">message</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- only specific users, by username or id</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">raise info </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'Your report is ready'</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> using</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> hint </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> format</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'authorize %s'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_id);</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div></details><p>This is what makes per-user notifications possible: an endpoint that processes a job can notify <em>just the user who owns it</em> with <code>using hint = format('authorize %s', _user_id)</code>, even though the broadcaster is shared.</p><div class="info custom-block"><p class="custom-block-title">Request correlation</p><p>When a request carries an execution-id header (<code>ExecutionIdHeaderName</code>, default <code>X-NpgsqlRest-ID</code>) and an <code>EventSource</code> includes the same id as a query parameter, events are also filtered to that execution id — useful for streaming the progress of one specific long-running call back to its initiator.</p></div><h2 id="splitting-publish-from-subscribe" tabindex="-1">Splitting publish from subscribe <a class="header-anchor" href="#splitting-publish-from-subscribe" aria-label="Permalink to "Splitting publish from subscribe""></a></h2><p>In the chat example, one endpoint both sends and is subscribed to. Often you want them separate — for example, a privileged action emits events, but ordinary users subscribe. Use a <strong>subscribe-only</strong> endpoint (its body never runs — it exists only to register the URL) plus one or more <strong>emitter</strong> endpoints that broadcast on the same level/scope.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-SbuMh" id="tab-92f2rt4" checked><label data-title="Function" for="tab-92f2rt4">Function</label><input type="radio" name="group-SbuMh" id="tab-owKypUd"><label data-title="SQL file" for="tab-owKypUd">SQL file</label></div><div class="blocks"><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- subscribe-only: clients connect here, body never executes</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">create</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> user_events_subscribe</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">()</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">language</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> plpgsql </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">as</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $$ </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">begin</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> perform </span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;">1</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">; </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">end</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">; $$;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">comment </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">on</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> user_events_subscribe</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">()</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> is</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> '</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">HTTP GET</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@authorize</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse_scope authorize'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- emitter: a privileged action that notifies the affected user</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">create</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> update_user_roles(_target_user_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _roles </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">[])</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">language</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> plpgsql </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">as</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $$</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">begin</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;"> -- ... perform the role update ...</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> raise info </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'roles updated'</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> using</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> hint </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> format</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'authorize %s'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _target_user_id);</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">end</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">$$;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">comment </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">on</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> update_user_roles(</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">[]) </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">is</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> '</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">HTTP POST</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@authorize manager</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse_scope authorize'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div></details><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- sql/user-events-subscribe.sql (subscribe-only)</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">/*</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">HTTP GET</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@authorize</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@sse</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@sse_scope authorize</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@void</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">*/</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">select</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> 1</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- sql/update-user-roles.sql (emitter)</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">/*</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">HTTP POST</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@authorize manager</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@sse</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@sse_scope authorize</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@param $1 _target_user_id int</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@param $2 _roles text[]</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">@void</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">*/</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">do $$</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">declare</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _target_user_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;">1</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">begin</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;"> -- ... perform the role update ...</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> raise info </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'roles updated'</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> using</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> hint </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> format</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'authorize %s'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _target_user_id);</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">end</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">$$;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div></details></div></div><p>The browser subscribes to <code>GET /api/user-events-subscribe/info</code>; when a manager calls <code>update_user_roles</code>, only the targeted user's connection receives the event.</p><h2 id="configuration" tabindex="-1">Configuration <a class="header-anchor" href="#configuration" aria-label="Permalink to "Configuration""></a></h2><p>SSE works out of the box — no global enable flag. These options under <code>NpgsqlRest</code> tune the defaults:</p><div class="table-container"><div class="table-wrapper"><table tabindex="0"><thead><tr><th>Setting</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>DefaultServerSentEventsEventNoticeLevel</code></td><td><code>"INFO"</code></td><td>Default PostgreSQL notice level for SSE events (<code>INFO</code>, <code>NOTICE</code>, or <code>WARNING</code>). Overridable per endpoint via <a href="#which-raise-level-fires-event-level"><code>@sse … on <level></code></a>.</td></tr><tr><td><code>ServerSentEventsResponseHeaders</code></td><td><code>{}</code></td><td>Extra headers added to SSE responses.</td></tr><tr><td><code>WarnUnboundServerSentEventsNotices</code></td><td><code>true</code></td><td>Logs a one-time warning for a <code>RAISE</code> that matches the SSE level but sits on an endpoint with no <code>@sse</code> annotation (a likely missing publisher).</td></tr></tbody></table></div></div><details class="code-collapsible" open><summary>json</summary><div class="language-json vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">{</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">NpgsqlRest</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> {</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">DefaultServerSentEventsEventNoticeLevel</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> "INFO"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">,</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">ServerSentEventsResponseHeaders</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> {</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">X-Accel-Buffering</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> "no"</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> }</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> }</span></span>
<span class="line"><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div></details><div class="tip custom-block"><p class="custom-block-title">Behind nginx</p><p>SSE is a long-lived streaming response. If you run behind nginx, add <code>X-Accel-Buffering: no</code> (as above) so the proxy doesn't buffer the stream and delay events.</p></div><div class="warning custom-block"><p class="custom-block-title">Cache hits don't broadcast</p><p>If a publisher endpoint is also <a href="./../annotations/cached.html"><code>@cached</code></a> and a request is served from cache, the function body doesn't run — so no <code>RAISE</code> fires and no event is broadcast. That's correct behavior, but keep it in mind: don't cache an endpoint whose side effect is the broadcast.</p></div><h2 id="a-complete-example-real-time-chat" tabindex="-1">A complete example: real-time chat <a class="header-anchor" href="#a-complete-example-real-time-chat" aria-label="Permalink to "A complete example: real-time chat""></a></h2><p>The pieces below form a minimal chat: a login, a publisher that sends + broadcasts, a history endpoint, and the browser subscription. (Cookie auth setup omitted — see the <a href="./authentication.html">Authentication guide</a>.)</p><p><strong>Tables</strong></p><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">create</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> table</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> messages</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> (</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> message_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> primary key</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> generated</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> always</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> as</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> identity</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> user_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> not null</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> username </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> not null</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> message_text </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> not null</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">timestamptz</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> not null</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> default</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> now</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">()</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">);</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></details><p><strong>Send + broadcast</strong> (publisher)</p><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">create</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> send_message(_message_text </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> null</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_name </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> null</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">language</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> plpgsql </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">as</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $$</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">declare</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_id </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">; _created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">timestamptz</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">begin</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> insert into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> messages (user_id, username, message_text)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> values</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> (_user_id::</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_name, _message_text)</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> returning message_id, created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _message_id, _created_at;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> raise info </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'%'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, json_build_object(</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'message_id'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _message_id, </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'user_id'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_id::</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">int</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">,</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'username'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _user_name, </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'message_text'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _message_text, </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'created_at'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, _created_at);</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">end</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">$$;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">comment </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">on</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> procedure</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> send_message(</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">text</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">) </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">is</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> '</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">HTTP POST</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@authorize</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@user_parameters</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@sse_scope authorize'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div></details><p><strong>Load history</strong> (plain endpoint, no SSE)</p><details class="code-collapsible" open><summary>sql</summary><div class="language-sql vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">create</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> function</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> get_messages</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">()</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">returns</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> setof messages</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">language</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> sql</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> as</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> $$</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> select</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> *</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> from</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> messages </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">order by</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">asc</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">$$;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">comment on function get_messages() is </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">HTTP GET</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">@authorize'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></details><p><strong>Browser</strong> — using the generated TypeScript client, no hand-written <code>fetch</code>:</p><details class="code-collapsible" open><summary>js</summary><div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">import</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> {</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> getMessages</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">,</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> sendMessage</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">,</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> createSendMessageEventSource </span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">}</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> from</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> './example8Api'</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">// 1. load history (typed, generated)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">const</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> {</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> response</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> history </span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">}</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> await</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> getMessages</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">()</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">history</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">?.</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">forEach</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(renderMessage)</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">// 2. subscribe to new messages</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">const</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> events </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> createSendMessageEventSource</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">()</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">events</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">onmessage</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#E64553;--shiki-light-font-style:italic;--shiki-dark:#EBA0AC;--shiki-dark-font-style:italic;"> e</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> =></span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> renderMessage</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;">JSON</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">parse</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(e</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">.</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">data))</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">// 3. send a message — every authorized subscriber receives the broadcast</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">await</span><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;"> sendMessage</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">(</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">{</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> messageText</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">:</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'Hello!'</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> }</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">)</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div></details><p>Because the broadcast uses <code>@sse_scope authorize</code>, every signed-in client connected to the stream sees each new message in real time. All three functions — <code>getMessages</code>, <code>sendMessage</code>, and <code>createSendMessageEventSource</code> — are generated from your SQL; you don't write the HTTP calls.</p><h2 id="see-it-in-the-examples" tabindex="-1">See it in the examples <a class="header-anchor" href="#see-it-in-the-examples" aria-label="Permalink to "See it in the examples""></a></h2><ul><li><a href="/examples/"><strong>Simple Chat Client</strong></a> (<code>8_simple_chat_client</code>) — the full runnable chat app, function-based and as SQL files.</li><li>Tutorial walkthrough: <a href="/blog/real-time-chat-postgresql-sse-npgsqlrest.html">Real-Time Chat with SSE</a>.</li></ul><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../annotations/sse.html"><code>@sse</code></a> — mark an endpoint as an SSE publisher / subscribe URL</li><li><a href="./../annotations/sse-events-level.html"><code>@sse_events_level</code></a> — set the notice level the endpoint listens on</li><li><a href="./../annotations/sse-events-scope.html"><code>@sse_events_scope</code></a> — set who receives the events</li><li><a href="./../annotations/authorize.html"><code>@authorize</code></a> / <a href="./authentication.html">Authentication guide</a> — securing real-time endpoints</li><li><a href="./../annotations/cached.html"><code>@cached</code></a> — caching (and why it skips broadcasts)</li><li><a href="./../config/codegen.html">TypeScript client generation</a> — <code>ExportEventSources</code> for typed <code>EventSource</code> clients</li></ul></div></div></main><footer class="VPDocFooter" data-v-39a288b8 data-v-e257564d><!--[--><!--]--><div class="edit-info" data-v-e257564d><div class="edit-link" data-v-e257564d><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/NpgsqlRest/npgsqlrest-docs/edit/main/docs/guide/sse.md" target="_blank" rel="noreferrer" data-v-e257564d><!--[--><span class="vpi-square-pen edit-link-icon" data-v-e257564d></span> Edit this page on GitHub<!--]--></a></div><!----></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-e257564d><span class="visually-hidden" id="doc-footer-aria-label" data-v-e257564d>Pager</span><div class="pager" data-v-e257564d><a class="VPLink link pager-link prev" href="/guide/authentication.html" data-v-e257564d><!--[--><span class="desc" data-v-e257564d>Previous page</span><span class="title" data-v-e257564d>Authentication</span><!--]--></a></div><div class="pager" data-v-e257564d><a class="VPLink link pager-link next" href="/guide/http-types.html" data-v-e257564d><!--[--><span class="desc" data-v-e257564d>Next page</span><span class="title" data-v-e257564d>HTTP Custom Types</span><!--]--></a></div></nav></footer><!--[--><!--[--><!--[--><div id="comments" class="giscus-wrapper" data-v-5337483f><h2 class="comments-heading" data-v-5337483f>Comments</h2><!----></div><div class="sponsor-footer" data-v-b93f2dbd><div class="sponsor-footer-content" data-v-b93f2dbd><span class="sponsor-heart" data-v-b93f2dbd>❤️</span><span class="sponsor-text" data-v-b93f2dbd>Support this project:</span><a href="https://patreon.com/vbconsulting" target="_blank" class="sponsor-link" data-v-b93f2dbd><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" data-v-b93f2dbd><path d="M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 7.463 3.097 9.746 2.602 2.124 6.19 2.078 9.402 1.836 1.883-.142 3.939-.358 5.477-1.528 1.564-1.19 1.873-3.298 1.972-5.151.134-2.51.187-5.016-.037-7.233zm-2.55 7.703c-.078 1.593-.383 3.473-1.795 4.334-1.351.824-3.151.973-4.686 1.083-2.891.207-6.063.276-8.514-1.399C3.106 17.39 2.924 14.34 2.95 11.67c.03-3.206.678-6.721 3.654-8.375 2.756-1.531 6.556-1.727 9.544-.872 2.339.669 4.351 2.678 4.355 5.217.007 2.583-.016 5.168-.095 7.273z" data-v-b93f2dbd></path><path d="M16.088 5.19c-1.008-.542-2.607-.48-3.441.388-.568.591-.773 1.389-.8 2.172-.034.993.068 2.013.361 2.953.307.985 1.034 1.848 2.077 2.012.878.138 1.83-.088 2.458-.732.7-.718.88-1.81.877-2.779-.003-.989-.084-1.99-.423-2.91-.268-.726-.654-1.328-1.109-1.104zm-.294 5.482c-.182.462-.581.771-1.091.696-.532-.078-.859-.533-1.04-1.005-.248-.647-.327-1.375-.312-2.06.01-.46.095-.939.371-1.313.345-.467.993-.447 1.426-.115.41.315.607.835.74 1.32.18.66.211 1.675-.094 2.477zM8.4 10.394c.233 1.084.755 2.299 1.907 2.579.934.227 1.993-.165 2.434-1.048.455-.91.346-1.995.166-2.972-.165-.893-.46-1.885-1.207-2.445-.745-.559-1.832-.457-2.479.192-.84.843-.958 2.138-.955 3.277.001.147.119.364.134.417zm1.363-2.808c.302-.321.805-.336 1.14-.054.445.375.618 1.015.75 1.558.131.54.212 1.156.082 1.703-.1.423-.378.821-.84.882-.469.062-.886-.306-1.088-.704-.326-.644-.401-1.426-.381-2.148.013-.465.104-.993.337-1.237z" data-v-b93f2dbd></path></svg> Patreon </a><span class="sponsor-separator" data-v-b93f2dbd>·</span><a href="https://buymeacoffee.com/vbilopavu" target="_blank" class="sponsor-link" data-v-b93f2dbd><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" data-v-b93f2dbd><path d="M20.216 6.415l-.132-.666c-.119-.598-.388-1.163-1.001-1.379-.197-.069-.42-.098-.57-.241-.152-.143-.196-.366-.231-.572-.065-.378-.125-.756-.192-1.133-.057-.325-.102-.69-.25-.987-.195-.4-.597-.634-.996-.788a5.723 5.723 0 00-.626-.194c-1-.263-2.05-.36-3.077-.416a25.834 25.834 0 00-3.7.062c-.915.083-1.88.184-2.75.5-.318.116-.646.256-.888.501-.297.302-.393.77-.177 1.146.154.267.415.456.692.58.36.162.737.284 1.123.366 1.075.238 2.189.331 3.287.37 1.218.05 2.437.01 3.65-.118.299-.033.598-.073.896-.119.352-.054.578-.513.474-.834-.124-.383-.457-.531-.834-.473-.466.074-.96.108-1.382.146-1.177.08-2.358.082-3.536.006a22.228 22.228 0 01-1.157-.107c-.086-.01-.18-.025-.258-.036-.243-.036-.484-.08-.724-.13-.111-.027-.111-.185 0-.212h.005c.277-.06.557-.108.838-.147h.002c.131-.009.263-.032.394-.048a25.076 25.076 0 013.426-.12c.674.019 1.347.067 2.017.144l.228.031c.267.04.533.088.798.145.392.085.895.113 1.07.542.055.137.08.288.111.431l.319 1.484a.237.237 0 01-.199.284h-.003c-.037.006-.075.01-.112.015a36.704 36.704 0 01-4.743.295 37.059 37.059 0 01-4.699-.304c-.14-.017-.293-.042-.417-.06-.326-.048-.649-.108-.973-.161-.393-.065-.768-.032-1.123.161-.29.16-.527.404-.675.701-.154.316-.199.66-.267 1-.069.34-.176.707-.135 1.056.087.753.613 1.365 1.37 1.502a39.69 39.69 0 0011.343.376.483.483 0 01.535.53l-.071.697-1.018 9.907c-.041.41-.047.832-.125 1.237-.122.637-.553 1.028-1.182 1.171-.577.131-1.165.2-1.756.205-.656.004-1.31-.025-1.966-.022-.699.004-1.556-.06-2.095-.58-.475-.458-.54-1.174-.605-1.793l-.731-7.013-.322-3.094c-.037-.351-.286-.695-.678-.678-.336.015-.718.3-.678.679l.228 2.185.949 9.112c.147 1.344 1.174 2.068 2.446 2.272.742.12 1.503.144 2.257.156.966.016 1.942.053 2.892-.122 1.408-.258 2.465-1.198 2.616-2.657.34-3.332.683-6.663 1.024-9.995l.215-2.087a.484.484 0 01.39-.426c.402-.078.787-.212 1.074-.518.455-.488.546-1.124.385-1.766zm-1.478.772c-.145.137-.363.201-.578.233-2.416.359-4.866.54-7.308.46-1.748-.06-3.477-.254-5.207-.498-.17-.024-.353-.055-.47-.18-.22-.236-.111-.71-.054-.995.052-.26.152-.609.463-.646.484-.057 1.046.148 1.526.22.577.088 1.156.159 1.737.212 2.48.226 5.002.19 7.472-.14.45-.06.899-.13 1.345-.21.399-.072.84-.206 1.08.206.166.281.188.657.162.974a.544.544 0 01-.169.364z" data-v-b93f2dbd></path></svg> Buy Me a Coffee </a></div><div class="footer-license" data-v-b93f2dbd>Released under the MIT License.</div><div class="footer-copyright" data-v-b93f2dbd>Copyright © 2024-2026 VB Consulting</div></div><!--]--><!--]--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"about.md\":\"DQcoTdts\",\"annotations_allow-anonymous.md\":\"B0UuFGg2\",\"annotations_authorize.md\":\"CK7v-SQu\",\"annotations_basic-auth-command.md\":\"Csb6mha2\",\"annotations_basic-auth-realm.md\":\"DsMX0SDT\",\"annotations_basic-auth.md\":\"ClrT2h43\",\"annotations_body-parameter-name.md\":\"BfhRegXI\",\"annotations_buffer-rows.md\":\"BrfXbHRV\",\"annotations_cache-expires-in.md\":\"BRoExkyw\",\"annotations_cache-profile.md\":\"YD0xPH6k\",\"annotations_cached.md\":\"Z17IaMQ8\",\"annotations_column-names.md\":\"BgCUEwzC\",\"annotations_command-timeout.md\":\"DGZAbOuK\",\"annotations_connection.md\":\"kVRk6UjZ\",\"annotations_custom-parameters.md\":\"C_JoJInz\",\"annotations_define-param.md\":\"BEpTOvZh\",\"annotations_disabled.md\":\"DLiSD84Q\",\"annotations_enabled.md\":\"w_f0uh0_\",\"annotations_encrypt-decrypt.md\":\"BVL3DPHk\",\"annotations_error-code-policy.md\":\"CcDC1Uqp\",\"annotations_http-type.md\":\"Yj3KYiqW\",\"annotations_http.md\":\"DPCDKDD2\",\"annotations_index.md\":\"DSU3OO0a\",\"annotations_internal.md\":\"yWqX_Gop\",\"annotations_interval-format.md\":\"qinH4egR\",\"annotations_login.md\":\"CNtMBAwP\",\"annotations_logout.md\":\"Cle7WE1K\",\"annotations_mcp.md\":\"CUGE4v1n\",\"annotations_nested.md\":\"G3R18jm5\",\"annotations_new-line.md\":\"9HsK47GA\",\"annotations_openapi.md\":\"CYi2hImP\",\"annotations_param.md\":\"DCLc58O5\",\"annotations_parameter-hash.md\":\"DAN4SbBB\",\"annotations_parameter-substitution.md\":\"BAnY-Etv\",\"annotations_path.md\":\"4EcrWuEH\",\"annotations_proxy-out.md\":\"C6XnOMaD\",\"annotations_proxy.md\":\"C1XKqZ1u\",\"annotations_query-string-null-handling.md\":\"bDnQmkU1\",\"annotations_rate-limiter-policy.md\":\"C6rNxcxq\",\"annotations_raw.md\":\"mVR52W_-\",\"annotations_request-headers-mode.md\":\"CiBM2WBe\",\"annotations_request-headers-parameter-name.md\":\"B1w65j2m\",\"annotations_request-param-type.md\":\"D2ADbicS\",\"annotations_resolved-parameters.md\":\"CtIRul_U\",\"annotations_response-headers.md\":\"BjZbt4Z0\",\"annotations_response-null-handling.md\":\"BXujxmf9\",\"annotations_result-name.md\":\"oSFavaHs\",\"annotations_retry-strategy.md\":\"DJkjr3eT\",\"annotations_returns.md\":\"BXcLtPWm\",\"annotations_security-sensitive.md\":\"iGNlRYXu\",\"annotations_separator.md\":\"Bh3F0ZIY\",\"annotations_single.md\":\"6tuGsQhF\",\"annotations_skip.md\":\"Dh_dVMzK\",\"annotations_sse-events-level.md\":\"BzejI_6s\",\"annotations_sse-events-scope.md\":\"DSBEdrmZ\",\"annotations_sse.md\":\"VtYFy1W4\",\"annotations_table-format.md\":\"BKXSdBmi\",\"annotations_tags.md\":\"DmTy6McN\",\"annotations_test-claim.md\":\"B8Axvirh\",\"annotations_test-connection.md\":\"CBXd7WXg\",\"annotations_test-response.md\":\"BIQYW_7j\",\"annotations_test-setup.md\":\"CEjyi1f2\",\"annotations_test-tag.md\":\"CzXuyAz7\",\"annotations_test-teardown.md\":\"DrTOzo2w\",\"annotations_tsclient.md\":\"BNgVXSoY\",\"annotations_upload.md\":\"BJPkIDDG\",\"annotations_user-context.md\":\"D9DNdqIU\",\"annotations_user-parameters.md\":\"RuNgxxKs\",\"annotations_validate.md\":\"BYjsje_G\",\"annotations_void.md\":\"CdJ8Ec9f\",\"blog_case-study-zero-backend-code.md\":\"C_RsDiAE\",\"blog_csv-excel-ingestion-postgresql-npgsqlrest.md\":\"DSyRNYor\",\"blog_custom-types-multiset-rest-api.md\":\"DCC_Eq7R\",\"blog_database-level-security-postgresql-authentication.md\":\"DOXBN62P\",\"blog_draft-anniversary-vietnam-of-computer-science.md\":\"pc601xHv\",\"blog_draft-npgsqlrest-vs-sqlpage.md\":\"DbSL1Z8X\",\"blog_end-to-end-static-type-checking-postgresql-typescript.md\":\"CfE5da_h\",\"blog_excel-export-table-format-postgresql-npgsqlrest.md\":\"BuWwG6CQ\",\"blog_external-api-calls-postgresql-http-types.md\":\"C9zYiqiX\",\"blog_index.md\":\"De5ptA_4\",\"blog_mcp-server-postgresql-ai-tools-npgsqlrest.md\":\"DvISemRM\",\"blog_multiple-auth-schemes-rbac-external-providers.md\":\"BbvFjCJf\",\"blog_npgsqlrest-3.13-production-patterns.md\":\"jTlztVH-\",\"blog_npgsqlrest-3.19-sql-test-runner-watch-mode.md\":\"Dc7T3KVb\",\"blog_npgsqlrest-vs-postgrest-supabase-comparison.md\":\"00RFbAF5\",\"blog_passkey-sql-auth.md\":\"BRkr8TRo\",\"blog_performance-scalability-high-availability-npgsqlrest.md\":\"C-bwVXtr\",\"blog_postgresql-bi-server-excel-csv-basic-auth.md\":\"C9mEJphA\",\"blog_postgresql-rest-api-benchmark-2024.md\":\"DwEQmIoA\",\"blog_postgresql-rest-api-benchmark-2025.md\":\"Tbw6Blag\",\"blog_postgresql-rest-api-benchmark-2026.md\":\"BnlvOVbX\",\"blog_real-time-chat-postgresql-sse-npgsqlrest.md\":\"DHt1C23t\",\"blog_reverse-proxy-postgresql-ai-service-npgsqlrest.md\":\"BtaYnMBE\",\"blog_secure-image-uploads-postgresql-typescript.md\":\"Cp-wJyj4\",\"blog_sql-file-source-rest-api-from-plain-sql.md\":\"czCJfcgj\",\"blog_sql-rest-api.md\":\"C3OYX-j7\",\"blog_the-backend-that-writes-itself-presentation.md\":\"gFR1Oe0-\",\"blog_the-power-of-simplicity.md\":\"Cs_l8y-q\",\"blog_typescript-codegen-walkthrough.md\":\"DU5mkobw\",\"blog_web-scraping-postgresql-http-types-xml.md\":\"CCovU_63\",\"blog_what-have-stored-procedures-ever-done-for-us.md\":\"DbQNwRp9\",\"config_antiforgery.md\":\"7miFkqvJ\",\"config_auth.md\":\"BTlaq10R\",\"config_authentication-options.md\":\"CzhPcVla\",\"config_basic-auth-config.md\":\"DZCrOE7U\",\"config_cache-options.md\":\"Cq5Q0JXd\",\"config_claims-mapping.md\":\"DxUSHFxx\",\"config_codegen.md\":\"opHl7x9x\",\"config_command-retry.md\":\"BgAKKMgf\",\"config_config-section.md\":\"CwHYEVn1\",\"config_connection.md\":\"OYNJshxp\",\"config_cors.md\":\"Cusa--1Y\",\"config_data-protection.md\":\"Djdf76Tb\",\"config_error-handling.md\":\"DjvdMMV4\",\"config_external-auth.md\":\"bAqNP7C3\",\"config_forwarded-headers.md\":\"CGTpUREz\",\"config_health-checks.md\":\"BpWdFu-y\",\"config_http-client.md\":\"dRXgMQQQ\",\"config_http-files.md\":\"B6K6vnkA\",\"config_index.md\":\"CXfhm2PI\",\"config_latest.md\":\"BHuOeOrq\",\"config_logging.md\":\"B2g4l4DC\",\"config_mcp.md\":\"D08gYjRL\",\"config_npgsqlrest.md\":\"CnfMgb40\",\"config_openapi.md\":\"BCg7CKgl\",\"config_passkey-auth.md\":\"DHQzx-GX\",\"config_proxy.md\":\"DOTosU06\",\"config_rate-limiter.md\":\"wLNPwvhE\",\"config_response-compression.md\":\"CMmom6qe\",\"config_routine-options.md\":\"VEEBtjYd\",\"config_security-headers.md\":\"D2EP-6xq\",\"config_server.md\":\"BCPr-8rO\",\"config_sql-file-source.md\":\"5_GwGm0C\",\"config_static-files.md\":\"CxiUeSZr\",\"config_stats.md\":\"CXkhOJdL\",\"config_table-format.md\":\"CKOmZ6yI\",\"config_test-runner.md\":\"D9PY_12B\",\"config_thread-pool.md\":\"CQCaprkR\",\"config_top-level.md\":\"F9S_nf2B\",\"config_uploads.md\":\"DoJGjd4G\",\"config_validation.md\":\"lHNUsfic\",\"config_watch.md\":\"B_iL-Wg4\",\"examples_index.md\":\"D4o4oSds\",\"guide_annotations.md\":\"DVRiz6k_\",\"guide_authentication.md\":\"BaKZBV2r\",\"guide_changelog_index.md\":\"B7c1xVM5\",\"guide_changelog_v3.0.0.md\":\"BCZYSJDP\",\"guide_changelog_v3.0.1.md\":\"C5QoKstF\",\"guide_changelog_v3.1.0.md\":\"Xl_94wGw\",\"guide_changelog_v3.1.1.md\":\"CP1dTmO5\",\"guide_changelog_v3.1.2.md\":\"DaCWRd65\",\"guide_changelog_v3.1.3.md\":\"BMixLZ4Y\",\"guide_changelog_v3.10.0.md\":\"CCimYYDV\",\"guide_changelog_v3.11.0.md\":\"yn587hBX\",\"guide_changelog_v3.11.1.md\":\"DxsV24Au\",\"guide_changelog_v3.12.0.md\":\"BDVbkMod\",\"guide_changelog_v3.13.0.md\":\"kmKD3jrx\",\"guide_changelog_v3.14.0.md\":\"DqJvVHhw\",\"guide_changelog_v3.15.0.md\":\"DiRcMMNc\",\"guide_changelog_v3.15.1.md\":\"EipfUUTu\",\"guide_changelog_v3.15.2.md\":\"B_9nMiuK\",\"guide_changelog_v3.16.0.md\":\"z16WdNnJ\",\"guide_changelog_v3.16.1.md\":\"twyBHeJH\",\"guide_changelog_v3.16.2.md\":\"DJyi_HNy\",\"guide_changelog_v3.16.3.md\":\"BaS-l5LJ\",\"guide_changelog_v3.17.0.md\":\"DCqJkXNp\",\"guide_changelog_v3.18.0.md\":\"DhzJiwQ7\",\"guide_changelog_v3.18.1.md\":\"BUjRzlAL\",\"guide_changelog_v3.18.2.md\":\"D9Kg93qi\",\"guide_changelog_v3.19.0.md\":\"CnLwz7zb\",\"guide_changelog_v3.2.0.md\":\"DqMIq3GM\",\"guide_changelog_v3.2.1.md\":\"jsATl_CJ\",\"guide_changelog_v3.2.2.md\":\"DCWOjWem\",\"guide_changelog_v3.2.3.md\":\"BU0QClul\",\"guide_changelog_v3.2.4.md\":\"DlHy9dKX\",\"guide_changelog_v3.2.6.md\":\"Be7WrEBG\",\"guide_changelog_v3.2.7.md\":\"DnOXNKXQ\",\"guide_changelog_v3.3.0.md\":\"D_74S82V\",\"guide_changelog_v3.3.1.md\":\"DBVEhTOX\",\"guide_changelog_v3.4.0.md\":\"DWaLq7jU\",\"guide_changelog_v3.4.1.md\":\"BjkyM2ol\",\"guide_changelog_v3.4.2.md\":\"CwgXLNC8\",\"guide_changelog_v3.4.3.md\":\"CwIJ6zQw\",\"guide_changelog_v3.4.4.md\":\"Dun3dnAP\",\"guide_changelog_v3.4.5.md\":\"CCdH9iK4\",\"guide_changelog_v3.4.6.md\":\"DfISyzwO\",\"guide_changelog_v3.4.7.md\":\"PS46_sBY\",\"guide_changelog_v3.4.8.md\":\"C6Us0ANY\",\"guide_changelog_v3.5.0.md\":\"COe0eWbp\",\"guide_changelog_v3.6.0.md\":\"p7Q-OsI9\",\"guide_changelog_v3.6.1.md\":\"CCDqHGJF\",\"guide_changelog_v3.6.2.md\":\"Lg_0h_OI\",\"guide_changelog_v3.6.3.md\":\"CcLrwLcH\",\"guide_changelog_v3.7.0.md\":\"BsBWtBOJ\",\"guide_changelog_v3.8.0.md\":\"D7bLiXbw\",\"guide_changelog_v3.9.0.md\":\"Cm0S1Ft1\",\"guide_configuration.md\":\"CAstKOPi\",\"guide_faq.md\":\"DzLvzPIX\",\"guide_http-types.md\":\"6rK6DntP\",\"guide_index.md\":\"C-0777ru\",\"guide_installation.md\":\"KDi2i5hY\",\"guide_logging.md\":\"CT7Uqiy7\",\"guide_proxy.md\":\"DF7C5yHU\",\"guide_quick-start.md\":\"DtKtFUQX\",\"guide_sql-files.md\":\"yAmqICyN\",\"guide_sse.md\":\"CCeiNuHG\",\"guide_testing.md\":\"Mc_wQPBP\",\"index.md\":\"WBf3vDSd\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"NpgsqlRest - Automatic PostgreSQL Web Server\",\"description\":\"Automatic PostgreSQL Web Server - Create REST APIs for PostgreSQL databases in minutes.\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/favicon.ico\",\"siteTitle\":\"NpgsqlRest\",\"nav\":[{\"text\":\"Guide\",\"items\":[{\"text\":\"Getting Started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/guide/\"},{\"text\":\"Installation\",\"link\":\"/guide/installation\"},{\"text\":\"Quick Start\",\"link\":\"/guide/quick-start\"}]},{\"text\":\"Topics\",\"items\":[{\"text\":\"SQL File Endpoints\",\"link\":\"/guide/sql-files\"},{\"text\":\"Configuration Guide\",\"link\":\"/guide/configuration\"},{\"text\":\"Comment Annotations Guide\",\"link\":\"/guide/annotations\"},{\"text\":\"Authentication\",\"link\":\"/guide/authentication\"},{\"text\":\"Server-Sent Events\",\"link\":\"/guide/sse\"},{\"text\":\"HTTP Custom Types\",\"link\":\"/guide/http-types\"},{\"text\":\"Proxy Endpoints\",\"link\":\"/guide/proxy\"},{\"text\":\"Testing\",\"link\":\"/guide/testing\"},{\"text\":\"Logging\",\"link\":\"/guide/logging\"}]},{\"text\":\"Reference\",\"items\":[{\"text\":\"FAQ & Troubleshooting\",\"link\":\"/guide/faq\"},{\"text\":\"Changelog\",\"link\":\"/guide/changelog/\"}]}]},{\"text\":\"Examples\",\"link\":\"/examples/\"},{\"text\":\"Reference\",\"items\":[{\"text\":\"Annotations\",\"link\":\"/annotations/\"},{\"text\":\"Configuration\",\"link\":\"/config/\"}]},{\"text\":\"Blog\",\"link\":\"/blog/\"}],\"sidebar\":{\"/blog/\":[{\"text\":\"Tutorials\",\"collapsed\":false,\"items\":[{\"text\":\"Tests Are SQL Files Too\",\"link\":\"/blog/npgsqlrest-3.19-sql-test-runner-watch-mode\"},{\"text\":\"Case Study: 74 Endpoints, Zero Backend Code\",\"link\":\"/blog/case-study-zero-backend-code\"},{\"text\":\"TypeScript Code Generation Walkthrough\",\"link\":\"/blog/typescript-codegen-walkthrough\"},{\"text\":\"NpgsqlRest 3.13.0: Production Patterns\",\"link\":\"/blog/npgsqlrest-3.13-production-patterns\"},{\"text\":\"SQL REST API\",\"link\":\"/blog/sql-rest-api\"},{\"text\":\"SQL File Source\",\"link\":\"/blog/sql-file-source-rest-api-from-plain-sql\"},{\"text\":\"Database-Level Security\",\"link\":\"/blog/database-level-security-postgresql-authentication\"},{\"text\":\"Multiple Auth Schemes & RBAC\",\"link\":\"/blog/multiple-auth-schemes-rbac-external-providers\"},{\"text\":\"Passkey SQL Auth\",\"link\":\"/blog/passkey-sql-auth\"},{\"text\":\"End-to-End Type Checking\",\"link\":\"/blog/end-to-end-static-type-checking-postgresql-typescript\"},{\"text\":\"Real-Time Chat with SSE\",\"link\":\"/blog/real-time-chat-postgresql-sse-npgsqlrest\"},{\"text\":\"External API Calls\",\"link\":\"/blog/external-api-calls-postgresql-http-types\"},{\"text\":\"Web Scraping with HTTP Types\",\"link\":\"/blog/web-scraping-postgresql-http-types-xml\"},{\"text\":\"Reverse Proxy & AI Service\",\"link\":\"/blog/reverse-proxy-postgresql-ai-service-npgsqlrest\"},{\"text\":\"Secure Image Uploads\",\"link\":\"/blog/secure-image-uploads-postgresql-typescript\"},{\"text\":\"CSV & Excel Ingestion\",\"link\":\"/blog/csv-excel-ingestion-postgresql-npgsqlrest\"},{\"text\":\"PostgreSQL BI Server\",\"link\":\"/blog/postgresql-bi-server-excel-csv-basic-auth\"}]},{\"text\":\"Feature Deep Dives\",\"collapsed\":false,\"items\":[{\"text\":\"Excel Exports Done Right\",\"link\":\"/blog/excel-export-table-format-postgresql-npgsqlrest\"},{\"text\":\"Custom Types & Multiset\",\"link\":\"/blog/custom-types-multiset-rest-api\"},{\"text\":\"Performance & High Availability\",\"link\":\"/blog/performance-scalability-high-availability-npgsqlrest\"},{\"text\":\"What Have Stored Procedures Done for Us?\",\"link\":\"/blog/what-have-stored-procedures-ever-done-for-us\"},{\"text\":\"The Power of Simplicity\",\"link\":\"/blog/the-power-of-simplicity\"}]},{\"text\":\"Benchmarks & Comparisons\",\"collapsed\":false,\"items\":[{\"text\":\"Benchmark 2026\",\"link\":\"/blog/postgresql-rest-api-benchmark-2026\"},{\"text\":\"NpgsqlRest vs PostgREST vs Supabase\",\"link\":\"/blog/npgsqlrest-vs-postgrest-supabase-comparison\"}]},{\"text\":\"Other Links\",\"collapsed\":false,\"items\":[{\"text\":\"Guide\",\"link\":\"/guide/\"},{\"text\":\"Annotations Reference\",\"link\":\"/annotations/\"},{\"text\":\"Configuration Reference\",\"link\":\"/config/\"}]}],\"/guide/changelog/\":[{\"text\":\"Changelog\",\"items\":[{\"text\":\"Overview\",\"link\":\"/guide/changelog/\"},{\"text\":\"v3.19.0 (Latest)\",\"link\":\"/guide/changelog/v3.19.0\"},{\"text\":\"v3.18.2\",\"link\":\"/guide/changelog/v3.18.2\"},{\"text\":\"v3.18.1\",\"link\":\"/guide/changelog/v3.18.1\"},{\"text\":\"v3.18.0\",\"link\":\"/guide/changelog/v3.18.0\"},{\"text\":\"v3.17.0\",\"link\":\"/guide/changelog/v3.17.0\"},{\"text\":\"v3.16.3\",\"link\":\"/guide/changelog/v3.16.3\"},{\"text\":\"v3.16.2\",\"link\":\"/guide/changelog/v3.16.2\"},{\"text\":\"v3.16.1\",\"link\":\"/guide/changelog/v3.16.1\"},{\"text\":\"v3.16.0\",\"link\":\"/guide/changelog/v3.16.0\"},{\"text\":\"v3.15.2\",\"link\":\"/guide/changelog/v3.15.2\"},{\"text\":\"v3.15.1\",\"link\":\"/guide/changelog/v3.15.1\"},{\"text\":\"v3.15.0\",\"link\":\"/guide/changelog/v3.15.0\"},{\"text\":\"v3.14.0\",\"link\":\"/guide/changelog/v3.14.0\"},{\"text\":\"v3.13.0\",\"link\":\"/guide/changelog/v3.13.0\"},{\"text\":\"v3.12.0\",\"link\":\"/guide/changelog/v3.12.0\"},{\"text\":\"v3.11.1\",\"link\":\"/guide/changelog/v3.11.1\"},{\"text\":\"v3.11.0\",\"link\":\"/guide/changelog/v3.11.0\"},{\"text\":\"v3.10.0\",\"link\":\"/guide/changelog/v3.10.0\"},{\"text\":\"v3.9.0\",\"link\":\"/guide/changelog/v3.9.0\"},{\"text\":\"v3.8.0\",\"link\":\"/guide/changelog/v3.8.0\"},{\"text\":\"v3.7.0\",\"link\":\"/guide/changelog/v3.7.0\"},{\"text\":\"v3.6.3\",\"link\":\"/guide/changelog/v3.6.3\"},{\"text\":\"v3.6.2\",\"link\":\"/guide/changelog/v3.6.2\"},{\"text\":\"v3.6.1\",\"link\":\"/guide/changelog/v3.6.1\"},{\"text\":\"v3.6.0\",\"link\":\"/guide/changelog/v3.6.0\"},{\"text\":\"v3.5.0\",\"link\":\"/guide/changelog/v3.5.0\"},{\"text\":\"v3.4.8\",\"link\":\"/guide/changelog/v3.4.8\"},{\"text\":\"v3.4.7\",\"link\":\"/guide/changelog/v3.4.7\"},{\"text\":\"v3.4.6\",\"link\":\"/guide/changelog/v3.4.6\"},{\"text\":\"v3.4.5\",\"link\":\"/guide/changelog/v3.4.5\"},{\"text\":\"v3.4.4\",\"link\":\"/guide/changelog/v3.4.4\"},{\"text\":\"v3.4.3\",\"link\":\"/guide/changelog/v3.4.3\"},{\"text\":\"v3.4.2\",\"link\":\"/guide/changelog/v3.4.2\"},{\"text\":\"v3.4.1\",\"link\":\"/guide/changelog/v3.4.1\"},{\"text\":\"v3.4.0\",\"link\":\"/guide/changelog/v3.4.0\"},{\"text\":\"v3.3.1\",\"link\":\"/guide/changelog/v3.3.1\"},{\"text\":\"v3.3.0\",\"link\":\"/guide/changelog/v3.3.0\"},{\"text\":\"v3.2.7\",\"link\":\"/guide/changelog/v3.2.7\"},{\"text\":\"v3.2.6\",\"link\":\"/guide/changelog/v3.2.6\"},{\"text\":\"v3.2.4\",\"link\":\"/guide/changelog/v3.2.4\"},{\"text\":\"v3.2.3\",\"link\":\"/guide/changelog/v3.2.3\"},{\"text\":\"v3.2.2\",\"link\":\"/guide/changelog/v3.2.2\"},{\"text\":\"v3.2.1\",\"link\":\"/guide/changelog/v3.2.1\"},{\"text\":\"v3.2.0\",\"link\":\"/guide/changelog/v3.2.0\"},{\"text\":\"v3.1.3\",\"link\":\"/guide/changelog/v3.1.3\"},{\"text\":\"v3.1.2\",\"link\":\"/guide/changelog/v3.1.2\"},{\"text\":\"v3.1.1\",\"link\":\"/guide/changelog/v3.1.1\"},{\"text\":\"v3.1.0\",\"link\":\"/guide/changelog/v3.1.0\"},{\"text\":\"v3.0.1\",\"link\":\"/guide/changelog/v3.0.1\"},{\"text\":\"v3.0.0\",\"link\":\"/guide/changelog/v3.0.0\"}]},{\"text\":\"Other Links\",\"collapsed\":false,\"items\":[{\"text\":\"Guide\",\"link\":\"/guide/\"},{\"text\":\"Annotations Reference\",\"link\":\"/annotations/\"},{\"text\":\"Configuration Reference\",\"link\":\"/config/\"}]}],\"/examples/\":[{\"text\":\"Examples\",\"items\":[{\"text\":\"Overview\",\"link\":\"/examples/\"}]},{\"text\":\"Reference\",\"items\":[{\"text\":\"Guide\",\"link\":\"/guide/\"},{\"text\":\"Annotations Reference\",\"link\":\"/annotations/\"},{\"text\":\"Configuration Reference\",\"link\":\"/config/\"},{\"text\":\"Changelog\",\"link\":\"/guide/changelog/\"}]}],\"/guide/\":[{\"text\":\"Getting Started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/guide/\"},{\"text\":\"Installation\",\"link\":\"/guide/installation\"},{\"text\":\"Quick Start\",\"link\":\"/guide/quick-start\"}]},{\"text\":\"Topics\",\"items\":[{\"text\":\"SQL File Endpoints\",\"link\":\"/guide/sql-files\"},{\"text\":\"Configuration Guide\",\"link\":\"/guide/configuration\"},{\"text\":\"Comment Annotations Guide\",\"link\":\"/guide/annotations\"},{\"text\":\"Authentication\",\"link\":\"/guide/authentication\"},{\"text\":\"Server-Sent Events\",\"link\":\"/guide/sse\"},{\"text\":\"HTTP Custom Types\",\"link\":\"/guide/http-types\"},{\"text\":\"Proxy Endpoints\",\"link\":\"/guide/proxy\"},{\"text\":\"Testing\",\"link\":\"/guide/testing\"},{\"text\":\"Logging\",\"link\":\"/guide/logging\"}]},{\"text\":\"Reference\",\"items\":[{\"text\":\"FAQ & Troubleshooting\",\"link\":\"/guide/faq\"},{\"text\":\"Changelog\",\"link\":\"/guide/changelog/\"},{\"text\":\"Examples\",\"link\":\"/examples/\"},{\"text\":\"Annotations Reference\",\"link\":\"/annotations/\"},{\"text\":\"Configuration Reference\",\"link\":\"/config/\"}]}],\"/annotations/\":[{\"text\":\"HTTP & Routing\",\"items\":[{\"text\":\"Overview\",\"link\":\"/annotations/\"},{\"text\":\"HTTP\",\"link\":\"/annotations/http\"},{\"text\":\"PATH\",\"link\":\"/annotations/path\"},{\"text\":\"PROXY\",\"link\":\"/annotations/proxy\"},{\"text\":\"PROXY_OUT\",\"link\":\"/annotations/proxy-out\"},{\"text\":\"INTERNAL\",\"link\":\"/annotations/internal\"},{\"text\":\"ENABLED\",\"link\":\"/annotations/enabled\"},{\"text\":\"DISABLED\",\"link\":\"/annotations/disabled\"},{\"text\":\"TAGS\",\"link\":\"/annotations/tags\"},{\"text\":\"OPENAPI\",\"link\":\"/annotations/openapi\"},{\"text\":\"MCP\",\"link\":\"/annotations/mcp\"},{\"text\":\"HTTP CUSTOM TYPES\",\"link\":\"/annotations/http-type\"}]},{\"text\":\"Authorization\",\"items\":[{\"text\":\"AUTHORIZE\",\"link\":\"/annotations/authorize\"},{\"text\":\"ALLOW_ANONYMOUS\",\"link\":\"/annotations/allow-anonymous\"},{\"text\":\"LOGIN\",\"link\":\"/annotations/login\"},{\"text\":\"LOGOUT\",\"link\":\"/annotations/logout\"},{\"text\":\"BASIC_AUTH\",\"link\":\"/annotations/basic-auth\"},{\"text\":\"BASIC_AUTH_REALM\",\"link\":\"/annotations/basic-auth-realm\"},{\"text\":\"BASIC_AUTH_COMMAND\",\"link\":\"/annotations/basic-auth-command\"}]},{\"text\":\"Request Configuration\",\"items\":[{\"text\":\"REQUEST_PARAM_TYPE\",\"link\":\"/annotations/request-param-type\"},{\"text\":\"REQUEST_HEADERS_MODE\",\"link\":\"/annotations/request-headers-mode\"},{\"text\":\"REQUEST_HEADERS_PARAMETER_NAME\",\"link\":\"/annotations/request-headers-parameter-name\"},{\"text\":\"BODY_PARAMETER_NAME\",\"link\":\"/annotations/body-parameter-name\"},{\"text\":\"QUERY_STRING_NULL_HANDLING\",\"link\":\"/annotations/query-string-null-handling\"},{\"text\":\"VALIDATE\",\"link\":\"/annotations/validate\"}]},{\"text\":\"Response Configuration\",\"items\":[{\"text\":\"Response Headers\",\"link\":\"/annotations/response-headers\"},{\"text\":\"RESPONSE_NULL_HANDLING\",\"link\":\"/annotations/response-null-handling\"},{\"text\":\"NESTED\",\"link\":\"/annotations/nested\"},{\"text\":\"SINGLE\",\"link\":\"/annotations/single\"},{\"text\":\"VOID\",\"link\":\"/annotations/void\"},{\"text\":\"RAW\",\"link\":\"/annotations/raw\"},{\"text\":\"SEPARATOR\",\"link\":\"/annotations/separator\"},{\"text\":\"NEW_LINE\",\"link\":\"/annotations/new-line\"},{\"text\":\"COLUMN_NAMES\",\"link\":\"/annotations/column-names\"}]},{\"text\":\"Caching & Performance\",\"items\":[{\"text\":\"CACHED\",\"link\":\"/annotations/cached\"},{\"text\":\"CACHE_EXPIRES_IN\",\"link\":\"/annotations/cache-expires-in\"},{\"text\":\"CACHE_PROFILE\",\"link\":\"/annotations/cache-profile\"},{\"text\":\"BUFFER_ROWS\",\"link\":\"/annotations/buffer-rows\"},{\"text\":\"COMMAND_TIMEOUT\",\"link\":\"/annotations/command-timeout\"},{\"text\":\"RETRY_STRATEGY\",\"link\":\"/annotations/retry-strategy\"},{\"text\":\"Interval Format\",\"link\":\"/annotations/interval-format\"}]},{\"text\":\"Server-Sent Events\",\"items\":[{\"text\":\"SSE\",\"link\":\"/annotations/sse\"},{\"text\":\"SSE_EVENTS_LEVEL\",\"link\":\"/annotations/sse-events-level\"},{\"text\":\"SSE_EVENTS_SCOPE\",\"link\":\"/annotations/sse-events-scope\"}]},{\"text\":\"Upload & Policies\",\"items\":[{\"text\":\"UPLOAD\",\"link\":\"/annotations/upload\"},{\"text\":\"ERROR_CODE_POLICY\",\"link\":\"/annotations/error-code-policy\"},{\"text\":\"RATE_LIMITER_POLICY\",\"link\":\"/annotations/rate-limiter-policy\"}]},{\"text\":\"Output & Code Generation\",\"items\":[{\"text\":\"TABLE_FORMAT\",\"link\":\"/annotations/table-format\"},{\"text\":\"TSCLIENT\",\"link\":\"/annotations/tsclient\"}]},{\"text\":\"Parameters\",\"items\":[{\"text\":\"PARAM\",\"link\":\"/annotations/param\"},{\"text\":\"PARAMETER_HASH\",\"link\":\"/annotations/parameter-hash\"},{\"text\":\"ENCRYPT / DECRYPT\",\"link\":\"/annotations/encrypt-decrypt\"},{\"text\":\"Parameter Value Substitution\",\"link\":\"/annotations/parameter-substitution\"},{\"text\":\"Resolved Parameters\",\"link\":\"/annotations/resolved-parameters\"}]},{\"text\":\"SQL File Annotations\",\"items\":[{\"text\":\"DEFINE_PARAM\",\"link\":\"/annotations/define-param\"},{\"text\":\"RESULT_NAME\",\"link\":\"/annotations/result-name\"},{\"text\":\"SKIP\",\"link\":\"/annotations/skip\"},{\"text\":\"RETURNS\",\"link\":\"/annotations/returns\"}]},{\"text\":\"Test Files (--test)\",\"items\":[{\"text\":\"TEST @setup\",\"link\":\"/annotations/test-setup\"},{\"text\":\"TEST @teardown\",\"link\":\"/annotations/test-teardown\"},{\"text\":\"TEST @connection\",\"link\":\"/annotations/test-connection\"},{\"text\":\"TEST @tag\",\"link\":\"/annotations/test-tag\"},{\"text\":\"TEST @claim\",\"link\":\"/annotations/test-claim\"},{\"text\":\"TEST @response\",\"link\":\"/annotations/test-response\"}]},{\"text\":\"Context & Security\",\"items\":[{\"text\":\"USER_CONTEXT\",\"link\":\"/annotations/user-context\"},{\"text\":\"USER_PARAMETERS\",\"link\":\"/annotations/user-parameters\"},{\"text\":\"CONNECTION\",\"link\":\"/annotations/connection\"},{\"text\":\"SECURITY_SENSITIVE\",\"link\":\"/annotations/security-sensitive\"},{\"text\":\"Custom Parameters\",\"link\":\"/annotations/custom-parameters\"}]},{\"text\":\"Other Links\",\"collapsed\":false,\"items\":[{\"text\":\"Guide\",\"link\":\"/guide/\"},{\"text\":\"Configuration Reference\",\"link\":\"/config/\"},{\"text\":\"Changelog\",\"link\":\"/guide/changelog/\"}]}],\"/config/\":[{\"text\":\"Core Settings\",\"items\":[{\"text\":\"Overview\",\"link\":\"/config/\"},{\"text\":\"Latest Default Configuration\",\"link\":\"/config/latest\"},{\"text\":\"Top-Level Settings\",\"link\":\"/config/top-level\"},{\"text\":\"Config Section\",\"link\":\"/config/config-section\"},{\"text\":\"NpgsqlRest Options\",\"link\":\"/config/npgsqlrest\"},{\"text\":\"Routine Options\",\"link\":\"/config/routine-options\"},{\"text\":\"Connection Settings\",\"link\":\"/config/connection\"},{\"text\":\"Server & SSL\",\"link\":\"/config/server\"}]},{\"text\":\"Security\",\"items\":[{\"text\":\"Authentication\",\"link\":\"/config/auth\"},{\"text\":\"External OAuth\",\"link\":\"/config/external-auth\"},{\"text\":\"Passkey Authentication\",\"link\":\"/config/passkey-auth\"},{\"text\":\"Authentication Options\",\"link\":\"/config/authentication-options\"},{\"text\":\"Claims Mapping\",\"link\":\"/config/claims-mapping\"},{\"text\":\"Basic Auth Config\",\"link\":\"/config/basic-auth-config\"},{\"text\":\"Validation\",\"link\":\"/config/validation\"},{\"text\":\"Antiforgery\",\"link\":\"/config/antiforgery\"},{\"text\":\"Data Protection\",\"link\":\"/config/data-protection\"},{\"text\":\"CORS\",\"link\":\"/config/cors\"},{\"text\":\"Security Headers\",\"link\":\"/config/security-headers\"},{\"text\":\"Forwarded Headers\",\"link\":\"/config/forwarded-headers\"}]},{\"text\":\"Features\",\"items\":[{\"text\":\"SQL File Source\",\"link\":\"/config/sql-file-source\"},{\"text\":\"Test Runner\",\"link\":\"/config/test-runner\"},{\"text\":\"Watch Mode\",\"link\":\"/config/watch\"},{\"text\":\"Proxy\",\"link\":\"/config/proxy\"},{\"text\":\"OpenAPI\",\"link\":\"/config/openapi\"},{\"text\":\"MCP\",\"link\":\"/config/mcp\"},{\"text\":\"HTTP Files\",\"link\":\"/config/http-files\"},{\"text\":\"Code Generation\",\"link\":\"/config/codegen\"},{\"text\":\"Upload Options\",\"link\":\"/config/uploads\"},{\"text\":\"Table Format\",\"link\":\"/config/table-format\"},{\"text\":\"HTTP Client\",\"link\":\"/config/http-client\"}]},{\"text\":\"Performance\",\"items\":[{\"text\":\"Response Compression\",\"link\":\"/config/response-compression\"},{\"text\":\"Cache Options\",\"link\":\"/config/cache-options\"},{\"text\":\"Rate Limiter\",\"link\":\"/config/rate-limiter\"},{\"text\":\"Command Retry\",\"link\":\"/config/command-retry\"},{\"text\":\"Thread Pool\",\"link\":\"/config/thread-pool\"}]},{\"text\":\"Infrastructure\",\"items\":[{\"text\":\"Logging\",\"link\":\"/config/logging\"},{\"text\":\"Static Files\",\"link\":\"/config/static-files\"},{\"text\":\"Error Handling\",\"link\":\"/config/error-handling\"},{\"text\":\"Health Checks\",\"link\":\"/config/health-checks\"},{\"text\":\"Stats\",\"link\":\"/config/stats\"}]},{\"text\":\"Other Links\",\"collapsed\":false,\"items\":[{\"text\":\"Guide\",\"link\":\"/guide/\"},{\"text\":\"Annotations Reference\",\"link\":\"/annotations/\"}]}]},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/NpgsqlRest/NpgsqlRest\"},{\"icon\":{\"svg\":\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"currentColor\\\"><path d=\\\"M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 7.463 3.097 9.746 2.602 2.124 6.19 2.078 9.402 1.836 1.883-.142 3.939-.358 5.477-1.528 1.564-1.19 1.873-3.298 1.972-5.151.134-2.51.187-5.016-.037-7.233zm-2.55 7.703c-.078 1.593-.383 3.473-1.795 4.334-1.351.824-3.151.973-4.686 1.083-2.891.207-6.063.276-8.514-1.399C3.106 17.39 2.924 14.34 2.95 11.67c.03-3.206.678-6.721 3.654-8.375 2.756-1.531 6.556-1.727 9.544-.872 2.339.669 4.351 2.678 4.355 5.217.007 2.583-.016 5.168-.095 7.273z\\\"/><path d=\\\"M16.088 5.19c-1.008-.542-2.607-.48-3.441.388-.568.591-.773 1.389-.8 2.172-.034.993.068 2.013.361 2.953.307.985 1.034 1.848 2.077 2.012.878.138 1.83-.088 2.458-.732.7-.718.88-1.81.877-2.779-.003-.989-.084-1.99-.423-2.91-.268-.726-.654-1.328-1.109-1.104zm-.294 5.482c-.182.462-.581.771-1.091.696-.532-.078-.859-.533-1.04-1.005-.248-.647-.327-1.375-.312-2.06.01-.46.095-.939.371-1.313.345-.467.993-.447 1.426-.115.41.315.607.835.74 1.32.18.66.211 1.675-.094 2.477zM8.4 10.394c.233 1.084.755 2.299 1.907 2.579.934.227 1.993-.165 2.434-1.048.455-.91.346-1.995.166-2.972-.165-.893-.46-1.885-1.207-2.445-.745-.559-1.832-.457-2.479.192-.84.843-.958 2.138-.955 3.277.001.147.119.364.134.417zm1.363-2.808c.302-.321.805-.336 1.14-.054.445.375.618 1.015.75 1.558.131.54.212 1.156.082 1.703-.1.423-.378.821-.84.882-.469.062-.886-.306-1.088-.704-.326-.644-.401-1.426-.381-2.148.013-.465.104-.993.337-1.237z\\\"/></svg>\"},\"link\":\"https://patreon.com/vbconsulting\",\"ariaLabel\":\"Patreon\"},{\"icon\":{\"svg\":\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"currentColor\\\"><path d=\\\"M20.216 6.415l-.132-.666c-.119-.598-.388-1.163-1.001-1.379-.197-.069-.42-.098-.57-.241-.152-.143-.196-.366-.231-.572-.065-.378-.125-.756-.192-1.133-.057-.325-.102-.69-.25-.987-.195-.4-.597-.634-.996-.788a5.723 5.723 0 00-.626-.194c-1-.263-2.05-.36-3.077-.416a25.834 25.834 0 00-3.7.062c-.915.083-1.88.184-2.75.5-.318.116-.646.256-.888.501-.297.302-.393.77-.177 1.146.154.267.415.456.692.58.36.162.737.284 1.123.366 1.075.238 2.189.331 3.287.37 1.218.05 2.437.01 3.65-.118.299-.033.598-.073.896-.119.352-.054.578-.513.474-.834-.124-.383-.457-.531-.834-.473-.466.074-.96.108-1.382.146-1.177.08-2.358.082-3.536.006a22.228 22.228 0 01-1.157-.107c-.086-.01-.18-.025-.258-.036-.243-.036-.484-.08-.724-.13-.111-.027-.111-.185 0-.212h.005c.277-.06.557-.108.838-.147h.002c.131-.009.263-.032.394-.048a25.076 25.076 0 013.426-.12c.674.019 1.347.067 2.017.144l.228.031c.267.04.533.088.798.145.392.085.895.113 1.07.542.055.137.08.288.111.431l.319 1.484a.237.237 0 01-.199.284h-.003c-.037.006-.075.01-.112.015a36.704 36.704 0 01-4.743.295 37.059 37.059 0 01-4.699-.304c-.14-.017-.293-.042-.417-.06-.326-.048-.649-.108-.973-.161-.393-.065-.768-.032-1.123.161-.29.16-.527.404-.675.701-.154.316-.199.66-.267 1-.069.34-.176.707-.135 1.056.087.753.613 1.365 1.37 1.502a39.69 39.69 0 0011.343.376.483.483 0 01.535.53l-.071.697-1.018 9.907c-.041.41-.047.832-.125 1.237-.122.637-.553 1.028-1.182 1.171-.577.131-1.165.2-1.756.205-.656.004-1.31-.025-1.966-.022-.699.004-1.556-.06-2.095-.58-.475-.458-.54-1.174-.605-1.793l-.731-7.013-.322-3.094c-.037-.351-.286-.695-.678-.678-.336.015-.718.3-.678.679l.228 2.185.949 9.112c.147 1.344 1.174 2.068 2.446 2.272.742.12 1.503.144 2.257.156.966.016 1.942.053 2.892-.122 1.408-.258 2.465-1.198 2.616-2.657.34-3.332.683-6.663 1.024-9.995l.215-2.087a.484.484 0 01.39-.426c.402-.078.787-.212 1.074-.518.455-.488.546-1.124.385-1.766zm-1.478.772c-.145.137-.363.201-.578.233-2.416.359-4.866.54-7.308.46-1.748-.06-3.477-.254-5.207-.498-.17-.024-.353-.055-.47-.18-.22-.236-.111-.71-.054-.995.052-.26.152-.609.463-.646.484-.057 1.046.148 1.526.22.577.088 1.156.159 1.737.212 2.48.226 5.002.19 7.472-.14.45-.06.899-.13 1.345-.21.399-.072.84-.206 1.08.206.166.281.188.657.162.974a.544.544 0 01-.169.364z\\\"/></svg>\"},\"link\":\"https://buymeacoffee.com/vbilopavu\",\"ariaLabel\":\"Buy Me a Coffee\"}],\"editLink\":{\"pattern\":\"https://github.com/NpgsqlRest/npgsqlrest-docs/edit/main/docs/:path\",\"text\":\"Edit this page on GitHub\"},\"search\":{\"provider\":\"local\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
</body>
</html>