## Description
Replaces legacy `anon` / `service_role` key references with the new
`publishable` / `secret` naming across SDK spec files under
`apps/docs/spec/`. Mirrors the rename table established by
[supabase-js#2280](https://github.com/supabase/supabase-js/pull/2280),
so the auto-generated reference docs at
supabase.com/docs/reference/{js,dart,kotlin,python,swift} stay
consistent with the SDK source.
## Files changed
| File | Highlights |
| --- | --- |
| `supabase_js_v2.yml` | Rename example vars `anon_key` →
`publishable_key`, `service_role_key` → `secret_key`; admin notes use
`secret`. |
| `supabase_dart_v2.yml` | Rename `anonKey` param → `publishableKey`
(matches the live Flutter SDK — see
[supabase-flutter/supabase.dart#L81](https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/lib/src/supabase.dart#L81));
update call-site; example var `serviceRoleKey` → `secretKey`; admin
notes use `secret`. |
| `supabase_kt_v2.yml`, `supabase_kt_v3.yml` | Replace
`'publishable-or-anon-key'` placeholders with `'your-publishable-key'`;
admin notes use `secret`; fix `importAuthToken(\"service_role\")` →
`importAuthToken(\"your-secret-key\")` (the Kotlin SDK's
`importAuthToken(accessToken: String, …)` takes a JWT, not a role name).
|
| `supabase_py_v2.yml` | All `service_role` references → `secret`;
example var `service_role_key` → `secret_key`. |
| `supabase_swift_v2.yml` | Replace placeholders with
`'your-publishable-key'`; admin notes use `secret`; example var
`serviceRoleKey` → `secretKey`. |
| `storage_v0_config.yaml` | Rewrite `ANON_KEY` / `SERVICE_KEY` env var
**descriptions** in publishable/secret terms. **Env var names kept** —
see below. |
## Why the storage env var names are unchanged
`storage_v0_config.yaml` documents the env vars used to configure the
storage server (multi-tenant deployments). The `id` and `title` fields
must match the actual env var names the binary reads. The storage server
still reads its config from env vars literally named `ANON_KEY` and
`SERVICE_KEY`:
-
[`storage/src/config.ts#L614`](https://github.com/supabase/storage/blob/master/src/config.ts#L614)
— `getOptionalConfigFromEnv('SERVICE_KEY')`
-
[`storage/src/config.ts#L625`](https://github.com/supabase/storage/blob/master/src/config.ts#L625)
— `getOptionalConfigFromEnv('ANON_KEY')`
There is no `PUBLISHABLE_KEY` / `SECRET_KEY` reader on master. Renaming
the doc IDs would break self-hosted deployments — users following the
docs would set the wrong env var and the storage server would silently
fall back to generating its own JWT. Until the storage server itself
adds publishable/secret env support, only descriptions can be updated.
(Same reasoning for not bumping `storage_v0_config.yaml` →
`storage_v1_config.yaml`: the `_v0_` tracks the storage server's own API
version, paired with `storage_v0_openapi.json` downloaded from
`supabase.github.io/storage/api.json`. The server hasn't shipped a v1
API.)
## What we deliberately did NOT rename
Per the same rules established in supabase-js#2280:
- **JWT role claims** like `role: 'anon'` / `role: 'service_role'` —
these are functional Postgres role names in JWT payloads, not key
labels.
- **Real SDK identifiers** that haven't been renamed in the source (we
only rename in the doc when the underlying SDK rename has shipped). The
Dart `anonKey` rename was safe to apply because the Flutter SDK already
ships `publishableKey` as the preferred named parameter (with `anonKey`
`@Deprecated`).
## Out of scope
- **All `*_v1.yml` SDK spec files** (`supabase_js_v1`,
`supabase_dart_v1`, `supabase_kt_v1`, `supabase_swift_v1`). Older SDK
versions, not worth churning.
- **`cli_v1_commands.yaml`**. This file is auto-generated by the CLI
repo's release workflow
([`cli/tools/bumpdoc/main.go`](https://github.com/supabase/cli/blob/develop/tools/bumpdoc/main.go))
and the example outputs come from
[`cli/docs/templates/examples.yaml`](https://github.com/supabase/cli/blob/develop/docs/templates/examples.yaml)
— embedded in the CLI binary at build time. Any edits we make here would
be clobbered by the next CLI release. The fix needs to land upstream in
the CLI repo (note: the CLI itself already ships publishable/secret
naming in \`supabase status\` output — see
[`cli/internal/status/status.go#L40-L44`](https://github.com/supabase/cli/blob/develop/internal/status/status.go#L40-L44)
— but the doc-generation template is stale).
- **`supabase_csharp_v0.yml` / `supabase_csharp_v1.yml`** — checked,
already neutral. Both files use a generic `SUPABASE_KEY` env var with no
`anon` / `service_role` references.
- **Renaming the legacy Dart `anonKey` parameter itself** — that's an
SDK-side change. The Flutter SDK already exposes `publishableKey` as the
preferred parameter; full removal of `anonKey` will happen in a future
major version per the SDK's own deprecation comment.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Standardized API key naming across SDK docs: use publishable (client)
and secret (server/admin) key terminology
* Updated server-side admin examples and warnings to require secret keys
and emphasize never exposing them in client code
* Unified initialization examples across JavaScript, Dart, Kotlin,
Python, and Swift
* Corrected Storage spec metadata to point to the proper configuration
file
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Summary
This PR updates documentation based on recent changes across multiple
SDK repositories since the last run on 2026-01-22.
## Changes Analyzed
| SDK | Repository | Commits | Latest Tag |
|-----|-----------|---------|------------|
| **js** | supabase/supabase-js | 40 | v2.95.4-canary.2 |
| **dart** | supabase/supabase-flutter | 4 | - |
| **py** | supabase/supabase-py | 12 | v2.28.0 |
| **swift** | supabase/supabase-swift | 14 | v2.41.1 |
| **kt** | supabase-community/supabase-kt | 36 | 3.3.0 |
| **csharp** | supabase-community/supabase-csharp | 1 | v1.1.2 |
## Documentation Updates
### JavaScript SDK (`supabase_js_v2.yml`)
- Added optional `jwt` parameter documentation to
`mfa.getAuthenticatorAssuranceLevel()`
- Added `timeout` and `urlLengthLimit` options to `PostgrestClient`
constructor with example
### Kotlin SDK (`supabase_kt_v3.yml`)
- Added new `getClaims()` API section with description, parameters, and
3 examples
- Added `channel` parameter to OTP `signInWith` config for WhatsApp
support
- Added WhatsApp OTP sign-in example
### Python SDK (`supabase_py_v2.yml`)
- Added `from_.list_v2()` method documentation with cursor-based
pagination support
- Includes `SearchV2Options` parameter documentation and pagination
example
- Added note about new User model fields (`is_sso_user`, `deleted_at`,
`banned_until`) on `get_user`
### Swift SDK (`supabase_swift_v2.yml`)
- Added breaking change note for `mfa.unenroll()`: response now uses
`id` instead of `factorId` (since v2.41.1)
### Phone Login Guide (`phone-login.mdx`)
- Added Kotlin WhatsApp OTP example to the sign-in section
### SDKs with no documentation updates needed
- **Dart**: Only CI and realtime type-cast fix (no user-facing API
changes)
- **C#**: Only README badge fix
## Test plan
- [ ] Verify YAML spec files parse correctly
- [ ] Review rendered documentation for new sections
- [ ] Confirm code examples match actual SDK APIs
---
Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Updated the email update note in the docs to explain that confirmation emails are still sent due to the Secure Email Change setting. Added a direct link to the relevant dashboard setting to help users better understand and manage the behavior.
Adds a note explaining that the `data` field maps to `raw_user_meta_data` in the database,
and is returned as `user_metadata` when calling `getUser()`.
* Move the spec/parser package into packages folder.
* Fix the spec generation with the new paths.
* Remove the spec folder from prettierignore.
* Run prettier on the spec folder (without regenerating, that's should be done by the product teams).
Migrates client SDK References to App Router. (Management and CLI API references aren't migrated yet, nor are self-hosting config references.)
Some notes:
Big changes to the way crawler pages are built and individual section URLs (e.g., javascript/select) are served. All of these used to be SSG-generated pages, but the number of heavy pages was just too much to handle -- slow as molasses and my laptop sounded like it was taking off, and CI sometimes refuses to build it all at all.
Tried various tricks with caching and pre-generating data but no dice.
So I changed to only building one copy of each SDK+version page, then serving the sub-URLs through a response rewrite. That's for the actual user-visible pages.
For the bot pages, each sub-URL needs to be its own page, but prebuilding it doesn't work, and rendering on demand from React components is too slow (looking for super-fast response here for SEO). Instead I changed to using an API route that serves very minimal, hand-crafted HTML. It looks ugly, but it's purely for the search bots.
You can test what bots see by running curl --user-agent "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" <URL_OF_PAGE>
Also added some smoke tests to run against prod for the crawler routes, since we don't keep an eye on those regularly, and Vercel config changes could surprise-break them. Tested the meta images on Open Graph and all seems to work fine.
With this approach, full production builds are really fast: ~5 minutes
Starts using the new type spec handling, which is better at finding params automatically, so I could remove some of the manually written ones from the spec files.
Our syntax highlighter doesn't recognize HTML (tried to install it but it's not
on the lsit of supported languages) and this somehow causes the server and
client to make different highlighting decisions, with the server attempting to
highlight the code block and the client not.
Removing the html language specifier removes the hydration error (and since the
client never properly highlighted it anyway, we don't lose much in terms of
syntax highlighting.)