-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfaq.html
More file actions
81 lines (79 loc) · 154 KB
/
Copy pathfaq.html
File metadata and controls
81 lines (79 loc) · 154 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
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>FAQ & Troubleshooting | NpgsqlRest</title>
<meta name="description" content="Frequently asked questions about NpgsqlRest: missing endpoints, 404s, parameter naming, authentication, login endpoints, uploads, SSE, CORS, deployment, testing, performance, logging, and troubleshooting.">
<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_faq.md.DzLvzPIX.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 faq, npgsqlrest troubleshooting, endpoint not found, postgresql rest api questions, npgsqlrest 404, sql injection, npgsqlrest testing, npgsqlrest cors, postgresql login endpoint, file upload postgresql, server-sent events postgresql">
<meta property="og:title" content="NpgsqlRest FAQ & Troubleshooting">
<meta property="og:description" content="Frequently asked questions about NpgsqlRest.">
<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" 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 active" 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" 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 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>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_faq" data-v-39a288b8><div><h1 id="faq-troubleshooting" tabindex="-1">FAQ & Troubleshooting <a class="header-anchor" href="#faq-troubleshooting" aria-label="Permalink to "FAQ & Troubleshooting""></a></h1><h2 id="general" tabindex="-1">General <a class="header-anchor" href="#general" aria-label="Permalink to "General""></a></h2><h3 id="what-is-npgsqlrest" tabindex="-1">What is NpgsqlRest? <a class="header-anchor" href="#what-is-npgsqlrest" aria-label="Permalink to "What is NpgsqlRest?""></a></h3><p>NpgsqlRest is a self-contained executable that connects to PostgreSQL and automatically creates REST API endpoints from plain SQL script files, database functions, and procedures. No code generation step, no ORM — just SQL.</p><h3 id="what-postgresql-versions-are-supported" tabindex="-1">What PostgreSQL versions are supported? <a class="header-anchor" href="#what-postgresql-versions-are-supported" aria-label="Permalink to "What PostgreSQL versions are supported?""></a></h3><p>PostgreSQL 13 and newer. Discovery uses standard <code>pg_catalog</code> views that are stable across PostgreSQL versions.</p><h3 id="what-net-version-is-required" tabindex="-1">What .NET version is required? <a class="header-anchor" href="#what-net-version-is-required" aria-label="Permalink to "What .NET version is required?""></a></h3><p>None, for most users — the standalone executable and the Docker image are fully self-contained (AOT-compiled). The NuGet library targets .NET 10.</p><h3 id="is-it-safe-from-sql-injection" tabindex="-1">Is it safe from SQL injection? <a class="header-anchor" href="#is-it-safe-from-sql-injection" aria-label="Permalink to "Is it safe from SQL injection?""></a></h3><p>Yes, by construction. Client-supplied values are <strong>always</strong> sent as PostgreSQL protocol parameters — never concatenated into SQL text. The SQL that runs is the SQL you wrote in the file, function, or procedure; a request can only choose parameter <em>values</em>, never SQL fragments. There is no query-building layer to inject into (unlike REST-to-SQL translators that construct queries from URLs).</p><h3 id="how-does-npgsqlrest-compare-to-postgrest-or-supabase" tabindex="-1">How does NpgsqlRest compare to PostgREST or Supabase? <a class="header-anchor" href="#how-does-npgsqlrest-compare-to-postgrest-or-supabase" aria-label="Permalink to "How does NpgsqlRest compare to PostgREST or Supabase?""></a></h3><p>See the detailed <a href="/blog/npgsqlrest-vs-postgrest-supabase-comparison.html">comparison blog post</a> for a full feature-by-feature breakdown. The short version: PostgREST turns your <em>tables</em> into an API you query from the client; NpgsqlRest turns your <em>SQL</em> (files, functions, procedures) into an API you design.</p><h3 id="can-i-use-it-inside-an-existing-asp-net-core-application" tabindex="-1">Can I use it inside an existing ASP.NET Core application? <a class="header-anchor" href="#can-i-use-it-inside-an-existing-asp-net-core-application" aria-label="Permalink to "Can I use it inside an existing ASP.NET Core application?""></a></h3><p>Yes — the standalone executable is a wrapper around the <code>NpgsqlRest</code> NuGet middleware. In your own app: <code>app.UseNpgsqlRest(new NpgsqlRestOptions(connectionString) { ... })</code>. The plugins (SQL file source, TypeScript client, OpenAPI, MCP) are separate NuGet packages.</p><h3 id="can-npgsqlrest-also-serve-my-frontend-static-files-spa" tabindex="-1">Can NpgsqlRest also serve my frontend (static files, SPA)? <a class="header-anchor" href="#can-npgsqlrest-also-serve-my-frontend-static-files-spa" aria-label="Permalink to "Can NpgsqlRest also serve my frontend (static files, SPA)?""></a></h3><p>Yes — enable the <code>StaticFiles</code> section (root defaults to <code>wwwroot</code>) and it serves your SPA or static site from the same host as the API. <code>AuthorizePaths</code> puts paths behind login (with <code>UnauthorizedRedirectPath</code> for the redirect), and <code>ParseContentOptions</code> can template user claims and allow-listed environment variables into HTML at serve time — per-environment SPA config without a build step. See <a href="/config/static-files.html">Static Files</a>.</p><hr><h2 id="installation-setup" tabindex="-1">Installation & Setup <a class="header-anchor" href="#installation-setup" aria-label="Permalink to "Installation & Setup""></a></h2><h3 id="how-do-i-install-npgsqlrest" tabindex="-1">How do I install NpgsqlRest? <a class="header-anchor" href="#how-do-i-install-npgsqlrest" aria-label="Permalink to "How do I install NpgsqlRest?""></a></h3><p>See the <a href="/guide/installation.html">Installation Guide</a> — standalone executable (Linux/macOS/Windows), an npm package (<code>npm i npgsqlrest</code>), a Docker image, or NuGet.</p><h3 id="how-do-i-run-it-in-docker" tabindex="-1">How do I run it in Docker? <a class="header-anchor" href="#how-do-i-run-it-in-docker" aria-label="Permalink to "How do I run it in Docker?""></a></h3><details class="code-collapsible" open><summary>sh</summary><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes catppuccin-latte catppuccin-mocha vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic;">docker</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> run</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> --name</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> npgsqlrest</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> -p</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 8080:8080</span><span style="--shiki-light:#EA76CB;--shiki-dark:#F5C2E7;"> \</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> -v</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> ./appsettings.json:/app/appsettings.json</span><span style="--shiki-light:#EA76CB;--shiki-dark:#F5C2E7;"> \</span></span>
<span class="line"><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> vbilopav/npgsqlrest:latest</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>Remember that <code>localhost</code> inside the container is the container — point the connection string at <code>host.docker.internal</code> (or the compose service name) to reach your database.</p><h3 id="how-do-i-connect-to-my-database" tabindex="-1">How do I connect to my database? <a class="header-anchor" href="#how-do-i-connect-to-my-database" aria-label="Permalink to "How do I connect to my database?""></a></h3><p>Set the connection string in <code>appsettings.json</code>:</p><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;">ConnectionStrings</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;">Default</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;"> "Host=localhost;Port=5432;Database=mydb;Username=postgres;Password=postgres"</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></div></div></details><p>See <a href="/config/connection.html">Connection Settings</a> for all options.</p><h3 id="what-if-npgsqlrest-won-t-start-because-the-database-is-down" tabindex="-1">What if NpgsqlRest won't start because the database is down? <a class="header-anchor" href="#what-if-npgsqlrest-won-t-start-because-the-database-is-down" aria-label="Permalink to "What if NpgsqlRest won't start because the database is down?""></a></h3><p>By default <code>TestConnectionStrings: true</code> opens a test connection at startup. If it fails, the client retries on a 1, 3, 6, 12-second sequence for transient errors (connection drops, timeouts), then exits with an error if all retries fail. To skip the startup test, set <code>TestConnectionStrings: false</code>, or disable retries with <code>ConnectionRetryOptions.Enabled: false</code>. This is useful when you want the server to start even if PostgreSQL isn't ready yet.</p><h3 id="can-i-use-environment-variables-for-configuration" tabindex="-1">Can I use environment variables for configuration? <a class="header-anchor" href="#can-i-use-environment-variables-for-configuration" aria-label="Permalink to "Can I use environment variables for configuration?""></a></h3><p>Yes. With <code>ParseEnvironmentVariables</code> in the <code>Config</code> section (enabled by default), use <code>{ENV_VAR_NAME}</code> placeholders in configuration values — optional by default, or <code>{!ENV_VAR_NAME}</code> for required (startup error when unset, since 3.17.0). An <code>.env</code> file is supported via the <code>EnvFile</code> option. Any setting can also be overridden on the command line: <code>npgsqlrest --npgsqlrest:urlpathprefix=/v1</code>.</p><h3 id="how-do-i-change-the-port-bind-address-or-enable-https" tabindex="-1">How do I change the port, bind address, or enable HTTPS? <a class="header-anchor" href="#how-do-i-change-the-port-bind-address-or-enable-https" aria-label="Permalink to "How do I change the port, bind address, or enable HTTPS?""></a></h3><p>Set the top-level <code>Urls</code> option — the default is <code>http://localhost:8080</code>; use <code>http://0.0.0.0:8080</code> to listen on all interfaces (semicolon-separate multiple URLs). HTTPS is enabled with the <code>Ssl</code> section (redirection and HSTS are on once enabled) and a certificate configured under <code>Kestrel</code> — PFX, PEM, or the Windows certificate store. See <a href="/config/server.html">Server settings</a>.</p><hr><h2 id="endpoints" tabindex="-1">Endpoints <a class="header-anchor" href="#endpoints" aria-label="Permalink to "Endpoints""></a></h2><h3 id="my-function-doesn-t-appear-as-an-endpoint" tabindex="-1">My function doesn't appear as an endpoint <a class="header-anchor" href="#my-function-doesn-t-appear-as-an-endpoint" aria-label="Permalink to "My function doesn't appear as an endpoint""></a></h3><p>Check these causes, most common first:</p><ol><li><strong>No <code>HTTP</code> annotation</strong> — since 3.17.0 the client defaults to <code>CommentsMode: "OnlyAnnotated"</code>: a routine becomes an endpoint <strong>only if its comment contains an HTTP annotation</strong> (or a plugin annotation like <code>@mcp</code>). Add one — <code>comment on function my_func() is 'HTTP GET';</code> — or set <code>CommentsMode: "ParseAll"</code> to expose everything discovered.</li><li><strong>Schema not included</strong>: by default only the <code>public</code> schema is scanned. Adjust <code>SchemaSimilarTo</code> in <a href="/config/npgsqlrest.html">NpgsqlRest Options</a>.</li><li><strong>Insufficient privileges</strong>: the connection's database user needs <code>EXECUTE</code> on the function and <code>USAGE</code> on the schema.</li><li><strong>A <code>@disabled</code> annotation</strong> on the routine.</li><li><strong>Check the logs</strong>: run with the <code>NpgsqlRest</code> log level at <code>Debug</code> to see what was discovered and skipped.</li></ol><h3 id="my-sql-file-doesn-t-appear-as-an-endpoint" tabindex="-1">My SQL file doesn't appear as an endpoint <a class="header-anchor" href="#my-sql-file-doesn-t-appear-as-an-endpoint" aria-label="Permalink to "My SQL file doesn't appear as an endpoint""></a></h3><p>Same <code>CommentsMode</code> rule as functions — the file needs an <code>HTTP</code> annotation by default. Two additional file-specific causes:</p><ol><li><strong><code>SkipPattern</code></strong> — files matching <code>SqlFileSource.SkipPattern</code> (default <code>"*.test.sql"</code>) are excluded from endpoint discovery; they're test files for the <a href="/guide/testing.html">test runner</a>.</li><li><strong>A describe error with <code>ErrorMode: "Skip"</code></strong> — the file failed type-checking against the database and was skipped with a logged error. (<code>ErrorMode: "Exit"</code>, the default, would have stopped startup and shown it.)</li></ol><h3 id="an-endpoint-exists-but-i-get-404-—-why" tabindex="-1">An endpoint exists but I get 404 — why? <a class="header-anchor" href="#an-endpoint-exists-but-i-get-404-—-why" aria-label="Permalink to "An endpoint exists but I get 404 — why?""></a></h3><p>A 404 for an existing path is almost always <strong>parameter matching</strong>: a request must supply values for <strong>all parameters without defaults</strong>, with <strong>matching names</strong> — otherwise no endpoint matches and the response is 404 (not 400). Check:</p><ol><li><strong>Parameter names are converted</strong> — <code>p_user_id</code> becomes <code>pUserId</code> with the default camelCase converter. The generated <a href="/config/codegen.html">TypeScript client</a> or <a href="/config/http-files.html">HTTP file</a> always shows the exact names.</li><li><strong>Missing required parameter</strong> — give it a default (<code>@param name default null</code> in SQL files, <code>DEFAULT</code> in function signatures) to make it optional.</li><li><strong>The path prefix</strong> — the full path includes <code>UrlPathPrefix</code> (default <code>/api</code>).</li><li><strong>The HTTP method</strong> — <code>select</code> files/functions map to GET by default; mutations map to PUT/POST/DELETE.</li></ol><h3 id="why-did-my-read-only-function-become-a-post-endpoint" tabindex="-1">Why did my read-only function become a POST endpoint? <a class="header-anchor" href="#why-did-my-read-only-function-become-a-post-endpoint" aria-label="Permalink to "Why did my read-only function become a POST endpoint?""></a></h3><p>For functions, the HTTP method is inferred from PostgreSQL <strong>volatility</strong> — and <code>VOLATILE</code> is PostgreSQL's default, so a plain function maps to a mutation unless it is declared <code>STABLE</code> or <code>IMMUTABLE</code>, its name starts with <code>get_</code>, contains <code>_get_</code>, or ends with <code>_get</code>. Fix: declare read functions <code>STABLE</code> (good practice anyway), use a <code>get_</code> name, or state the method explicitly in the comment: <code>HTTP GET</code>. See <a href="/guide/annotations.html">Comment Annotations</a>.</p><h3 id="are-parameters-sent-in-the-query-string-or-the-request-body" tabindex="-1">Are parameters sent in the query string or the request body? <a class="header-anchor" href="#are-parameters-sent-in-the-query-string-or-the-request-body" aria-label="Permalink to "Are parameters sent in the query string or the request body?""></a></h3><p>By HTTP method: GET and DELETE endpoints read parameters from the <strong>query string</strong>; POST, PUT, and other methods read a <strong>JSON body</strong>. Override per endpoint with <a href="/annotations/request-param-type.html"><code>@request_param_type</code></a> (<code>query_string</code> or <code>body_json</code>), or globally with <code>DefaultRequestParamType</code>. Sending parameters the wrong way means no endpoint matches — a 404, not a 400.</p><h3 id="why-are-parameter-and-column-names-camelcased-how-do-i-turn-that-off" tabindex="-1">Why are parameter and column names camelCased? How do I turn that off? <a class="header-anchor" href="#why-are-parameter-and-column-names-camelcased-how-do-i-turn-that-off" aria-label="Permalink to "Why are parameter and column names camelCased? How do I turn that off?""></a></h3><p>The default <code>NameConverter</code> converts <code>snake_case</code> PostgreSQL names to <code>camelCase</code> JSON/URL names. Set <code>"CamelCaseNames": false</code> in the <code>NpgsqlRest</code> section to keep names exactly as they are in the database.</p><h3 id="my-query-returns-one-row-—-why-do-i-get-an-array" tabindex="-1">My query returns one row — why do I get an array? <a class="header-anchor" href="#my-query-returns-one-row-—-why-do-i-get-an-array" aria-label="Permalink to "My query returns one row — why do I get an array?""></a></h3><p>Endpoints return arrays by default. Annotate with <a href="/annotations/single.html"><code>@single</code></a> to return the first row as a single JSON object, or combine with <code>@nested</code> for composite shapes. A single-column result set returns a flat value array (<code>["a","b"]</code>) — that's the <code>UnnamedSingleColumnSet</code> default in <a href="/config/sql-file-source.html">SQL File Source</a>.</p><h3 id="how-do-i-return-plain-text-html-or-csv-instead-of-json" tabindex="-1">How do I return plain text, HTML, or CSV instead of JSON? <a class="header-anchor" href="#how-do-i-return-plain-text-html-or-csv-instead-of-json" aria-label="Permalink to "How do I return plain text, HTML, or CSV instead of JSON?""></a></h3><p>Use <a href="/annotations/raw.html"><code>@raw</code></a> — the column values are written to the response verbatim, with <a href="/annotations/separator.html"><code>@separator</code> and <code>@new_line</code></a> for delimiter control, plus a <code>Content-Type</code> response header:</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;">-- 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;">-- @raw</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- @separator ,</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- @new_line \n</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">-- Content-Type: text/csv</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">select</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> id, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">name</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, price </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">from</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> products;</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></div></div></details><p>There is also a <a href="/config/table-format.html">table format</a> output mode for ready-made HTML tables and Excel exports.</p><h3 id="how-do-i-return-a-specific-http-status-code-from-sql" tabindex="-1">How do I return a specific HTTP status code from SQL? <a class="header-anchor" href="#how-do-i-return-a-specific-http-status-code-from-sql" aria-label="Permalink to "How do I return a specific HTTP status code from SQL?""></a></h3><p><code>raise exception 'message';</code> surfaces as HTTP 400 by default (SQLSTATE <code>P0001</code>), insufficient privilege (<code>42501</code>) as 403, and command timeouts as 504. The whole mapping is configurable — <code>ErrorHandlingOptions</code> maps any PostgreSQL SQLSTATE to any status code through named policies, so <code>raise exception ... using errcode = '...'</code> plus a policy entry gives full status control from SQL (e.g. map <code>23505</code> unique violations to 409). Apply a policy per endpoint with <a href="/annotations/error-code-policy.html"><code>@error_code_policy</code></a>; unmapped errors return 500. See <a href="/config/error-handling.html">Error Handling</a>.</p><h3 id="how-do-i-set-response-headers-like-content-disposition-or-set-cookie" tabindex="-1">How do I set response headers like <code>Content-Disposition</code> or <code>Set-Cookie</code>? <a class="header-anchor" href="#how-do-i-set-response-headers-like-content-disposition-or-set-cookie" aria-label="Permalink to "How do I set response headers like `Content-Disposition` or `Set-Cookie`?""></a></h3><p>Write plain <code>Header-Name: value</code> lines in the comment — the same way the CSV example above sets <code>Content-Type</code>. Values support <code>{parameter}</code> substitution, so a dynamic download filename is one line: <code>Content-Disposition: attachment; filename={name}.csv</code>. Repeated header names combine into one header. See <a href="/annotations/response-headers.html">Response Headers</a> and <a href="/annotations/parameter-substitution.html">parameter substitution</a>.</p><h3 id="can-one-sql-file-run-multiple-statements" tabindex="-1">Can one SQL file run multiple statements? <a class="header-anchor" href="#can-one-sql-file-run-multiple-statements" aria-label="Permalink to "Can one SQL file run multiple statements?""></a></h3><p>Yes — a multi-statement file executes as a single batch (one database round-trip) and returns a JSON object with one key per result set: <code>{"result1": ..., "result2": ...}</code>. Name the keys with <a href="/annotations/result-name.html"><code>@result</code></a>, drop a statement's output with <a href="/annotations/skip.html"><code>@skip</code></a> (it still executes), or return <code>204 No Content</code> with <a href="/annotations/void.html"><code>@void</code></a>; <code>BEGIN</code>/<code>COMMIT</code>/<code>SET</code> statements are hidden automatically. All statements share the same parameters. See <a href="/guide/sql-files.html">SQL File Endpoints</a>.</p><h3 id="how-do-i-customize-the-endpoint-url-path" tabindex="-1">How do I customize the endpoint URL path? <a class="header-anchor" href="#how-do-i-customize-the-endpoint-url-path" aria-label="Permalink to "How do I customize the endpoint URL path?""></a></h3><p>Use the <a href="/annotations/path.html"><code>@path</code></a> annotation — <code>-- @path /custom/path</code> in a SQL file, or the same line in a function comment. Versioning works the same way: <code>@path /v2/orders</code>.</p><h3 id="how-do-i-restrict-access-to-an-endpoint" tabindex="-1">How do I restrict access to an endpoint? <a class="header-anchor" href="#how-do-i-restrict-access-to-an-endpoint" aria-label="Permalink to "How do I restrict access to an endpoint?""></a></h3><p>Use <a href="/annotations/authorize.html"><code>@authorize</code></a>, optionally with roles: <code>-- @authorize admin, manager</code>. Mind the default posture, though: the standalone client ships with <code>RequiresAuthorization: true</code>, so <strong>every endpoint already requires an authenticated user</strong> and <a href="/annotations/allow-anonymous.html"><code>@allow_anonymous</code></a> opts out per endpoint. Set <code>NpgsqlRest.RequiresAuthorization</code> to <code>false</code> for public-by-default endpoints where <code>@authorize</code> opts in (that is the NuGet library's default).</p><h3 id="can-i-expose-tables-and-views-directly-without-writing-any-sql" tabindex="-1">Can I expose tables and views directly, without writing any SQL? <a class="header-anchor" href="#can-i-expose-tables-and-views-directly-without-writing-any-sql" aria-label="Permalink to "Can I expose tables and views directly, without writing any SQL?""></a></h3><p>That's deliberately not the default model — NpgsqlRest wants you to <em>design</em> the API surface. The closest thing is a one-line SQL file per operation (<code>select * from my_view;</code> is a complete endpoint file). If you want fully automatic table CRUD, the <code>NpgsqlRest.CrudSource</code> NuGet plugin exists for library users, but plain SQL files are the recommended path.</p><hr><h2 id="parameters" tabindex="-1">Parameters <a class="header-anchor" href="#parameters" aria-label="Permalink to "Parameters""></a></h2><h3 id="named-or-positional-parameters-in-sql-files-—-which-should-i-use" tabindex="-1">Named or positional parameters in SQL files — which should I use? <a class="header-anchor" href="#named-or-positional-parameters-in-sql-files-—-which-should-i-use" aria-label="Permalink to "Named or positional parameters in SQL files — which should I use?""></a></h3><p>Named (<code>:name</code>, since 3.19.0) for almost everything — the placeholder is the parameter name, so no <code>@param</code> naming annotations are needed, and the same name used repeatedly (even across statements) is one parameter:</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;">-- HTTP GET</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">select</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> id, title </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">from</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> reports</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">where</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> created_at </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">between</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> :from_date </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">and</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> :to_date;</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><code>GET /api/get-reports?fromDate=...&toDate=...</code> — done. Positional (<code>$1</code>, <code>$2</code>) remains fully supported; one style per file. See <a href="/guide/sql-files.html#parameters">SQL File Endpoints — Parameters</a>.</p><h3 id="how-do-i-make-a-parameter-optional" tabindex="-1">How do I make a parameter optional? <a class="header-anchor" href="#how-do-i-make-a-parameter-optional" aria-label="Permalink to "How do I make a parameter optional?""></a></h3><p>Give it a default. Functions: the native <code>DEFAULT</code> clause. SQL files: the <code>@param</code> annotation — <code>-- @param status default 'active'</code> or <code>-- @param label default null</code>. A parameter without a default is required, and a request missing it gets a 404 (no matching endpoint).</p><h3 id="how-do-i-get-the-authenticated-user-s-id-into-a-query" tabindex="-1">How do I get the authenticated user's ID into a query? <a class="header-anchor" href="#how-do-i-get-the-authenticated-user-s-id-into-a-query" aria-label="Permalink to "How do I get the authenticated user's ID into a query?""></a></h3><p>Enable claim-to-parameter mapping with <a href="/annotations/user-parameters.html"><code>@user_parameters</code></a> and use a parameter whose <strong>name matches a claim mapping</strong> (default: <code>_user_id</code> → the user-id claim). With named parameters this needs nothing else:</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;">-- 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;">-- @user_parameters</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">select</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> id, total, </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">status</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">from</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> orders</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">where</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> user_id </span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;">=</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></div></div></details><p>The value comes from the authenticated principal — the client cannot send or override it. (With positional parameters, add <code>-- @param $1 _user_id</code> to give <code>$1</code> the mapped name.) To read claims as session settings instead of parameters, <a href="/annotations/user-context.html"><code>@user_context</code></a> exposes them to <code>current_setting('request.user_id', true)</code>, <code>request.user_roles</code>, <code>request.ip_address</code>, and friends.</p><h3 id="how-do-i-send-an-array-parameter" tabindex="-1">How do I send an array parameter? <a class="header-anchor" href="#how-do-i-send-an-array-parameter" aria-label="Permalink to "How do I send an array parameter?""></a></h3><p>In a query string, repeat the key: <code>?ids=1&ids=2&ids=3</code> binds a three-element PostgreSQL array to an <code>int[]</code> parameter. In a JSON body, use a JSON array: <code>{"ids": [1, 2, 3]}</code>. Careful: repeating a key for a <em>non-array</em> parameter concatenates the values into one string instead.</p><h3 id="how-do-i-pass-null-in-a-query-string" tabindex="-1">How do I pass NULL in a query string? <a class="header-anchor" href="#how-do-i-pass-null-in-a-query-string" aria-label="Permalink to "How do I pass NULL in a query string?""></a></h3><p>By default an empty value (<code>?p=</code>) is an <strong>empty string</strong>, not NULL (<code>QueryStringNullHandling: "Ignore"</code>). Change it per endpoint with <a href="/annotations/query-string-null-handling.html"><code>@query_string_null_handling</code></a> — <code>empty_string</code> makes <code>?p=</code> mean NULL, <code>null_literal</code> makes <code>?p=null</code> mean NULL — or set the global default. For NULLs in <em>text responses</em>, <a href="/annotations/response-null-handling.html"><code>@response_null</code></a> chooses between empty string (default), the literal <code>null</code>, or <code>204 No Content</code>.</p><h3 id="how-do-i-read-http-request-headers-in-my-sql" tabindex="-1">How do I read HTTP request headers in my SQL? <a class="header-anchor" href="#how-do-i-read-http-request-headers-in-my-sql" aria-label="Permalink to "How do I read HTTP request headers in my SQL?""></a></h3><p>Add a <code>json</code> or <code>text</code> parameter named <code>_headers</code> with a <code>null</code> default — the default <code>RequestHeadersMode: "Parameter"</code> fills it with all request headers as JSON. The <code>Context</code> mode makes headers readable anywhere via <code>current_setting('request.headers', true)</code> instead. Per endpoint: <a href="/annotations/request-headers-mode.html"><code>@request_headers_mode</code></a>.</p><h3 id="how-do-i-receive-a-raw-request-body-webhooks" tabindex="-1">How do I receive a raw request body (webhooks)? <a class="header-anchor" href="#how-do-i-receive-a-raw-request-body-webhooks" aria-label="Permalink to "How do I receive a raw request body (webhooks)?""></a></h3><p>Use <a href="/annotations/body-parameter-name.html"><code>@body_parameter_name</code></a> — the entire raw body (text, JSON, or <code>bytea</code>) is routed into that one parameter, and any other parameters automatically move to the query string.</p><h3 id="can-i-validate-parameters-before-they-reach-the-database" tabindex="-1">Can I validate parameters before they reach the database? <a class="header-anchor" href="#can-i-validate-parameters-before-they-reach-the-database" aria-label="Permalink to "Can I validate parameters before they reach the database?""></a></h3><p>Yes — <code>@validate <param> using <rule1>, <rule2></code> runs immediately after parsing, before any database connection is opened. Built-in rules: <code>not_null</code>, <code>not_empty</code>, <code>required</code>, <code>email</code>; custom <code>Regex</code>/<code>MinLength</code>/<code>MaxLength</code> rules with their own status codes and messages are defined in <code>ValidationOptions</code>. See <a href="/config/validation.html">Validation</a> and <a href="/annotations/validate.html"><code>@validate</code></a>.</p><h3 id="error-could-not-determine-data-type-of-parameter" tabindex="-1">Error: "could not determine data type of parameter" <a class="header-anchor" href="#error-could-not-determine-data-type-of-parameter" aria-label="Permalink to "Error: "could not determine data type of parameter"""></a></h3><p>PostgreSQL couldn't infer the parameter's type from context (classic case: <code>select set_config('key', :value, true)</code>). Give it a type hint: <code>-- @param :value text</code> (or <code>-- @param $1 value text</code> positionally), or add an inline cast in the SQL (<code>:value::text</code>).</p><hr><h2 id="authentication" tabindex="-1">Authentication <a class="header-anchor" href="#authentication" aria-label="Permalink to "Authentication""></a></h2><h3 id="what-authentication-methods-are-supported" tabindex="-1">What authentication methods are supported? <a class="header-anchor" href="#what-authentication-methods-are-supported" aria-label="Permalink to "What authentication methods are supported?""></a></h3><p>Cookie-based auth, JWT Bearer tokens, Microsoft Bearer tokens, HTTP Basic Auth, Passkeys/WebAuthn (FIDO2), and external OAuth providers (Google, GitHub, LinkedIn, Microsoft, Facebook). All can be enabled simultaneously. See <a href="/config/auth.html">Authentication config</a>.</p><h3 id="how-do-i-set-up-jwt-authentication" tabindex="-1">How do I set up JWT authentication? <a class="header-anchor" href="#how-do-i-set-up-jwt-authentication" aria-label="Permalink to "How do I set up JWT authentication?""></a></h3><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;">Auth</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;">JwtAuth</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> true</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;">JwtSecret</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;"> "your-secret-key-at-least-32-characters-long"</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;">JwtExpire</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;"> "60 minutes"</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></div></div></details><p>See the <a href="/blog/multiple-auth-schemes-rbac-external-providers.html">Multiple Auth Schemes blog post</a> for a complete walkthrough including login endpoints and RBAC.</p><h3 id="how-do-i-create-a-login-endpoint" tabindex="-1">How do I create a login endpoint? <a class="header-anchor" href="#how-do-i-create-a-login-endpoint" aria-label="Permalink to "How do I create a login endpoint?""></a></h3><p>Annotate a routine or SQL file with <a href="/annotations/login.html"><code>@login</code></a> (usually together with <code>@allow_anonymous</code>). It returns <strong>one row</strong>: a few special columns (<code>status</code>, <code>scheme</code>, <code>body</code>, <code>hash</code>) control the response, and <strong>every other column becomes a claim</strong> on the signed-in user — no row returned means 401. Verify the password yourself in SQL, or return a <code>hash</code> column and let the built-in PBKDF2 hasher verify it. Full walkthrough in the <a href="/guide/authentication.html">Authentication guide</a>.</p><h3 id="how-do-i-log-users-out" tabindex="-1">How do I log users out? <a class="header-anchor" href="#how-do-i-log-users-out" aria-label="Permalink to "How do I log users out?""></a></h3><p>Annotate an endpoint with <a href="/annotations/logout.html"><code>@logout</code></a>. A <code>void</code> routine signs the caller out of all schemes; returned values are treated as scheme names to sign out of selectively.</p><h3 id="how-do-i-hash-passwords-when-creating-users" tabindex="-1">How do I hash passwords when creating users? <a class="header-anchor" href="#how-do-i-hash-passwords-when-creating-users" aria-label="Permalink to "How do I hash passwords when creating users?""></a></h3><p>Use <code>-- @param hashed_password is hash of password</code> — the target parameter receives a PBKDF2-SHA256 hash of the source parameter before the routine runs, compatible with <code>@login</code>'s built-in verification. The CLI can hash too: <code>npgsqlrest --hash <password></code>. See <a href="/annotations/parameter-hash.html">parameter hashing</a>.</p><h3 id="how-do-i-add-social-login-google-github-microsoft" tabindex="-1">How do I add social login (Google, GitHub, Microsoft…)? <a class="header-anchor" href="#how-do-i-add-social-login-google-github-microsoft" aria-label="Permalink to "How do I add social login (Google, GitHub, Microsoft…)?""></a></h3><p>Enable <code>Auth.External</code> and add a provider block with <code>ClientId</code> and <code>ClientSecret</code> — Google, GitHub, LinkedIn, Microsoft, and Facebook are pre-configured; custom providers just set their URLs. After the OAuth flow, NpgsqlRest calls your configured <code>LoginCommand</code> function with the provider data, and its result follows the same columns-to-claims conventions as <a href="/annotations/login.html"><code>@login</code></a>. See <a href="/config/external-auth.html">External Auth</a>.</p><h3 id="my-spa-on-a-different-domain-loses-the-session-cookie-—-why" tabindex="-1">My SPA on a different domain loses the session cookie — why? <a class="header-anchor" href="#my-spa-on-a-different-domain-loses-the-session-cookie-—-why" aria-label="Permalink to "My SPA on a different domain loses the session cookie — why?""></a></h3><p>Browsers drop cookies on cross-site requests unless the cookie is explicitly marked for it: set <code>Auth.CookieSameSite: "None"</code> together with <code>Auth.CookieSecure: "Always"</code> (and typically <code>CookieDomain</code>), and enable CORS with <code>AllowCredentials: true</code> and explicit origins. See <a href="/config/auth.html">Auth config</a> and <a href="/config/cors.html">CORS</a>.</p><hr><h2 id="real-time-uploads-integrations" tabindex="-1">Real-time, Uploads & Integrations <a class="header-anchor" href="#real-time-uploads-integrations" aria-label="Permalink to "Real-time, Uploads & Integrations""></a></h2><h3 id="how-do-i-push-real-time-events-to-the-browser" tabindex="-1">How do I push real-time events to the browser? <a class="header-anchor" href="#how-do-i-push-real-time-events-to-the-browser" aria-label="Permalink to "How do I push real-time events to the browser?""></a></h3><p>Server-Sent Events: annotate a routine with <a href="/annotations/sse.html"><code>@sse</code></a> and every <code>raise info</code> it makes is broadcast to subscribers connected to the endpoint's stream URL (<code><path>/info</code> by default). Control who receives events with <a href="/annotations/sse-events-scope.html"><code>@sse_scope</code></a> — <code>all</code>, <code>authorize [roles]</code>, or <code>matching</code>. See the <a href="/guide/sse.html">SSE guide</a> and the <a href="/blog/real-time-chat-postgresql-sse-npgsqlrest.html">real-time chat blog post</a>.</p><h3 id="how-do-i-accept-file-uploads" tabindex="-1">How do I accept file uploads? <a class="header-anchor" href="#how-do-i-accept-file-uploads" aria-label="Permalink to "How do I accept file uploads?""></a></h3><p>Enable <code>UploadOptions</code> and annotate the endpoint with <a href="/annotations/upload.html"><code>@upload</code></a>. Four handlers: <code>large_object</code> (default — PostgreSQL Large Objects), <code>file_system</code>, and <code>csv</code>/<code>excel</code>, which parse the file and run a SQL command per row (bulk ingestion without client code). Upload metadata arrives in a <code>json</code> parameter, and everything is transactional — an exception rolls back the rows <em>and</em> discards the file. See <a href="/config/uploads.html">Uploads</a> and the <a href="/blog/secure-image-uploads-postgresql-typescript.html">secure image uploads post</a>.</p><h3 id="can-my-sql-call-an-external-http-api" tabindex="-1">Can my SQL call an external HTTP API? <a class="header-anchor" href="#can-my-sql-call-an-external-http-api" aria-label="Permalink to "Can my SQL call an external HTTP API?""></a></h3><p>Yes — <strong>HTTP Custom Types</strong>: create a composite type whose comment describes a request (<code>GET https://api.example.com/{id}</code>, headers, body), take it as a function parameter, and NpgsqlRest executes the call and fills the type's fields (<code>body</code>, <code>status_code</code>, <code>success</code>, …) before your function runs. Requires <code>HttpClientOptions.Enabled: true</code>; supports timeouts, retries, and GET response caching. See <a href="/guide/http-types.html">HTTP Custom Types</a>.</p><h3 id="can-npgsqlrest-forward-requests-to-another-service-reverse-proxy" tabindex="-1">Can NpgsqlRest forward requests to another service (reverse proxy)? <a class="header-anchor" href="#can-npgsqlrest-forward-requests-to-another-service-reverse-proxy" aria-label="Permalink to "Can NpgsqlRest forward requests to another service (reverse proxy)?""></a></h3><p>Yes — <a href="/annotations/proxy.html"><code>@proxy</code></a> forwards the request to an upstream URL and streams the response back without touching the database; declare <code>_proxy_*</code> parameters to transform the upstream response in SQL instead. <a href="/annotations/proxy-out.html"><code>@proxy_out</code></a> is the reverse: run your routine first, then send its result upstream (PDF rendering, ML inference, email). Requires <code>ProxyOptions.Enabled</code>. See the <a href="/guide/proxy.html">Proxy guide</a>.</p><h3 id="how-do-i-expose-functions-as-ai-tools-mcp" tabindex="-1">How do I expose functions as AI tools (MCP)? <a class="header-anchor" href="#how-do-i-expose-functions-as-ai-tools-mcp" aria-label="Permalink to "How do I expose functions as AI tools (MCP)?""></a></h3><p>Enable <code>McpOptions</code> and annotate routines with <a href="/annotations/mcp.html"><code>@mcp</code></a> — only annotated routines are exposed, on a single <code>/mcp</code> endpoint (streamable HTTP). <code>@mcp</code> without an HTTP annotation makes a tool-only routine with no REST route, and <code>@authorize</code> roles are enforced on tool calls. See <a href="/config/mcp.html">MCP</a> and the <a href="/blog/mcp-server-postgresql-ai-tools-npgsqlrest.html">MCP server blog post</a>.</p><h3 id="can-it-generate-a-client-—-typescript-http-files-openapi" tabindex="-1">Can it generate a client — TypeScript, <code>.http</code> files, OpenAPI? <a class="header-anchor" href="#can-it-generate-a-client-—-typescript-http-files-openapi" aria-label="Permalink to "Can it generate a client — TypeScript, `.http` files, OpenAPI?""></a></h3><p>All three, regenerated on every <a href="/config/watch.html">watch</a> cycle: <code>ClientCodeGen</code> emits typed TypeScript fetch modules with interfaces, <code>HttpFileOptions</code> writes ready-to-run <code>.http</code> files, and <code>OpenApiOptions</code> serves <code>openapi.json</code> (hide individual endpoints with <a href="/annotations/openapi.html"><code>@openapi hide</code></a>). See <a href="/config/codegen.html">Code Generation</a>, <a href="/config/http-files.html">HTTP Files</a>, and <a href="/config/openapi.html">OpenAPI</a>.</p><hr><h2 id="testing" tabindex="-1">Testing <a class="header-anchor" href="#testing" aria-label="Permalink to "Testing""></a></h2><h3 id="how-do-i-test-my-endpoints" tabindex="-1">How do I test my endpoints? <a class="header-anchor" href="#how-do-i-test-my-endpoints" aria-label="Permalink to "How do I test my endpoints?""></a></h3><p>With the built-in <a href="/guide/testing.html">SQL test runner</a> (since 3.19.0): write tests as plain <code>.sql</code> files and run <code>npgsqlrest ./config.json --test</code>. A test inserts fixtures, invokes a real endpoint <strong>in-process</strong> (full pipeline: routing, auth, parameter binding, serialization), asserts on the captured response with ordinary SQL, and rolls back — endpoints see the test's uncommitted data because they run on the test's own connection and transaction.</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;">begin</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">;</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">insert into</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> users (email) </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">values</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> (</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'x@example.com'</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;">/*</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;">GET /api/get-users</span></span>
<span class="line"><span style="--shiki-light:#9CA0B0;--shiki-light-font-style:italic;--shiki-dark:#6C7086;--shiki-dark-font-style:italic;"># @claim user_id=1</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:#8839EF;--shiki-dark:#CBA6F7;"> status</span><span style="--shiki-light:#179299;--shiki-dark:#94E2D5;"> =</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> 200</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, </span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">'authenticated caller gets 200'</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> from</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> _response;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">rollback</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></div></div></details><h3 id="can-tests-run-against-a-temporary-database-instead-of-my-real-one" tabindex="-1">Can tests run against a temporary database instead of my real one? <a class="header-anchor" href="#can-tests-run-against-a-temporary-database-instead-of-my-real-one" aria-label="Permalink to "Can tests run against a temporary database instead of my real one?""></a></h3><p>Yes — that's the recommended CI setup. <code>Setup</code> steps create (and <code>Teardown</code> drops) a uniquely named database (<code>app_test_{rnd5}</code>), migrations run as a step, and <code>TestRunner.ConnectionName</code> points the whole run at it. Template databases give per-test clones for perfect isolation. See the <a href="/guide/testing.html#scenario-dedicated-test-database-per-run">scenario catalog in the Testing Guide</a>.</p><h3 id="my-test-fixtures-need-half-the-database-inserted-first-—-is-there-a-better-way" tabindex="-1">My test fixtures need half the database inserted first — is there a better way? <a class="header-anchor" href="#my-test-fixtures-need-half-the-database-inserted-first-—-is-there-a-better-way" aria-label="Permalink to "My test fixtures need half the database inserted first — is there a better way?""></a></h3><p>Yes, and it's pure PostgreSQL: declare your foreign keys <strong><code>deferrable</code></strong>, then start the test with <code>set constraints all deferred;</code>. Deferred constraints are checked at <code>COMMIT</code> — and a test that ends in <code>rollback</code> never commits, so you can insert <strong>only the rows the test is about</strong>, in any order, referencing rows that don't exist. No fixture factories, no dependency-ordered setup. See <a href="/guide/testing.html#fixtures-without-inserting-the-whole-database-deferrable-constraints">the technique in the Testing Guide</a>.</p><h3 id="is-there-a-watch-mode" tabindex="-1">Is there a watch mode? <a class="header-anchor" href="#is-there-a-watch-mode" aria-label="Permalink to "Is there a watch mode?""></a></h3><p>Two, with one flag. <code>npgsqlrest ... --test --watch</code> re-runs <strong>tests</strong> on changes — a changed test re-runs alone in milliseconds; a changed <em>endpoint</em> file or <em>database routine</em> rebuilds the endpoints in-process and re-runs everything, reporting exactly which endpoints appeared or dropped; Ctrl+C still tears the test database down. <code>npgsqlrest ... --watch</code> (without <code>--test</code>) watches the <strong>running server</strong> — it restarts on SQL file, configuration, and database routine changes, regenerating code (TypeScript client, HTTP files) on every cycle, so <code>create or replace</code> a function in psql and the endpoint is live seconds later. See <a href="/config/watch.html">Watch Mode configuration</a>.</p><hr><h2 id="performance" tabindex="-1">Performance <a class="header-anchor" href="#performance" aria-label="Permalink to "Performance""></a></h2><h3 id="how-fast-is-it" tabindex="-1">How fast is it? <a class="header-anchor" href="#how-fast-is-it" aria-label="Permalink to "How fast is it?""></a></h3><p>Independent-methodology benchmarks measure thousands of requests per second on a single host — see the <a href="/blog/postgresql-rest-api-benchmark-2026.html">2026 benchmark post</a> for detailed comparisons against PostgREST, Go, Rust, Spring Boot, FastAPI, and others, including the methodology and source. The executables are AOT-compiled native binaries; there is no JIT warmup and no reflection at runtime.</p><h3 id="how-do-i-enable-caching" tabindex="-1">How do I enable caching? <a class="header-anchor" href="#how-do-i-enable-caching" aria-label="Permalink to "How do I enable caching?""></a></h3><p>Annotate with <a href="/annotations/cached.html"><code>@cached</code></a> (+ <code>@cache_expires_in 5 minutes</code>). The backend (Memory, Redis, or HybridCache) is configured in <a href="/config/cache-options.html">Cache Options</a>; per-user and per-parameter cache keys are supported. For conditional or tiered rules ("skip caching for admins", "shorter TTL for open-ended queries"), bundle settings into named profiles and select them with <a href="/annotations/cache-profile.html"><code>@cache_profile</code></a>. <strong>Note:</strong> <code>@cached</code> only works for endpoints returning a <strong>single scalar value</strong> — set-returning or multi-column results log a warning and aren't cached.</p><h3 id="how-do-i-enable-response-compression" tabindex="-1">How do I enable response compression? <a class="header-anchor" href="#how-do-i-enable-response-compression" aria-label="Permalink to "How do I enable response compression?""></a></h3><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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">ResponseCompression</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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">Enabled</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> true</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> }</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></div></div></details><p>See <a href="/config/response-compression.html">Response Compression</a>.</p><h3 id="how-do-i-set-up-rate-limiting" tabindex="-1">How do I set up rate limiting? <a class="header-anchor" href="#how-do-i-set-up-rate-limiting" aria-label="Permalink to "How do I set up rate limiting?""></a></h3><p>Define policies in <a href="/config/rate-limiter.html">Rate Limiter config</a> and apply them per endpoint with <a href="/annotations/rate-limiter-policy.html"><code>@rate_limiter_policy</code></a>.</p><h3 id="should-i-use-the-aot-or-the-jit-docker-image" tabindex="-1">Should I use the AOT or the JIT Docker image? <a class="header-anchor" href="#should-i-use-the-aot-or-the-jit-docker-image" aria-label="Permalink to "Should I use the AOT or the JIT Docker image?""></a></h3><p>The default AOT image (~30 MB) starts instantly — best for development, CLI use, and scale-to-zero deployments. The JIT variant (<code>vbilopav/npgsqlrest:latest-jit</code>) is 50–100% faster under sustained high concurrency, at the cost of slower cold start and a ~200–250 MB image — recommended for sustained high-throughput production workloads. See <a href="/guide/installation.html#jit-image">Installation — JIT Image</a>.</p><h3 id="how-do-i-stream-very-large-result-sets" tabindex="-1">How do I stream very large result sets? <a class="header-anchor" href="#how-do-i-stream-very-large-result-sets" aria-label="Permalink to "How do I stream very large result sets?""></a></h3><p>Responses are flushed every 25 rows by default. <a href="/annotations/buffer-rows.html"><code>@buffer_rows 0</code></a> writes each row as it arrives (constant memory, immediate first byte); higher values trade memory for throughput.</p><hr><h2 id="deployment-production" tabindex="-1">Deployment & Production <a class="header-anchor" href="#deployment-production" aria-label="Permalink to "Deployment & Production""></a></h2><h3 id="my-browser-app-gets-cors-errors-—-how-do-i-allow-my-frontend-origin" tabindex="-1">My browser app gets CORS errors — how do I allow my frontend origin? <a class="header-anchor" href="#my-browser-app-gets-cors-errors-—-how-do-i-allow-my-frontend-origin" aria-label="Permalink to "My browser app gets CORS errors — how do I allow my frontend origin?""></a></h3><p>Enable the <code>Cors</code> section and list origins explicitly. <code>AllowCredentials</code> defaults to <code>false</code> — cookie-based auth needs it <code>true</code>, together with explicit <code>AllowedOrigins</code> (browsers reject <code>*</code> combined with credentials):</p><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;">Cors</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;">Enabled</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> true</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;">AllowedOrigins</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 style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;">"https://app.example.com"</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;">AllowCredentials</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> true</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></div></div></details><p>See <a href="/config/cors.html">CORS</a>.</p><h3 id="behind-nginx-cloudflare-the-client-ip-is-wrong" tabindex="-1">Behind nginx / Cloudflare the client IP is wrong <a class="header-anchor" href="#behind-nginx-cloudflare-the-client-ip-is-wrong" aria-label="Permalink to "Behind nginx / Cloudflare the client IP is wrong""></a></h3><p>Enable the <code>ForwardedHeaders</code> section so <code>X-Forwarded-For</code>/<code>-Proto</code> are honored — this affects logs, rate limiting, and the <code>request.ip_address</code> context value. Set <code>ForwardLimit</code> to your proxy-chain depth and restrict trust with <code>KnownProxies</code>/<code>KnownNetworks</code>; with both lists empty, the headers are accepted from any source. See <a href="/config/forwarded-headers.html">Forwarded Headers</a>.</p><h3 id="can-i-run-behind-pgbouncer-rds-proxy-supabase-pooler-in-transaction-mode" tabindex="-1">Can I run behind PgBouncer / RDS Proxy / Supabase Pooler in transaction mode? <a class="header-anchor" href="#can-i-run-behind-pgbouncer-rds-proxy-supabase-pooler-in-transaction-mode" aria-label="Permalink to "Can I run behind PgBouncer / RDS Proxy / Supabase Pooler in transaction mode?""></a></h3><p>Yes — set <code>NpgsqlRest.WrapInTransaction: true</code>. It wraps every request in <code>BEGIN</code>…<code>COMMIT</code>, which keeps <code>set_config</code> state (claims, headers, user context) local to the request instead of leaking across pooled backends. Required for any pooler in transaction mode. See <a href="/config/npgsqlrest.html">NpgsqlRest Options</a>.</p><h3 id="is-there-a-health-endpoint-for-kubernetes-or-load-balancers" tabindex="-1">Is there a health endpoint for Kubernetes or load balancers? <a class="header-anchor" href="#is-there-a-health-endpoint-for-kubernetes-or-load-balancers" aria-label="Permalink to "Is there a health endpoint for Kubernetes or load balancers?""></a></h3><p>Enable <code>HealthChecks</code>: <code>/health</code> (overall), <code>/health/ready</code> (includes a PostgreSQL connectivity check), and <code>/health/live</code> (no database check — so a database outage doesn't restart your pods). See <a href="/config/health-checks.html">Health Checks</a>.</p><h3 id="can-i-route-endpoints-to-a-read-replica-or-a-second-database" tabindex="-1">Can I route endpoints to a read replica or a second database? <a class="header-anchor" href="#can-i-route-endpoints-to-a-read-replica-or-a-second-database" aria-label="Permalink to "Can I route endpoints to a read replica or a second database?""></a></h3><p>Yes — define multiple named entries in <code>ConnectionStrings</code>, set <code>NpgsqlRest.UseMultipleConnections: true</code>, and pick per endpoint with <a href="/annotations/connection.html"><code>@connection <name></code></a>. Without <code>NpgsqlRest.ConnectionName</code>, the first entry is used. Comma-separated hosts in one connection string become a multi-host data source with failover and load balancing. See <a href="/config/connection.html">Connection Settings</a>.</p><h3 id="does-it-retry-transient-errors" tabindex="-1">Does it retry transient errors? <a class="header-anchor" href="#does-it-retry-transient-errors" aria-label="Permalink to "Does it retry transient errors?""></a></h3><p>Two layers, both on by default. Connection failures (startup included) retry on a 1, 3, 6, 12-second sequence, so the server survives the database starting after it does. Command execution retries transient SQLSTATEs — serialization failures (<code>40001</code>), deadlocks (<code>40P01</code>), dropped connections — on a 0, 1, 2, 5, 10-second sequence; define named strategies and assign them per endpoint with <a href="/annotations/retry-strategy.html"><code>@retry_strategy</code></a>. <strong>Important:</strong> mutations (INSERT/UPDATE/DELETE) can be retried and re-executed on a deadlock or serialization failure — they should be idempotent or accept duplicate attempts. See <a href="/config/command-retry.html">Command Retry</a> and <a href="/config/connection.html">Connection Settings</a>.</p><hr><h2 id="debugging-logging" tabindex="-1">Debugging & Logging <a class="header-anchor" href="#debugging-logging" aria-label="Permalink to "Debugging & Logging""></a></h2><h3 id="how-do-i-see-which-endpoints-are-created-and-what-options-they-have" tabindex="-1">How do I see which endpoints are created and what options they have? <a class="header-anchor" href="#how-do-i-see-which-endpoints-are-created-and-what-options-they-have" aria-label="Permalink to "How do I see which endpoints are created and what options they have?""></a></h3><p>Set the <code>NpgsqlRest</code> log level to <code>Debug</code> — every endpoint logs as it is created, including which annotations were applied:</p><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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">Log</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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">MinimalLevels</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 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:#40A02B;--shiki-dark:#A6E3A1;"> "Debug"</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></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div></details><p>Or list them without starting the server: <code>npgsqlrest --endpoints</code>.</p><h3 id="how-do-i-log-the-sql-each-endpoint-executes-at-runtime" tabindex="-1">How do I log the SQL each endpoint executes at runtime? <a class="header-anchor" href="#how-do-i-log-the-sql-each-endpoint-executes-at-runtime" aria-label="Permalink to "How do I log the SQL each endpoint executes at runtime?""></a></h3><p>Two settings: <code>"LogCommands": true</code> in the <code>NpgsqlRest</code> section opts in, and the <code>NpgsqlRest</code> channel must be at <code>Verbose</code> (commands log at trace level):</p><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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">LogCommands</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">:</span><span style="--shiki-light:#FE640B;--shiki-dark:#FAB387;"> true</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;">Log</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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">MinimalLevels</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 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:#40A02B;--shiki-dark:#A6E3A1;"> "Verbose"</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></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>Add <code>"LogCommandParameters": true</code> to include parameter values (mind the sensitive-data implications in production — <a href="/annotations/security-sensitive.html"><code>@security_sensitive</code></a> obfuscates a specific endpoint). See the <a href="/guide/logging.html">Logging Guide</a> for the full picture.</p><h3 id="how-do-i-see-the-metadata-queries-npgsqlrest-runs-at-startup" tabindex="-1">How do I see the metadata queries NpgsqlRest runs at startup? <a class="header-anchor" href="#how-do-i-see-the-metadata-queries-npgsqlrest-runs-at-startup" aria-label="Permalink to "How do I see the metadata queries NpgsqlRest runs at startup?""></a></h3><p>Set the <code>NpgsqlRest</code> log level to <code>Verbose</code> — includes everything from <code>Debug</code> plus the raw <code>pg_catalog</code> discovery queries and the SQL-file describe phase. Useful when a function or file isn't being discovered and you need to see the underlying query and its filters.</p><h3 id="how-do-i-completely-silence-a-logger" tabindex="-1">How do I completely silence a logger? <a class="header-anchor" href="#how-do-i-completely-silence-a-logger" aria-label="Permalink to "How do I completely silence a logger?""></a></h3><p>Since 3.19.0 any <code>Log:MinimalLevels</code> entry accepts <code>"Off"</code> (aliases <code>"None"</code>, <code>"Silent"</code>):</p><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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">Log</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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">MinimalLevels</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 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:#40A02B;--shiki-dark:#A6E3A1;"> "Off"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">,</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">NpgsqlRestClient</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;"> "Off"</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></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div></details><p>Each named logger is independent — handy for muting the application channels while watching the test runner's <code>NpgsqlRestTest</code> channel.</p><h3 id="why-do-my-raise-messages-appear-in-the-server-log" tabindex="-1">Why do my RAISE messages appear in the server log? <a class="header-anchor" href="#why-do-my-raise-messages-appear-in-the-server-log" aria-label="Permalink to "Why do my RAISE messages appear in the server log?""></a></h3><p><code>LogConnectionNoticeEvents</code> is on by default — <code>raise info/notice/warning</code> from executing routines is written to the application log (the same mechanism that powers <a href="/guide/sse.html">SSE</a>). Set it to <code>false</code> in the <code>NpgsqlRest</code> section to silence them, or tune the format with <code>LogConnectionNoticeEventsMode</code>. See the <a href="/guide/logging.html">Logging Guide</a>.</p><h3 id="how-do-i-validate-the-configuration-without-starting-the-server" tabindex="-1">How do I validate the configuration without starting the server? <a class="header-anchor" href="#how-do-i-validate-the-configuration-without-starting-the-server" aria-label="Permalink to "How do I validate the configuration without starting the server?""></a></h3><p><code>npgsqlrest --validate</code> checks configuration keys <em>and</em> database connectivity, exiting 0 on success and 1 on failure — CI-friendly. Related: <code>--config</code> prints the fully resolved annotated configuration, <code>--annotations</code> lists every supported comment annotation as JSON, and <code>--endpoints</code> lists the endpoints that would be created. See <a href="/guide/installation.html">Installation — CLI</a>.</p><h3 id="can-i-use-the-cli-to-generate-password-hashes" tabindex="-1">Can I use the CLI to generate password hashes? <a class="header-anchor" href="#can-i-use-the-cli-to-generate-password-hashes" aria-label="Permalink to "Can I use the CLI to generate password hashes?""></a></h3><p>Yes — <code>npgsqlrest --hash <password></code> generates a PBKDF2-SHA256 hash compatible with <a href="/annotations/login.html"><code>@login</code></a> and password parameters. For HTTP Basic auth, <code>npgsqlrest --basic_auth <user> <password></code> outputs the header value to add to a request.</p><hr><h2 id="troubleshooting" tabindex="-1">Troubleshooting <a class="header-anchor" href="#troubleshooting" aria-label="Permalink to "Troubleshooting""></a></h2><h3 id="every-endpoint-returns-401-unauthorized" tabindex="-1">Every endpoint returns 401 Unauthorized <a class="header-anchor" href="#every-endpoint-returns-401-unauthorized" aria-label="Permalink to "Every endpoint returns 401 Unauthorized""></a></h3><p>That is the default posture, not a bug: the standalone client ships with <code>RequiresAuthorization: true</code>, so endpoints require an authenticated user unless annotated otherwise. Add <a href="/annotations/allow-anonymous.html"><code>@allow_anonymous</code></a> to public endpoints, or set <code>NpgsqlRest.RequiresAuthorization</code> to <code>false</code> and protect endpoints individually with <a href="/annotations/authorize.html"><code>@authorize</code></a>.</p><h3 id="startup-warning-unknown-configuration-key" tabindex="-1">Startup warning: "Unknown configuration key" <a class="header-anchor" href="#startup-warning-unknown-configuration-key" aria-label="Permalink to "Startup warning: "Unknown configuration key"""></a></h3><p>Almost always a typo in <code>appsettings.json</code> — keys are validated at startup. Run <code>npgsqlrest --config</code> to print the complete annotated configuration, or use the published JSON schema for editor autocompletion.</p><h3 id="error-permission-denied-for-schema" tabindex="-1">Error: "permission denied for schema" <a class="header-anchor" href="#error-permission-denied-for-schema" aria-label="Permalink to "Error: "permission denied for schema"""></a></h3><p>The database user lacks <code>USAGE</code> on the schema:</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;">grant</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> usage </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">on</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> schema</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> my_schema </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">to</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> my_user;</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">grant</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> execute</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> on</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> all functions </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">in</span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;"> schema</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> my_schema </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">to</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> my_user;</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></div></div></details><p>This is also a feature: run the server as a least-privilege role and endpoints can only do what that role can do.</p><h3 id="timeout-errors-504-gateway-timeout" tabindex="-1">Timeout errors (504 Gateway Timeout) <a class="header-anchor" href="#timeout-errors-504-gateway-timeout" aria-label="Permalink to "Timeout errors (504 Gateway Timeout)""></a></h3><p>Adjust the command timeout per endpoint with <a href="/annotations/command-timeout.html"><code>@command_timeout 2 minutes</code></a>, or globally in configuration.</p><h3 id="my-post-body-seems-ignored-—-the-endpoint-returns-404" tabindex="-1">My POST body seems ignored — the endpoint returns 404 <a class="header-anchor" href="#my-post-body-seems-ignored-—-the-endpoint-returns-404" aria-label="Permalink to "My POST body seems ignored — the endpoint returns 404""></a></h3><p>Request bodies are read as <strong>JSON regardless of the <code>Content-Type</code> header</strong> — there is no content-type validation, and form-encoded/form-multipart bodies are never parsed (multipart files are only for <a href="/annotations/upload.html"><code>@upload</code></a> endpoints). A malformed JSON body logs a warning (<code>Could not parse JSON body ...</code>) and the request proceeds with <strong>no parameters</strong>, which then fails endpoint matching with a 404. Always send valid JSON, and the <code>Content-Type</code> header can be anything or omitted.</p><h3 id="_413-payload-too-large" tabindex="-1">413 Payload Too Large <a class="header-anchor" href="#_413-payload-too-large" aria-label="Permalink to "413 Payload Too Large""></a></h3><p>Kestrel caps request bodies at 30,000,000 bytes (~28.6 MB) by default — large uploads hit this before any NpgsqlRest setting. Raise <code>Kestrel.Limits.MaxRequestBodySize</code> in <a href="/config/server.html">Server settings</a>.</p><h3 id="timestamps-shifted-after-upgrading-to-3-16" tabindex="-1">Timestamps shifted after upgrading to 3.16+ <a class="header-anchor" href="#timestamps-shifted-after-upgrading-to-3-16" aria-label="Permalink to "Timestamps shifted after upgrading to 3.16+""></a></h3><p>Since 3.16.0, timestamps in JSON are treated as <strong>UTC</strong> by default (naive ISO strings assumed UTC, offset strings converted), so stored values no longer depend on the host's timezone. If you relied on the old host-local parsing, <code>NpgsqlRest.JsonTimestampsAreUtc: false</code> restores it — but treat that as a compatibility escape hatch, not a setting for new projects.</p><h3 id="encrypted-data-is-unreadable-after-restart" tabindex="-1">Encrypted data is unreadable after restart <a class="header-anchor" href="#encrypted-data-is-unreadable-after-restart" aria-label="Permalink to "Encrypted data is unreadable after restart""></a></h3><p>Data Protection keys default to in-memory on Linux — configure persistent storage:</p><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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">DataProtection</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 style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">Storage</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;"> "FileSystem"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;">,</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> "</span><span style="--shiki-light:#1E66F5;--shiki-dark:#89B4FA;">FileSystemPath</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;"> "/var/lib/npgsqlrest/keys"</span><span style="--shiki-light:#7C7F93;--shiki-dark:#9399B2;"> }</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></div></div></details><p>See <a href="/config/data-protection.html">Data Protection config</a>.</p><h3 id="leftover-abcde-test-databases" tabindex="-1">Leftover <code>*_abcde</code> test databases <a class="header-anchor" href="#leftover-abcde-test-databases" aria-label="Permalink to "Leftover `*_abcde` test databases""></a></h3><p>The test runner drops its <code>{rnd}</code>-named databases on every exit path it can intercept — including Ctrl+C, SIGTERM, and hard startup errors. Leftovers mean a run was killed with SIGKILL (nothing can intercept that) or ran with <code>Keep: true</code>. Drop them manually:</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;">select</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;">'drop database %I with (force);'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;">, datname)</span></span>
<span class="line"><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">from</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> pg_database </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">where</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> datname </span><span style="--shiki-light:#8839EF;--shiki-dark:#CBA6F7;">like</span><span style="--shiki-light:#40A02B;--shiki-dark:#A6E3A1;"> 'app_test_%'</span><span style="--shiki-light:#4C4F69;--shiki-dark:#CDD6F4;"> \gexec</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></div></div></details></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/faq.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/logging.html" data-v-e257564d><!--[--><span class="desc" data-v-e257564d>Previous page</span><span class="title" data-v-e257564d>Logging</span><!--]--></a></div><div class="pager" data-v-e257564d><a class="VPLink link pager-link next" href="/guide/changelog/" data-v-e257564d><!--[--><span class="desc" data-v-e257564d>Next page</span><span class="title" data-v-e257564d>Changelog</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>