API versions: run v1 and v2 side by side
Ship a new version of your API next to the current one: v2 gets its own URL, tables, functions and policies, v1 keeps working, and you move apps over when you are ready.
Your project's URL is v1: production. An API version is an environment marked as a version with a label such as v2. It has its own URL, its own database (starting as production's tables, or another version's), its own functions and its own access policies. Apps on the project URL keep getting v1; apps you point at the v2 URL get v2. Both stay live until you delete the version.
How a request finds its version
| A call through the v2 URL uses | From |
|---|---|
| Tables | The v2 database |
| A function | Its v2 version — else the production one |
| Policies | The v2 policies; a production policy with the same name is replaced in v2, the other production policies still apply |
| Secrets | Those set in v2 — never copied from production |
Billing, rate limits and logs stay with the project: one bill, and every log line is tagged with the version it came through. In the console each version shows its own logs.
Create a version
Open the environment switcher
In the console top bar, open the database menu, choose + New environment or API version and pick API version.
Label it
For example
v2(v1is production). Labels are unique in a project.Choose where it starts
Start from production, or — on plans that include it — from another version, which copies that version's tables (no rows), functions and policies. Secrets are not copied.
Use its URL
Switch to it in the same menu. Its URL is in Connect and in Deploy to production; point your new app build at it.
An existing staging environment can be marked as a version later (and back) — its URL, data, functions and policies stay as they are.
Change things in v2 only
While v2 is selected in the console, tables, migrations, functions and policies you change are v2's. Production's function or policy edited in v2 becomes v2's own copy; production keeps its version. From the CLI and SDK, send the version's id:
# deploy a function to v2 only
sov fn deploy ./functions/hello --env <v2-environment-id>
# call it through each URL
curl -X POST https://<project-ref>.sovaria.in/functions/v1/hello -H "apikey: <anon-key>" # v1
curl -X POST https://<v2-ref>.sovarias.in/functions/v1/hello -H "apikey: <anon-key>" # v2Make v2 the new production
With v2 selected, Deploy to production lists v2's migrations, new and changed functions and new and changed policies, and shows who would gain or lose access in production with those policies. Everything is checked first with nothing written; then it is applied as one commit you can undo from Version history: see, undo and restore changes. If the check finds that visitors who aren't signed in would be able to change data, the deploy stops unless you confirm.
After the deploy the v2 URL keeps working — apps still on it are not affected, and v1 now behaves like v2. Delete the version once nothing uses its URL; deleting it stops that URL for everyone.
POST /api/v1/data/rel/migrations/promote
X-Sovaria-Env-ID: <v2-environment-id>
{ "from_env_id": "<v2-environment-id>", "dry_run": true }
# then, after reading migrations, functions, policies and simulation:
{ "from_env_id": "<v2-environment-id>", "dry_run": false }Plans
| Free | Pro | Ultra | Team | Enterprise | |
|---|---|---|---|---|---|
| Environments per project, versions and staging together (besides production) | — | 2 | 5 | 10 | 50 |
| Start a version from another version | — | — | Yes | Yes | Yes |
| Extra environment add-on ($5/month each, up to 10) | — | Yes | Yes | Yes | — |
A version's disk counts towards database storage and its function calls towards the project's usage, like production's. See Plan limits.
Common mistakes
- Expecting v2 to have production's rows. It starts with the tables only; copy or seed the data it needs.
- Forgetting secrets. Set the function secrets v2 needs in v2 — production's are not copied, so a staging key never becomes production's by accident.
- Deleting a version that apps still call. Check its logs first; its URL stops working when it is deleted.