apps/docs/content/guides/api/creating-routes.mdx
API routes are automatically created when you create Postgres Tables, Views, or Functions.
Create your first API route by creating a table called todos to store tasks.
This creates a corresponding route todos which can accept GET, POST, PATCH, & DELETE requests.
<Tabs scrollable size="small" type="underlined" defaultActiveId="dashboard" queryGroup="database-method"
<TabPanel id="dashboard" label="Dashboard">
todos.task and type text.todos or the functions you want to access. To automatically grant access for new tables and functions in public, enable Default privileges for new entities.-- Create a table called "todos" with a column to store tasks.
create table
todos (
id bigint generated by default as identity primary key,
task text check (char_length(task) > 3)
);
-- Enable Data API access with least-privilege grants
-- Allow read-only access for anonymous clients
grant select on public.todos to anon;
-- Allow full CRUD for authenticated clients
grant select, insert, update, delete on public.todos to authenticated;
-- Allow full CRUD for the server-side service role
grant select, insert, update, delete on public.todos to service_role;
-- Important: enable Row Level Security and create appropriate policies
-- before granting write access to client roles (see RLS guide)
Granting privileges (like select or execute) to roles such as anon or authenticated makes those tables or functions accessible through the Data API. Behind the scenes, the API checks your Postgres permissions—only objects with explicit grants are exposed, and all other access is denied by default.
Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.
To do this, you need to get the Project URL and key from the project's Connect dialog.
<$Partial path="api_keys_deprecation.mdx" variables={{ "framework": "{{ .framework }}", "tab": "{{ .tab }}" }} />
Read the API keys docs for a full explanation of all key types and their uses.
The REST API is accessible through the URL https://<project_ref>.supabase.co/rest/v1
Both of these routes require the key to be passed through an apikey header.
You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide.
See how to make a request to the todos table which we created in the first step,
using the API URL (SUPABASE_URL) and Key (SUPABASE_PUBLISHABLE_KEY) we provided:
<Tabs scrollable size="small" type="underlined" defaultActiveId="javascript" queryGroup="language"
<TabPanel id="javascript" label="JavaScript">
// Initialize the JS client
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY)
// Make a request
const { data: todos, error } = await supabase.from('todos').select('*')
// Initialize the client
var supabase = new Supabase.Client(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY);
await supabase.InitializeAsync();
// Make a request
var todos = await supabase.From<Todo>().Get();
# Append /rest/v1/ to your URL, and then use the table name as the route
curl '<SUPABASE_URL>/rest/v1/todos' \
-H "apikey: <SUPABASE_PUBLISHABLE_KEY>" \
-H "Authorization: Bearer <SUPABASE_PUBLISHABLE_KEY>"
JS Reference: select(),
insert(),
update(),
upsert(),
delete(),
rpc() (call Postgres functions).