Files
supabase/apps/docs/content/guides/api/using-custom-schemas.mdx
Chris Chinchilla 1644030dcd docs: RLS and wrapper Key changes (#45166)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Updated SDK initialization examples to reflect current authentication
patterns across multiple Supabase integration guides
* Enhanced security documentation with expanded guidance on protecting
sensitive credentials like secrets and service role keys in frontend and
Edge Function environments
* Clarified Row-Level Security access patterns and data availability
considerations when using publishable keys

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: fadymak <dev@fadymak.com>
2026-04-24 14:01:44 +00:00

102 lines
3.2 KiB
Plaintext

---
id: 'using-custom-schemas'
title: 'Using Custom Schemas'
description: 'You need additional steps to use custom database schemas with data APIs.'
---
By default, your database has a `public` schema which is automatically exposed on data APIs.
## Creating custom schemas
You can create your own custom schema/s by running the following SQL, substituting `myschema` with the name you want to use for your schema:
```sql
CREATE SCHEMA myschema;
```
## Exposing custom schemas
You can expose custom database schemas - to do so you need to follow these steps:
1. Go to [API settings](/dashboard/project/_/settings/api) and add your custom schema to "Exposed schemas".
2. Run the following SQL, substituting `myschema` with your schema name:
```sql
GRANT USAGE ON SCHEMA myschema TO anon, authenticated, service_role;
GRANT ALL ON ALL TABLES IN SCHEMA myschema TO anon, authenticated, service_role;
GRANT ALL ON ALL ROUTINES IN SCHEMA myschema TO anon, authenticated, service_role;
GRANT ALL ON ALL SEQUENCES IN SCHEMA myschema TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA myschema GRANT ALL ON TABLES TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA myschema GRANT ALL ON ROUTINES TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA myschema GRANT ALL ON SEQUENCES TO anon, authenticated, service_role;
```
Now you can access these schemas from data APIs:
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="javascript"
queryGroup="language"
>
<TabPanel id="javascript" label="JavaScript">
```js
// Initialize the JS client
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
db: { schema: 'myschema' },
})
// Make a request
const { data: todos, error } = await supabase.from('todos').select('*')
// You can also change the target schema on a per-query basis
const { data: todos, error } = await supabase.schema('myschema').from('todos').select('*')
```
</TabPanel>
<$Show if="sdk:dart">
<TabPanel id="dart" label="Dart">
```dart
// Initialize the Flutter client
await Supabase.initialize(
url: supabaseUrl,
publishableKey: publishableKey,
postgrestOptions: const PostgrestClientOptions(schema: 'myschema'),
);
final supabase = Supabase.instance.client;
// Make a request
final data = await supabase.from('todos').select();
// You can also change the target schema on a per-query basis
final data = await supabase.schema('myschema').from('todos').select();
````
</TabPanel>
</$Show>
<TabPanel id="curl" label="cURL">
```bash
# Append /rest/v1/ to your URL, and then use the table name as the route.
# for GET or HEAD request use Accept-Profile
curl '<SUPABASE_URL>/rest/v1/todos' \
-H "apikey: <SUPABASE_PUBLISHABLE_KEY>" \
-H "Authorization: Bearer <SUPABASE_PUBLISHABLE_KEY>" \
-H "Accept-Profile: myschema"
# for POST, PATCH, PUT and DELETE Request use Content-Profile
curl -X POST '<SUPABASE_URL>/rest/v1/todos' \
-H "apikey: <SUPABASE_PUBLISHABLE_KEY>" \
-H "Authorization: Bearer <SUPABASE_PUBLISHABLE_KEY>" \
-H "Content-Type: application/json" \
-H "Content-Profile: myschema" \
-d '{"column_name": "value"}'
````
</TabPanel>
</Tabs>