🔧 Management API

All management endpoints require Authorization: Bearer <AdminApiKey>.

Table of contents

Applications

List applications

1
GET /api/management/applications

Returns all non-deleted applications.

Response 200:

1
2
3
4
5
6
7
8
9
10
[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "payments-api",
    "slug": "payments-api",
    "description": "Payment processing service",
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-01-01T00:00:00Z"
  }
]

Create application

1
POST /api/management/applications

Creates an application and automatically seeds a local environment.

Request body:

1
2
3
4
{
  "name": "payments-api",
  "description": "Payment processing service"
}
Field Required Constraints
name ✅ 1–200 characters
description âž– Optional

Response 201:

1
2
3
4
5
6
7
8
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "payments-api",
  "slug": "payments-api",
  "description": "Payment processing service",
  "plainApiKey": "grm_4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a",
  "createdAt": "2025-01-01T00:00:00Z"
}

Save plainApiKey. It is shown once and cannot be retrieved. Call rotate-key to get a new one if lost.

Response 409: An application with the same slug already exists.


Get application

1
GET /api/management/applications/{slug}

Response 200: Application object (same shape as list item, without plainApiKey).
Response 404: Application not found.


Update application

1
PUT /api/management/applications/{slug}

Request body:

1
2
3
4
{
  "name": "Payments API v2",
  "description": "Updated description"
}

Response 200: Updated application object.


Delete application

1
DELETE /api/management/applications/{slug}

Soft-deletes the application. The slug becomes available for reuse.
All child environments, secrets, and configurations are hidden (but not purged from the database).

Response 204: No content.


Rotate API key

1
POST /api/management/applications/{slug}/rotate-key

Generates a new API key and invalidates the old one immediately.

Response 200:

1
2
3
{
  "plainApiKey": "grm_9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c"
}

Environments

List environments

1
GET /api/management/applications/{slug}/environments

Response 200:

1
2
3
4
5
[
  { "id": "...", "slug": "local",   "name": "Local",      "createdAt": "..." },
  { "id": "...", "slug": "staging", "name": "Staging",    "createdAt": "..." },
  { "id": "...", "slug": "prod",    "name": "Production", "createdAt": "..." }
]

Create environment

1
POST /api/management/applications/{slug}/environments

Request body:

1
{ "name": "Production" }

The slug is auto-generated from the name (e.g. "Production" → "production").

Response 201: Created environment.
Response 409: Duplicate slug.


Delete environment

1
DELETE /api/management/applications/{slug}/environments/{envSlug}

Response 204: No content.


Secrets

List secrets

1
GET /api/management/applications/{slug}/secrets

Returns secret metadata — never the decrypted values.

Response 200:

1
2
3
4
5
6
7
8
9
[
  {
    "id": "...",
    "name": "database-password",
    "description": null,
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-01-01T00:00:00Z"
  }
]

Create secret

1
POST /api/management/applications/{slug}/secrets

Creates a named secret slot. Values are set separately via Set values.

Request body:

1
{ "name": "database-password", "description": "Main DB password" }

Response 201:

1
2
3
4
5
6
7
8
9
10
{
  "id": "...",
  "name": "database-password",
  "description": "Main DB password",
  "createdAt": "...",
  "requiredEnvironments": [
    { "slug": "local",   "name": "Local",   "valueProvided": false },
    { "slug": "staging", "name": "Staging", "valueProvided": false }
  ]
}

requiredEnvironments lists all existing environments and whether a value has been set for each.


Set secret values

1
POST /api/management/applications/{slug}/secrets/{name}/values

Creates new versions of the secret for one or more environments. Each call appends a new version — it does not overwrite existing versions.

Request body (array):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[
  {
    "environmentSlug": "local",
    "value": "dev-password-123",
    "isEnabled": true,
    "expiresAt": null,
    "notBefore": null
  },
  {
    "environmentSlug": "staging",
    "value": "stg-password-456",
    "isEnabled": true,
    "expiresAt": "2025-12-31T23:59:59Z"
  }
]
Field Required Description
environmentSlug ✅ Target environment
value ✅ Plain-text secret value (encrypted before storage)
isEnabled âž– Default true
expiresAt âž– ISO 8601 timestamp; version expires after this
notBefore âž– ISO 8601 timestamp; version inactive before this

expiresAt must be after notBefore if both are set (validated server-side).

Response 200: Empty body.
Response 404: Environment or secret not found.


Get secret metadata

1
GET /api/management/applications/{slug}/secrets/{name}

Returns the secret definition — not the values.


List secret versions

1
GET /api/management/applications/{slug}/secrets/{name}/versions/{environmentSlug}

Returns all versions for the named secret in the given environment, ordered newest-first.

Response 200:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
  {
    "id": "...",
    "version": 2,
    "isEnabled": true,
    "expiresAt": null,
    "notBefore": null,
    "createdAt": "2025-06-01T00:00:00Z"
  },
  {
    "id": "...",
    "version": 1,
    "isEnabled": false,
    "expiresAt": "2025-05-31T23:59:59Z",
    "notBefore": null,
    "createdAt": "2025-01-01T00:00:00Z"
  }
]

Delete secret

1
DELETE /api/management/applications/{slug}/secrets/{name}

Permanently deletes the secret and all its versions.

Response 204: No content.


Configurations

List configurations

1
GET /api/management/applications/{slug}/configurations

Returns all configuration entries for the application, across all environments.

Response 200:

1
2
3
4
5
6
7
8
9
10
11
[
  {
    "id": "...",
    "environmentSlug": "local",
    "key": "Feature:DarkMode",
    "value": "true",
    "description": null,
    "createdAt": "...",
    "updatedAt": "..."
  }
]

Create configuration

1
POST /api/management/applications/{slug}/configurations

Request body:

1
2
3
4
5
6
{
  "environmentSlug": "local",
  "key": "Feature:DarkMode",
  "value": "true",
  "description": "Toggle dark mode"
}
Field Required Constraints
environmentSlug ✅ Must exist
key ✅ Non-empty string
value ✅ Non-empty string
description âž– Optional

Response 201: Created entry.
Response 409: Key already exists for that environment.


Update configuration

1
PUT /api/management/applications/{slug}/configurations/{environmentSlug}/{key}

Request body:

1
{ "value": "false", "description": "Updated description" }

Response 200: Updated entry.
Response 404: Entry not found.


Delete configuration

1
DELETE /api/management/applications/{slug}/configurations/{environmentSlug}/{key}

Response 204: No content.