API
Everything the dashboard and the CLI do goes through one GraphQL API at https://lucity.cloud/graphql, which you can call yourself. The playground documents every query, mutation and type.
Authentication
Every request carries an access token as a bearer token. The CLI prints one for your session and the active workspace:
curl https://lucity.cloud/graphql \
-H "Authorization: Bearer $(lucity token)" \
-H "Content-Type: application/json" \
-d '{"query": "{ project(id: \"zeitlos-software/vouch\") { name environments { name } } }"}'
{
"data": {
"project": {
"name": "vouch",
"environments": [
{
"name": "development"
},
{
"name": "production"
}
]
}
}
}
For automation, use a workspace API token. The API doesn't accept the lucity_… value itself, so let the CLI exchange it. With the token in LUCITY_API_TOKEN, lucity token prints an access token that carries the API token's role:
export LUCITY_API_TOKEN=lucity_…
curl https://lucity.cloud/graphql \
-H "Authorization: Bearer $(lucity token)" \
-H "Content-Type: application/json" \
-d '{"query": "{ projects { id } }"}'
Access tokens are short-lived, so fetch a new one for every run instead of storing it. A token also decides the workspace, and every request runs against the workspace its token belongs to.
Playground
lucity.cloud/playground(opens in a new tab) is an interactive editor for the API, with autocomplete as you type. The book icon in its sidebar opens the documentation, which describes every query, mutation and type, so it doubles as the API reference.
To run queries against your workspace, add your token in the Headers tab as {"Authorization": "Bearer …"}.
Ids
Resources are addressed by ids that start with the workspace, and each kind of id has its own scalar type:
| Scalar | Format | Example |
|---|---|---|
ProjectID | workspace/project | zeitlos-software/vouch |
EnvironmentID | workspace/project/environment | zeitlos-software/vouch/production |
ServiceID | workspace/project/environment/service | zeitlos-software/vouch/production/vouch |
DatabaseID | workspace/project/environment/database | zeitlos-software/vouch/production/feedback |
Key-value stores, buckets and volumes follow the same pattern as databases. Unlike the CLI, the API always takes the full id.
Roles
Every token carries a role, and it can only call the operations that role allows:
| Role | Who has it |
|---|---|
| Admin | Workspace admins, and API tokens created with the admin role |
| Member | Workspace members, and API tokens created with the member role |
| Deployer | Keyless GitHub Actions sessions |
Members and roles describes what each role can do.
Errors
A failed operation still answers with HTTP 200. The reason is in the errors list, next to whatever data could be returned:
{
"errors": [
{
"message": "project with id \"zeitlos-software/nope\" not found",
"path": [
"project"
],
"locations": [
{
"line": 1,
"column": 3
}
]
}
],
"data": null
}
Live logs
Logs stream as GraphQL subscriptions over a WebSocket at wss://lucity.cloud/graphql, using the graphql-transport-ws protocol. Put the token in the connection_init payload:
{ "type": "connection_init", "payload": { "Authorization": "Bearer <token>" } }
Any client that speaks the protocol works, such as graphql-ws(opens in a new tab) for JavaScript.