Skip to content

Config

Remote configuration is the core feature of SkyState. Each project has independent configuration per environment. Every change creates a new immutable version identified by a semantic version string (major.minor.patch).

There are three distinct config endpoint groups:

  • Public (/public/...) — anonymous reads, used by SDKs and client apps
  • Dev (/dev/...) — SDK writes to the development environment, authenticated with a Dev API Key
  • Admin (/admin/...) — full management via JWT Bearer token

Object: ProjectConfig

json
{
  "remoteConfigId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "environment": "production",
  "major": 1,
  "minor": 2,
  "patch": 3,
  "state": "{\"featureEnabled\":true,\"maxUploadMb\":10}",
  "comment": "Enable upload feature",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "stateSizeBytes": 48
}
FieldTypeDescription
remoteConfigIdUUIDUnique version ID
projectIdUUIDOwning project
environmentstringdevelopment, staging, or production
majorintegerSemantic version major component
minorintegerSemantic version minor component
patchintegerSemantic version patch component
statestringJSON-encoded configuration object
commentstring or nullOptional description of the change
createdAtISO 8601 datetimeWhen this version was created
stateSizeBytesintegerByte size of the serialized state

Public Config Endpoints

Read Latest Config (Anonymous)

The primary SDK endpoint. Returns the latest published configuration for a project environment with no authentication required.

GET /api/public/{accountSlug}/{projectSlug}/config/{envSlug}

Auth: None

Path parameters:

ParameterPatternDescription
accountSlug^[a-z0-9][a-z0-9-]*[a-z0-9]$Account slug
projectSlug^[a-z0-9][a-z0-9-]*[a-z0-9]$Project slug
envSlugdevelopment, staging, or productionEnvironment name

Response: 200 OK

json
{
  "version": "1.2.3",
  "lastModified": "2025-01-15T10:30:00.000Z",
  "config": {
    "featureEnabled": true,
    "maxUploadMb": 10
  }
}

The config field is the deserialized JSON object stored in the config version's state field.

Response headers on 200:

HeaderDescription
Cache-Controlpublic, max-age=<N> — varies by tier and environment (see below)
X-RateLimit-LimitMonthly request limit (omitted if unlimited)
X-RateLimit-RemainingRemaining requests this month
X-RateLimit-ResetUnix timestamp of next monthly reset
X-RateLimit-WarningPresent if usage is between 100% and 110% of limit

Cache-Control max-age by tier and environment:

Tierdevelopmentstagingproduction
free10s900s
hobby10s10s300s
pro10s10s60s

Responses:

StatusDescription
200Config found
400Invalid slug format
404Project, account, or environment not found
429Monthly rate limit exceeded — see Rate Limiting

Example:

bash
curl https://app.skystate.io/api/public/acme/my-app/config/production

Admin Config Endpoints

All admin config endpoints require Authorization: Bearer <token>.

Get Config Version by ID

GET /api/admin/config/{remoteConfigId}

Path parameters:

ParameterTypeDescription
remoteConfigIdUUIDConfig version ID

Responses:

StatusDescription
200Returns ProjectConfig object
404Config not found

Example:

bash
curl https://app.skystate.io/api/admin/config/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer <token>"

List Config Versions for an Environment

Returns all versions for the given project and environment, ordered by version descending.

GET /api/admin/{projectId}/config/{envSlug}

Path parameters:

ParameterTypeDescription
projectIdUUIDProject ID
envSlugstringdevelopment, staging, or production

Response: 200 OK — array of ProjectConfig objects.

Example:

bash
curl https://app.skystate.io/api/admin/7c9e6679-7425-40de-944b-e07fc1f90ae7/config/production \
  -H "Authorization: Bearer <token>"

Get Latest Config Version

Returns the most recent version for the given project and environment.

GET /api/admin/{projectId}/config/{envSlug}/latest

Responses:

StatusDescription
200Returns ProjectConfig object
404No config exists yet

Example:

bash
curl https://app.skystate.io/api/admin/7c9e6679-7425-40de-944b-e07fc1f90ae7/config/production/latest \
  -H "Authorization: Bearer <token>"

Create Config Version (Full Replace)

Creates a new config version with explicitly specified version numbers and state.

PUT /api/admin/{projectId}/config/{envSlug}

Request body:

json
{
  "major": 1,
  "minor": 2,
  "patch": 3,
  "state": "{\"featureEnabled\":true}",
  "comment": "Enable feature"
}
FieldTypeRequiredDescription
majorintegerYesSemantic version major
minorintegerYesSemantic version minor
patchintegerYesSemantic version patch
statestringYesJSON-encoded configuration object
commentstringNoDescription of this change

