diff --git a/src/routes/changelog/(entries)/2026-04-10.markdoc b/src/routes/changelog/(entries)/2026-04-10.markdoc new file mode 100644 index 0000000000..aa0f9076ba --- /dev/null +++ b/src/routes/changelog/(entries)/2026-04-10.markdoc @@ -0,0 +1,34 @@ +--- +layout: changelog +title: "Public project APIs for platforms and API keys" +date: 2026-04-10 +--- + +Appwrite now exposes **public project APIs** for managing platforms and API keys programmatically. Previously these resources could only be configured through the Console; now you can automate project setup entirely through the API or Server SDKs. + +# Platforms API + +Create, list, update, and delete platforms through dedicated endpoints per platform type: **web**, **apple**, **android**, **windows**, and **linux**. Each type uses its own identifier (hostname, bundle identifier, application ID, package identifier name, or package name). + +The previous ~15 framework-specific platform types (`flutter-ios`, `flutter-android`, `apple-macos`, `react-native-ios`, etc.) have been consolidated into these 5 types. Existing platforms with deprecated types are mapped automatically when read. + +# API keys API + +Create, list, get, update, and delete API keys through the API. You can assign scopes and set expiration dates programmatically, enabling automated key rotation and infrastructure-as-code workflows. + +# New scopes + +Six new scope pairs are now available for API keys: + +- `platforms.read` / `platforms.write` -- manage project platforms +- `keys.read` / `keys.write` -- manage project API keys +- `webhooks.read` / `webhooks.write` -- manage project webhooks +- `project.read` / `project.write` -- read and update project information + +{% arrow_link href="/docs/advanced/platform/platforms" %} +Read the platforms docs +{% /arrow_link %} + +{% arrow_link href="/docs/advanced/platform/api-keys" %} +Read the API keys docs +{% /arrow_link %} diff --git a/src/routes/docs/advanced/platform/+layout.svelte b/src/routes/docs/advanced/platform/+layout.svelte index 5e1739b622..d1cf3cdcb8 100644 --- a/src/routes/docs/advanced/platform/+layout.svelte +++ b/src/routes/docs/advanced/platform/+layout.svelte @@ -66,6 +66,11 @@ { label: 'Dev keys', href: '/docs/advanced/platform/dev-keys' + }, + { + label: 'Platforms', + new: isNewUntil('10 Jul 2026'), + href: '/docs/advanced/platform/platforms' } ] }, diff --git a/src/routes/docs/advanced/platform/+page.markdoc b/src/routes/docs/advanced/platform/+page.markdoc index d85400548e..5054e9f65c 100644 --- a/src/routes/docs/advanced/platform/+page.markdoc +++ b/src/routes/docs/advanced/platform/+page.markdoc @@ -53,6 +53,10 @@ Create and manage API keys used by Server SDKs. {% cards_item href="/docs/advanced/platform/dev-keys" title="Dev keys" %} Create and manage dev keys used by Client SDKs in dev environments. {% /cards_item %} + +{% cards_item href="/docs/advanced/platform/platforms" title="Platforms" %} +Register and manage client platforms that can access your project. +{% /cards_item %} {% /cards %} # Plans {% #plans %} diff --git a/src/routes/docs/advanced/platform/api-keys/+page.markdoc b/src/routes/docs/advanced/platform/api-keys/+page.markdoc index 5faf72dbd4..cdee342d10 100644 --- a/src/routes/docs/advanced/platform/api-keys/+page.markdoc +++ b/src/routes/docs/advanced/platform/api-keys/+page.markdoc @@ -148,9 +148,63 @@ let client = Client::new() ``` {% /multicode %} -When adding a new API Key, you can choose which [scopes](#scopes) to grant your application. +When adding a new API Key, you can choose which [scopes](#scopes) to grant your application. If you need to replace your API Key, create a new key, update your app credentials and, once ready, delete your old key. +# Manage keys with the API {% #manage-keys-api %} + +You can also create, list, update, and delete API keys programmatically using the project API. This is useful for automated key rotation, infrastructure-as-code workflows, or building custom admin tooling. + +All key management endpoints require an API key with the `keys.read` or `keys.write` scope. + +| Method | Endpoint | Scope | +|--------|---------------------------------|----------------| +| GET | `/v1/project/keys` | `keys.read` | +| POST | `/v1/project/keys` | `keys.write` | +| GET | `/v1/project/keys/:keyId` | `keys.read` | +| PUT | `/v1/project/keys/:keyId` | `keys.write` | +| DELETE | `/v1/project/keys/:keyId` | `keys.write` | + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); // Must have keys.write scope + +const project = new sdk.Project(client); + +const key = await project.createKey( + sdk.ID.unique(), // keyId + 'My Server Key', // name + ['databases.read', 'databases.write'], // scopes + '2026-12-31T23:59:59.000+00:00' // expire (optional) +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') # Must have keys.write scope + +project = Project(client) + +key = project.create_key( + key_id=ID.unique(), + name='My Server Key', + scopes=['databases.read', 'databases.write'], + expire='2026-12-31T23:59:59.000+00:00' # optional +) +``` +{% /multicode %} + # Scopes {% #scopes %} | Name | Description | @@ -204,3 +258,11 @@ If you need to replace your API Key, create a new key, update your app credentia | `assistant.read` | Access to read the Assistant service | | `tokens.read` | Access to read your project's tokens | | `tokens.write` | Access to create, update, and delete your project's tokens | +| `webhooks.read` | Access to read your project's webhooks | +| `webhooks.write` | Access to create, update, and delete your project's webhooks | +| `project.read` | Access to read your project's information | +| `project.write` | Access to update your project's information | +| `keys.read` | Access to read your project's API keys | +| `keys.write` | Access to create, update, and delete your project's API keys | +| `platforms.read` | Access to read your project's platforms | +| `platforms.write` | Access to create, update, and delete your project's platforms | diff --git a/src/routes/docs/advanced/platform/platforms/+page.markdoc b/src/routes/docs/advanced/platform/platforms/+page.markdoc new file mode 100644 index 0000000000..0ddb1cd04e --- /dev/null +++ b/src/routes/docs/advanced/platform/platforms/+page.markdoc @@ -0,0 +1,165 @@ +--- +layout: article +title: Platforms +description: Manage your project's client platforms programmatically using the Appwrite Platforms API. Register web, Apple, Android, Windows, and Linux platforms to control which client applications can access your project. +--- + +Platforms define which client applications are allowed to access your Appwrite project. Each platform registers an identifier (such as a hostname or bundle ID) that Appwrite uses to validate requests from client SDKs. You can manage platforms through the Console or programmatically through the API. + +# Platform types {% #platform-types %} + +Appwrite supports five platform types. Each type uses a different identifier to validate client requests. + +| Type | Identifier | Example | +|-------------|--------------------------|------------------------------| +| `web` | Hostname | `example.com` | +| `apple` | Bundle identifier | `com.example.myapp` | +| `android` | Application ID | `com.example.myapp` | +| `windows` | Package identifier name | `com.example.myapp` | +| `linux` | Package name | `com.example.myapp` | + +{% info title="Consolidated types" %} +Earlier versions of Appwrite used framework-specific platform types such as `flutter-ios`, `flutter-android`, `apple-macos`, and `react-native-ios`. These have been consolidated into the five types above. Existing platforms with deprecated types are mapped automatically. See [migration notes](#migration-notes) for details. +{% /info %} + +# Endpoints {% #endpoints %} + +The platforms API is available under `/v1/project/platforms`. All endpoints require an API key with the appropriate scope. + +## Create a platform {% #create-platform %} + +Create a platform by calling the endpoint for its type. Each type requires a unique identifier. + +| Method | Endpoint | Scope | +|--------|----------------------------------------|---------------------| +| POST | `/v1/project/platforms/web` | `platforms.write` | +| POST | `/v1/project/platforms/apple` | `platforms.write` | +| POST | `/v1/project/platforms/android` | `platforms.write` | +| POST | `/v1/project/platforms/windows` | `platforms.write` | +| POST | `/v1/project/platforms/linux` | `platforms.write` | + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new sdk.Project(client); + +// Create a web platform +const platform = await project.createWebPlatform( + sdk.ID.unique(), // platformId + 'My Website', // name + 'example.com' // hostname +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +# Create a web platform +platform = project.create_web_platform( + platform_id=ID.unique(), + name='My Website', + hostname='example.com' +) +``` +{% /multicode %} + +## List platforms {% #list-platforms %} + +Retrieve all platforms registered in your project. + +| Method | Endpoint | Scope | +|--------|-----------------------------|--------------------| +| GET | `/v1/project/platforms` | `platforms.read` | + +{% multicode %} +```server-nodejs +const platforms = await project.listPlatforms(); +``` + +```server-python +platforms = project.list_platforms() +``` +{% /multicode %} + +## Get a platform {% #get-platform %} + +Retrieve a single platform by its ID. + +| Method | Endpoint | Scope | +|--------|-----------------------------------------|--------------------| +| GET | `/v1/project/platforms/:platformId` | `platforms.read` | + +## Update a platform {% #update-platform %} + +Update a platform by calling the endpoint for its type. + +| Method | Endpoint | Scope | +|--------|-------------------------------------------------|---------------------| +| PUT | `/v1/project/platforms/web/:platformId` | `platforms.write` | +| PUT | `/v1/project/platforms/apple/:platformId` | `platforms.write` | +| PUT | `/v1/project/platforms/android/:platformId` | `platforms.write` | +| PUT | `/v1/project/platforms/windows/:platformId` | `platforms.write` | +| PUT | `/v1/project/platforms/linux/:platformId` | `platforms.write` | + +## Delete a platform {% #delete-platform %} + +Delete a platform by its ID. + +| Method | Endpoint | Scope | +|--------|-----------------------------------------|---------------------| +| DELETE | `/v1/project/platforms/:platformId` | `platforms.write` | + +# Scopes {% #scopes %} + +Two scopes control access to the platforms API. + +| Scope | Description | +|--------------------|--------------------------------------------------------------------| +| `platforms.read` | Access to read your project's platforms | +| `platforms.write` | Access to create, update, and delete your project's platforms | + +Assign these scopes when [creating an API key](/docs/advanced/platform/api-keys). + +# Migration notes {% #migration-notes %} + +In Appwrite 1.9.x, platform types were consolidated from ~15 framework-specific types into 5 general types. If your project has platforms created with older types, be aware of the following. + +## Deprecated type mapping {% #deprecated-type-mapping %} + +| Deprecated type | Maps to | +|-------------------------|-------------| +| `flutter-web` | `web` | +| `unity` | `web` | +| `flutter-ios` | `apple` | +| `flutter-macos` | `apple` | +| `apple-ios` | `apple` | +| `apple-macos` | `apple` | +| `apple-watchos` | `apple` | +| `apple-tvos` | `apple` | +| `react-native-ios` | `apple` | +| `flutter-android` | `android` | +| `react-native-android` | `android` | +| `flutter-windows` | `windows` | +| `flutter-linux` | `linux` | + +## What you need to know {% #what-you-need-to-know %} + +- **Reading**: When you list or get platforms, deprecated types are automatically returned as their new consolidated type. No action is needed on your part. +- **Creating**: New platforms must use one of the five current types (`web`, `apple`, `android`, `windows`, `linux`). The deprecated type names are not accepted for new platforms. +- **Existing platforms**: Platforms already registered with deprecated types continue to work. The mapping is applied transparently on read. +- **Client SDK validation**: Origin validation for client requests works the same regardless of whether the platform was created with a deprecated or current type.