Skip to main content

Overview

Supabase REST API supports multiple authentication methods to secure your endpoints. Authentication is handled through API keys and JSON Web Tokens (JWTs).

API Keys

Supabase provides two types of API keys:

Anon Key (Public)

The anon key is safe to use in browser and mobile applications. It respects Row Level Security (RLS) policies.
curl 'https://<PROJECT_REF>.supabase.co/rest/v1/countries' \
  -H "apikey: YOUR_ANON_KEY"
apikey
string
required
Your public anon key from the project settings.
The anon key should only be used with proper RLS policies in place. Never expose the service role key in client applications.

Service Role Key (Private)

The service role key bypasses Row Level Security and should only be used in server environments.
curl 'https://<PROJECT_REF>.supabase.co/rest/v1/countries' \
  -H "apikey: YOUR_SERVICE_ROLE_KEY"
apikey
string
required
Your service role key from the project settings.
Never expose the service role key in client-side code, version control, or public repositories. It has full access to your database.

User Authentication

Sign Up

Create a new user account.
curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/signup' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "example@email.com",
    "password": "example-password"
  }'
email
string
required
User’s email address.
password
string
required
User’s password (minimum 6 characters).
data
object
Optional user metadata.

Response

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "v1.MXpZlZ9lXhyQKJ...",
  "user": {
    "id": "7f87f57e-6f46-4d5f-b3a9-0c9a6e0c5f1a",
    "email": "example@email.com",
    "role": "authenticated",
    "created_at": "2024-03-04T10:00:00.000Z"
  }
}
access_token
string
JWT access token for authenticated requests.
refresh_token
string
Token used to refresh the access token.
expires_in
number
Time in seconds until the access token expires.
user
object
User information object.

Sign In

Sign in an existing user.
curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/token?grant_type=password' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "example@email.com",
    "password": "example-password"
  }'
email
string
required
User’s email address.
password
string
required
User’s password.

Response

Returns the same structure as sign up with access token and user data.

Using the Access Token

Once you have an access token, include it in the Authorization header:
curl 'https://<PROJECT_REF>.supabase.co/rest/v1/countries' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Authorization
string
required
Bearer token format: Bearer <access_token>

Refresh Token

Refresh an expired access token.
curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/token?grant_type=refresh_token' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "v1.MXpZlZ9lXhyQKJ..."
  }'
refresh_token
string
required
The refresh token from the sign in response.

Sign Out

Invalidate the current session.
curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/logout' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

OAuth Providers

Initiate OAuth Flow

Redirect users to an OAuth provider:
GET https://<PROJECT_REF>.supabase.co/auth/v1/authorize?provider=google
provider
string
required
OAuth provider name: google, github, gitlab, azure, facebook, discord, etc.
redirect_to
string
URL to redirect to after authentication.
scopes
string
Space-separated OAuth scopes to request.

Supported Providers

  • Google
  • GitHub
  • GitLab
  • Bitbucket
  • Azure
  • Facebook
  • Twitter
  • Discord
  • Slack
  • Spotify
  • LinkedIn
  • And more…
Send a passwordless sign-in link via email.
curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/magiclink' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "example@email.com"
  }'
email
string
required
User’s email address.
options
object

Phone Authentication

Authenticate users via SMS OTP.

Send OTP

curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/otp' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+1234567890"
  }'
phone
string
required
User’s phone number in E.164 format.

Verify OTP

curl -X POST 'https://<PROJECT_REF>.supabase.co/auth/v1/verify' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+1234567890",
    "token": "123456",
    "type": "sms"
  }'
phone
string
required
User’s phone number.
token
string
required
6-digit OTP code.
type
string
required
Verification type: sms or phone_change.

Row Level Security (RLS)

Row Level Security works seamlessly with JWT authentication. The user’s JWT claims are available in PostgreSQL policies.

Example RLS Policy

-- Users can only read their own data
CREATE POLICY "Users can read own data"
  ON users
  FOR SELECT
  USING (auth.uid() = id);

-- Users can only insert their own data
CREATE POLICY "Users can insert own data"
  ON users
  FOR INSERT
  WITH CHECK (auth.uid() = id);

Accessing JWT Claims

Access user claims in your policies:
-- Get the user's ID
auth.uid()

-- Get the user's email
auth.email()

-- Get the user's role
auth.role()

-- Get custom JWT claims
auth.jwt() ->> 'custom_claim'

Session Management

Get Current User

curl 'https://<PROJECT_REF>.supabase.co/auth/v1/user' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Update User

curl -X PUT 'https://<PROJECT_REF>.supabase.co/auth/v1/user' \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "new@email.com",
    "password": "new-password",
    "data": {
      "display_name": "John Doe"
    }
  }'
email
string
New email address.
password
string
New password.
data
object
User metadata to update.

Security Best Practices

Never send API keys or tokens over unencrypted connections.
Always enable Row Level Security on your tables and create appropriate policies.
Regularly rotate your service role key if it’s been exposed.
Configure appropriate token expiration times in your auth settings.
Never trust client-side validation alone. Always validate on the server with RLS.

Next Steps

Database Operations

Perform CRUD operations with authentication

Row Level Security

Learn about RLS policies