Responses:

StatusBodyDescription
201{ "remoteConfigId": "<uuid>" }Config version created
400ErrorValidation error
402LimitResponseStorage limit exceeded for tier
404ErrorProject or environment not found

Example:

bash
curl -X PUT https://app.skystate.io/api/admin/7c9e6679-7425-40de-944b-e07fc1f90ae7/config/production \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"major":1,"minor":2,"patch":3,"state":"{\"featureEnabled\":true}","comment":"Enable feature"}'

Patch Config (JSON Patch, optimistic concurrency)

Applies RFC 6902 JSON Patch operations to the latest config version. The If-Match header is required and must contain the current version string. If the version has changed since your last read, the server returns 409 Conflict.

PATCH /api/admin/{projectId}/config/{envSlug}

Required header:

If-Match: "1.2.3"

The value must be the exact version string from your last read, including the quotes. Wildcards (If-Match: *) are not accepted.

Request body: Array of JSON Patch operations.

json
[
  { "op": "replace", "path": "/featureEnabled", "value": true },
  { "op": "add", "path": "/newKey", "value": "hello" },
  { "op": "remove", "path": "/oldKey" }
]
FieldTypeAllowed values
opstringadd, remove, replace
pathstringJSON Pointer (RFC 6901), e.g. /featureEnabled
valueanyRequired for add and replace

Responses:

StatusBodyDescription
201{ "remoteConfigId": "<uuid>", "version": "1.2.4" }Patch applied, new version created
400ErrorMissing or invalid If-Match, or invalid patch operations
402LimitResponseStorage limit exceeded
404ErrorProject or environment not found
409ConflictResponseVersion conflict — another write occurred since your read

Response headers on 201:

HeaderDescription
ETagNew version string, e.g. "1.2.4"

ConflictResponse (409):

json
{
  "code": "VERSION_CONFLICT",
  "message": "The config has been modified since your last read.",
  "currentVersion": "1.2.5"
}

Use the currentVersion to fetch the latest state and retry your patch.

Example:

bash
curl -X PATCH https://app.skystate.io/api/admin/7c9e6679-7425-40de-944b-e07fc1f90ae7/config/production \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H 'If-Match: "1.2.3"' \
  -d '[{"op":"replace","path":"/featureEnabled","value":true}]'

Rollback to a Previous Version

Creates a new config version whose state is a copy of the target historical version. The rollback itself is stored as a new version with an incremented version number.

POST /api/admin/{projectId}/config/{envSlug}/rollback/{targetId}

Path parameters:

ParameterTypeDescription
projectIdUUIDProject ID
envSlugstringEnvironment name
targetIdUUIDremoteConfigId of the version to restore

Responses:

StatusBodyDescription
201{ "remoteConfigId": "<uuid>" }Rollback created as new version
402LimitResponseStorage limit exceeded
404ErrorTarget version not found

Example:

bash
curl -X POST https://app.skystate.io/api/admin/7c9e6679-7425-40de-944b-e07fc1f90ae7/config/production/rollback/aabb1234-... \
  -H "Authorization: Bearer <token>"

Dev Config Endpoint

The dev endpoint is used by the SDK during local development. It authenticates with a Dev API Key rather than a Bearer token and is restricted to the development environment.

Patch Config via Dev API Key

PATCH /api/dev/{accountSlug}/{projectSlug}/config/{envSlug}

Auth: Authorization: DevKey <key>

The environment must be development. Any other value returns 403 Forbidden.

Required header:

If-Match: "1.2.3"

Request body: Same array of JSON Patch operations as the admin PATCH endpoint.

Responses:

StatusBodyDescription
201{ "remoteConfigId": "<uuid>", "version": "1.2.4" }Patch applied
400ErrorMissing or invalid If-Match, or invalid patch
402LimitResponseStorage limit exceeded
403ErrorNot the development environment, or no dev key claim
404ErrorProject or environment not found
409ConflictResponseVersion conflict

Example:

bash
curl -X PATCH https://app.skystate.io/api/dev/acme/my-app/config/development \
  -H "Authorization: DevKey sk_dev_abc123..." \
  -H "Content-Type: application/json" \
  -H 'If-Match: "1.0.0"' \
  -d '[{"op":"replace","path":"/debugMode","value":true}]'

Versioning

Config versions use three-component semantic versioning: major.minor.patch.

  • The CLI and dashboard increment the appropriate component when pushing via PUT.
  • PATCH operations auto-increment patch unless a version conflict is detected.
  • Rollbacks create a new version with a new ID — the historical record is never mutated.
  • The version field on the public config response is formatted as "major.minor.patch" (e.g. "1.2.3").

Built with VitePress