Skip to main content



Supabase generates three types of API directly from your database schema.

  • REST - interact with your database through a restful interface.
  • Realtime - listen to database changes.
  • GraphQL - coming soon.

The APIs are:

  • Instant and auto-generated: as you update your database the changes are immediately accessible through your API.
  • Self documenting: Supabase generates documentation in the Dashboard which updates as you make database changes.
  • Secure: the API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled.
  • Fast: our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting.
  • Scalable: the API can serve thousands of simultaneous requests, and works well for Serverless workloads.


Supabase provides a RESTful API using PostgREST. This is a very thin API layer on top of Postgres. It provides everything you need from a CRUD API:

  • Basic CRUD operations
  • Deeply nested joins, allowing you to fetch data from multiple tables in a single fetch
  • Works with Postgres Views
  • Works with Postgres Functions
  • Works with the Postgres security model - including Row Level Security, Roles, and Grants.

Realtime API#

Supabase provides a Realtime API using Realtime. You can use this to listen to database changes over websockets. Realtime leverages PostgreSQL's built-in logical replication. You can manage your Realtime API simply by managing Postgres publications.

GraphQL API#

Coming soon. We are developing pg_graphql, an open source PostgreSQL extension for GraphQL. pg_graphql inspects an existing PostgreSQL schema and reflects a GraphQL schema with resolvers. We will expose pg_graphql via the existing REST interface.

Getting started#

After you have added tables or functions to your database, you can use the API.

Creating API Routes#

API routes are automatically created when you create Postgres Tables, Views, or Functions.

Let's create our first API route by creating a table called todos (which will store some public user information). This will create a corresponding route todos which can accept GET, POST, PATCH, & DELETE requests.

1. Go to the "Table editor" section.
2. Click "New Table".
3. Enter the table name "todos".
4. Click "Save".
5. Click "New Column".
6. Enter the column name "task" and make the type "text".
7. Click "Save".

API URL and Keys#

Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.

You can find the Keys inside the Dashboard.

1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.

Details and links:#

You are provided with two keys initially:

  • an anon key, which is safe to be used in a browser context.
  • a service_role key, which should only be used on a server. This key can bypass Row Level Security.

Accessing the Docs#

Supabase generates documentation in the Dashboard which updates as you make database changes.

Let's view the documentation for the todos table which we created in the first step.

1. Go to the "API" section.
2. Find "todos" in the "Tables and Views" section.
3. Switch between the Javascript and the cURL docs using the tabs.

Using the API#

You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide.

Let's 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_ANON_KEY]) we provided:

// Initialize the JS client
import { createClient } from '@supabase/supabase-js'
const supabase = createClient([SUPABASE_URL], [SUPABASE_ANON_KEY])
// Make a request
let { data: todos, error } = await supabase

Details and links:#

  • When you create a table in Postgres, Row Level Security is disabled by default. Make sure you secure it by enabling RLS.
  • Never expose the service_role key in a browser or anywhere where a user can see it.
  • JS Reference: select(), insert(), update(), upsert(), delete(), rpc() (call Postgres functions).

Safeguards towards accidental deletes and updates#

For new projects, by default, the Postgres extension safeupdate is enabled for all queries coming from the API. This ensures that any delete() or update() would fail if there are no accompanying filters provided. This can be disabled by running the following query on the SQL editor on the dashboard:

alter role "authenticator"
set "session_preload_libraries" to default;

To reenable it :

alter role "authenticator"
set "session_preload_libraries" = 'safeupdate';

The above can also be run to enable it for existing projects. Settings are applied immediately and as such no restarts are needed after running any of the two.

Managing Realtime#

The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a "publication" called supabase_realtime, and by managing this publication you can control which data is broadcast.

By default Realtime is disabled on your database. Let's turn on Realtime for the todos table.

1. Go to the "Database" section.
2. Click on "Replication" in the sidebar.
3. Control which database events are sent by toggling the Insert/Update/Delete toggles.
4. Control which tables broadcast changes by clicking into the "Source" and toggling the tables.

Details and links:#

  • Realtime only works for tables in the public schema.
  • JS Reference: Subscribe to database changes using the realtime client

Securing your Routes#

1. Go to the "Authentication" section.
2. Click on "Policies" in the sidebar.
3. Click on the Padlock to enable Row Level Security.

Details and links:#

  • Your API is designed to work with Postgres Row Level Security. If you use Supabase Auth, you can restrict data based on the logged-in user.
  • To control access to your data, you can use Policies.