Skip to content
Skip to content
PGB Learn

Keys and the REST API

Your project has an address

Every project is reachable at https://<your-project>.pgbhub.app. The SDKs, the Console tools and your own code all use that address. If you can send an HTTPS request, you can use your project.

Two kinds of key

Requests identify your project with a key in the Authorization header:

Authorization: Bearer <key>
  • A publishable key (pgb_pub_...) is meant to ship in apps. It can do only what your row-level security policies allow.
  • A secret key (pgb_sec_...) has full access. It belongs only on servers, in environment variables.

Keys are created and managed in the Console under your project's settings. If a secret key leaks, revoke it and create a new one.

When your app signs a user in, it also sends the user's access token in an X-PGB-User-Token header. That is how policies know who is asking.

Read rows

curl -X POST https://my-project.pgbhub.app/v1/data/find \
  -H "Authorization: Bearer pgb_sec_..." -H "Content-Type: application/json" \
  -d '{"table": "users", "filter": {"role": "admin"}, "limit": 10}'

The body names a table, an optional filter of values that must match exactly, a limit (default 100, at most 1000), an offset, and orderBy with order. The answer is {"rows": [...], "count": n}. There are matching /v1/data/insert, /v1/data/update and /v1/data/delete endpoints.

Run SQL

For anything more complex, use the SQL endpoint with parameters:

curl -X POST https://my-project.pgbhub.app/sql \
  -H "Authorization: Bearer pgb_sec_..." -H "Content-Type: application/json" \
  -d '{"sql": "SELECT id, name FROM users WHERE email = $1", "params": ["[email protected]"]}'

The answer has rows, row_count and columns. Pass values in params and never join them into the SQL text yourself.

Run an action

curl -X POST https://my-project.pgbhub.app/v1/actions/invoke \
  -H "Authorization: Bearer pgb_sec_..." -H "Content-Type: application/json" \
  -d '{"action": "saveUser", "params": {"email": "[email protected]"}, "dry_run": true}'

dry_run: true rolls the transaction back and returns a preview, including any effects that would run.

Other services on the same address

Authentication is at /auth/..., storage at /storage/..., functions at /functions/<name>, mail at /mail/send, and the description of your tables and actions at /schema.json.

Errors and retries

Errors are JSON with a message. 400 means a bad request, 401 a missing or wrong key, 403 a key that is not allowed, 404 not found, 429 too many requests (check Retry-After) and 5xx a problem on the platform's side. Retrying reads after 429, 502, 503 and 504 is safe. Do not retry writes automatically, because repeating one can repeat its effect.

Try it

  1. Copy a secret key into an environment variable.
  2. Run the find request above against a table in your project.
  3. Run the /sql request with SELECT now().
  4. Repeat the find request with a publishable key and see how your policies change the result.

Recap

  • One address per project, one key in the Authorization header.
  • Publishable keys are safe in apps, secret keys only on servers.
  • Use /v1/data/* for simple rows, /sql for queries, and /v1/actions/invoke for named transactions.

Open Access Course

Free

forever
  • 7 structured lessons across 4 modules
  • Interactive knowledge checks with instant feedback
  • Verifiable completion certificate & PDF