Authentication
The three kinds of token the Groundfloor API accepts, and how to get each.
Send a bearer token with every request:
Authorization: Bearer <token>
Content-Type: application/jsonWhich token you use depends on who is calling.
Choose a token
| Caller | Token | Get it from | Can do |
|---|---|---|---|
| You or a teammate | A team token | gf token, or the Developers page in the Client Portal | What your role allows |
| Your code, with nobody signed in — Coderunners, CI, servers | An M2M token | POST …/m2m/token with a client's credentials, or gf m2m token | What a Writer can do, plus reading secrets if allowed. See M2M |
| Your app's users | Their sign-in token | window.__GF_GET_ACCESS_TOKEN__() in a Shell app | What their role is granted on Site access |
Tokens are short-lived: M2M tokens last 5 minutes by default (expires_in in the response says exactly). Team and app-user tokens are issued by the sign-in service and expire on its schedule. Get a fresh one rather than storing it.
Team tokens
gf login # once
TOKEN=$(gf token) # a fresh token each time
curl -H "Authorization: Bearer $TOKEN" "https://platform.groundfloor.cloud/v1/workspaces"Or run eval "$(gf env)" to set GROUNDFLOOR_TOKEN, CONTROLPLANE_URL and GROUNDFLOOR_WORKSPACE_ID for a script.
Use team tokens for yourself only. Code that runs unattended should use an M2M token.
M2M tokens
POST https://platform.groundfloor.cloud/v1/workspaces/{workspace_id}/m2m/token
Content-Type: application/json
{ "client_id": "…", "client_secret": "…" }This is the only request that needs no Authorization header. The response has access_token and expires_in. Reuse the token until shortly before it expires; getting tokens is rate-limited. See M2M.
App user tokens
A Shell app sends the signed-in user's token to the data, files and flags APIs, and to its own backend. Groundfloor accepts tokens from your workspace's sign-in mode, whether Groundfloor sign-in or your own provider.
App users aren't part of your team, so their tokens work only on the routes an app needs:
- listing apps and loading one by slug;
- Data Vault: listing collections, reading a collection's schema, and querying, counting, creating, updating and deleting records, as their role's grants allow;
- Files: listing, uploading, downloading and deleting, as their role's grants allow;
- reading feature flag values (
…/flags/runtime).
Every other route returns 403 "This API is not available to app end users", whatever the user's role, admin included. The user also needs at least one role from your app's sign-in; a signed-in user with no role gets 403.
Permissions
Each endpoint needs a permission on the workspace or organization. These docs list it on each endpoint:
| Permission | Roles that have it |
|---|---|
read | Every role |
write, delete | Writer, Admin, Owner |
ddl (create or delete collections), administer, manage_members | Admin, Owner |
Roles on the organization carry down to every workspace in it:
| Organization role | Gets on every workspace in the organization |
|---|---|
| Owner, Admin | administer, so also ddl, manage_members, and everything the workspace Admin role can do (secrets, M2M clients, members) |
| Writer, Member, Partner | read |
| Billing admin | Nothing |
On the organization itself, Owner and Admin have administer and manage_members; Owner, Admin and Billing admin have view_billing; every role has read. Deleting the organization needs the Owner role. A Partner has the same permissions as a Member. See Roles by scope.
Deploying and running a Coderunner through the API needs write, so a Writer can deploy.
A 401 means the token is missing or expired. A 403 means the token is valid but its role isn't allowed to do this.
Next steps
- M2M — clients, scopes and rotation.
- Team and roles — what each role allows.