Permission denied to create extension "pg_session_jwt"
Request failed: database CREATE permission is required for neon_superuserWhy this happens
You created your database with a direct SQL query (CREATE DATABASE foo;) instead of using the Console UI or Neon API. The Data API requires specific database permissions that aren't automatically granted when you create databases this way.
Fix
Grant neon_superuser permissions to the database you want to enable the Data API for.
GRANT ALL PRIVILEGES ON DATABASE your_database_name TO neon_superuser;For future databases, create them using the Console UI or Neon API instead of direct SQL. Neon automatically sets up the required permissions when you use these methods.
Example
curl -X POST "https://console.neon.tech/api/v2/projects/${projectId}/branches/${branchId}/databases" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $NEON_API_KEY" \
-d '{
"database": {
"name": "your_database_name"
}
}'JWT Audience validation failed
If you've configured a JWT Audience value in the Data API but your tokens are being rejected, the aud claim in your JWT may not match the configured value.
Fix
- Decode your JWT token at jwt.io to inspect the
audclaim - Ensure the
audvalue in your token exactly matches what you've configured in the Data API - If your provider doesn't include an
audclaim, remove the JWT Audience value from your Data API configuration
For more information, see What is JWT Audience?
JWT token missing sub claim
The JWT token must include the sub claim, which identifies the user, to enable Row-Level Security (RLS) policies. Ensure your authentication system includes this claim when generating JWT tokens for the Neon Data API. An example JWT payload with the sub claim is shown below:
{
"iat": 1764502220,
"createdAt": "2025-11-28T15:01:13.821Z",
"updatedAt": "2025-11-28T15:01:13.821Z",
"role": "authenticated",
"id": "41a5f680-89d2-474d-ae59-e27bfbbbd293",
"sub": "41a5f680-89d2-474d-ae59-e27bfbbbd293",
"exp": 1764503120,
"iss": "https://ep-spring-silence-ad3hu80n.neonauth.c-2.us-east-1.aws.neon.tech",
"aud": "https://ep-spring-silence-ad3hu80n.neonauth.c-2.us-east-1.aws.neon.tech"
}The sub claim in this example: 41a5f680-89d2-474d-ae59-e27bfbbbd293 represents the unique identifier for the authenticated user. This claim is used by your RLS policies to determine which data the user is allowed to access.
How do I test the Data API without building an app?
If you're using Neon Auth, you can use the Auth API reference UI to create test users and obtain JWT tokens for testing with tools like Postman or cURL.
Navigate to your Auth URL with /reference appended (e.g., https://ep-example.neonauth.us-east-1.aws.neon.tech/neondb/auth/reference). You can find your Auth URL on the Auth page on the Configuration tab in the Neon Console. From there, you can:
- Create a test user with
POST /api/auth/sign-up/email. - Sign in with
POST /api/auth/sign-in/email. - Call
GET /api/auth/get-sessionand copy the JWT from theSet-Auth-Jwtresponse header. - Use that JWT in your Data API requests.
For step-by-step instructions, see Testing with Postman or cURL.
Permission denied for table
{"code":"42501","detail":null,"hint":null,"message":"permission denied for table your_table_name"}Why this happens
The authenticated role doesn't have GRANT permissions on the table. This commonly occurs when:
- The table was created before the Data API was enabled
- The table was created after enabling the Data API, but default privileges weren't applied
- You disabled the "Grant public schema access" option when enabling the Data API
Fix
Grant the authenticated role access to the table:
GRANT SELECT, UPDATE, INSERT, DELETE ON your_table_name TO authenticated;Or grant access to all tables in the schema:
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA public TO authenticated;
-- Also set default privileges for future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLES TO authenticated;I can see all rows in my table
If authenticated users can see all rows in a table regardless of ownership, Row-Level Security (RLS) is likely disabled on that table.
Check RLS status
In the Neon Console, go to the Data API page. If a table has RLS disabled, you'll see a warning:
"table_name has RLS disabled. All authenticated users can view all rows in this table(s)."
Fix
-
Click the Enable RLS button in the Console, or run:
ALTER TABLE your_table_name ENABLE ROW LEVEL SECURITY; -
Create a policy to control access. For example, to let users see only their own rows:
CREATE POLICY "Users see own data" ON your_table_name FOR ALL TO authenticated USING (auth.user_id() = user_id);
For more details, see Row-Level Security.
RLS is enabled but I can't see any rows
If you've enabled RLS but queries return no data, you likely haven't created any policies yet.
Why this happens
When RLS is enabled on a table, all access is blocked by default until you create policies that grant access. This is a security feature — it ensures data is protected even if you forget to add policies.
Fix
Create policies that define who can access what data. For example:
-- Allow users to see their own rows
CREATE POLICY "Users see own data" ON your_table_name
FOR SELECT TO authenticated
USING (auth.user_id() = user_id);
-- Allow users to insert their own rows
CREATE POLICY "Users insert own data" ON your_table_name
FOR INSERT TO authenticated
WITH CHECK (auth.user_id() = user_id);See Access control & security for more examples.
OpenAPI spec returns "Entry not found"
{"message":"Entry 'openapi.json' not found"}Why this happens
The OpenAPI schema feature is disabled in your Data API configuration.
Fix
- Go to the Data API page in the Neon Console
- Open the Configuration panel
- Enable the OpenAPI schema toggle
- Try your request again
Can't access OpenAPI spec
If you're getting authentication errors when trying to access the OpenAPI spec, remember that it requires a valid JWT token like any other Data API request.
Fix
Include the Authorization header with a valid JWT:
curl -X GET 'https://your-data-api-endpoint/rest/v1/openapi.json' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'To get a JWT token for testing, see Testing with Postman or cURL.
New table not found or returns empty schema
If you've created a new table but the Data API doesn't recognize it, or the OpenAPI spec doesn't include it, the schema cache may be stale.
Why this happens
The Data API caches your database schema for performance. When you create or modify tables, the cache doesn't automatically update.
Fix
- Go to the Data API page in the Neon Console
- Click the Refresh schema cache button
- Retry your request
You'll need to refresh the schema cache whenever you:
- Create new tables
- Add or remove columns
- Change column types
- Modify table structure
JWT token has expired
{"message":"JWT token has expired (exp=...)"}Why this happens
JWT tokens have a limited lifespan (typically around 15 minutes). Once expired, they can no longer be used to authenticate requests.
Fix
Sign in again to get a fresh token. If you're using Neon Auth, call POST /api/auth/sign-in/email in the Auth API reference UI, then call GET /api/auth/get-session and copy the new JWT from the Set-Auth-Jwt response header.
For programmatic token refresh, see your authentication provider's documentation on token renewal.








