Skip to content

REST API Reference

The REST API is Envy’s authoritative control surface. It operates over HTTP with JSON payloads and conforms to the formal OpenAPI 3.1 specification (api/openapi.yaml). This page summarizes common composition endpoints; the OpenAPI file includes the complete catalog, source, frontend, installation, and recipe contracts. Response examples below show selected fields.

The draft, plan, and diagnosis routes were merged after v0.8.0 and require a newer source build until a release includes them.


All /v1 endpoints use the installation’s configured authentication. CLI and machine clients send an Envy bearer token; browsers use a session cookie in password/Google mode. Explicit dev mode supplies the Admin identity automatically. For bearer requests:

Authorization: Bearer <token>
  • Authorization: Bearer <token>: Used for CLI, agent, and machine authentication. Cookie-authenticated mutations also require same-origin Origin and X-CSRF-Token from /auth/config.
  • Content-Type: application/json: Required for POST and PATCH requests.
  • Idempotency-Key: <string>: Optional unique identifier (up to 128 printable ASCII characters) to ensure safe retries.

MethodPathDescriptionStatus
POST/v1/compositionsCreate a new ephemeral composition202 Accepted
GET/v1/compositionsList active compositions (paginated)200 OK
GET/v1/compositions/{id}Get full desired and observed state200 OK
GET/v1/compositions/{id}/statusGet lightweight phase and latest operation200 OK
GET/v1/compositions/{id}/endpointsGet preview URLs and routing readiness200 OK
POST/v1/compositions/planReview a read-only preview plan200 OK
PATCH/v1/compositions/{id}Rolling image update with expected generation202 Accepted
DELETE/v1/compositions/{id}Destroy composition asynchronously202 Accepted
GET/v1/compositions/{id}/components/{component}/logsFetch bounded container log snapshots200 OK
GET/v1/compositions/{id}/eventsDurable audit events log200 OK
GET/v1/compositions/{id}/diagnosisExplain recorded blockers and unknowns200 OK
GET/v1/compositions/{id}/verificationList retained checks with freshness200 OK
GET/v1/compositions/{id}/observabilityResolve configured external links200 OK
POST/v1/catalog/validateDry-run catalog validation200 OK
POST/v1/catalog/applyAtomic catalog registration200 OK
GET, PUT, DELETE/v1/projects/{project}/onboarding-draftResume, save, or discard non-secret preparation200 / 204
GET/v1/projectsList registered projects200 OK
GET/v1/projects/{project}/componentsList approved component profiles200 OK
GET/v1/projects/{project}/baselinesList registered baselines200 OK

POST /v1/compositions
Authorization: Bearer <token>
Content-Type: application/json
Idempotency-Key: ci-pr-42-attempt-1
{
"project": "demo",
"baseline": "staging",
"name": "pr-auth-fix",
"overrides": {
"service-b": { "image": "envy/service-b:v2" }
},
"ttl": "8h"
}
Location: /v1/compositions/cmp-84f1a09
{
"id": "cmp-84f1a09",
"project": "demo",
"baseline": "staging",
"name": "pr-auth-fix",
"generation": 1,
"observed_generation": 0,
"phase": "created",
"expires_at": "2026-09-12T04:20:00Z",
"created_at": "2026-09-11T20:20:00Z",
"endpoints": {
"public": {
"url": "http://cmp-84f1a09.envy.localhost:8080",
"ready": false
}
},
"latest_operation": {
"id": "op-01J98X7",
"kind": "create",
"status": "pending"
}
}

Creation accepts zero to three overrides. Use "overrides": {} for a baseline-only preview. Each selected component supplies either {"image":"registry/image:tag"} or {"build_id":"BUILD_ID"}; Envy resolves build provenance and does not accept caller-provided source.

Send the same request body to POST /v1/compositions/plan to inspect the selected images, inherited components, approved revisions, declared dependencies, destination, lifetime, resource estimate, blockers, and cautions before creation. Planning is read-only and does not reserve capacity. The create request rechecks the current contract, so a ready plan does not guarantee that a later create will succeed.

Optional "message_isolation": true enables Google Pub/Sub isolation at creation after operator/application setup. It defaults to false and is immutable. The composition response includes message_subscriptions for inspection and readiness.

2. Update Composition (Complete Override Selection)

Section titled “2. Update Composition (Complete Override Selection)”
PATCH /v1/compositions/cmp-84f1a09
Authorization: Bearer <token>
Content-Type: application/json
{
"expected_generation": 1,
"overrides": {
"service-b": { "image": "envy/service-b:v3" }
}
}
  • If the current generation does not match expected_generation, the API responds with 409 Conflict.
  • overrides is the complete desired selection, not a partial patch. Add or remove components within the zero-to-three limit; omitted keys return to inheritance and {} removes all overrides.
  • The preview URL and original expiry stay the same. TTL and message isolation cannot be changed here.
  • Only ready or failed, unexpired compositions can be updated. Concurrent rollout/deletion conflicts and generic updates to GitHub App-owned previews return 409.
  • Wait for the new generation to become ready before testing. Rolling updates are not atomic across components; a failed rollout can leave the previous override serving without switching it to the baseline.

GET /v1/compositions/cmp-84f1a09/components/service-b/logs?tail_lines=50&since_seconds=600
Authorization: Bearer <token>
{
"message": "returned log snapshots",
"component": "service-b",
"source": "override",
"composition_filtered": false,
"streams": [
{
"pod": "cmp-84f1a09-service-b-7f4d",
"container": "service-b",
"text": "2026-09-11T20:22:01Z [info] server listening on :8080\n",
"truncated": false
}
],
"partial": false,
"truncated": false
}

If querying an unmodified baseline service (for example gateway), the response identifies source as "shared-baseline" and the returned logs are not filtered by composition baggage.


DELETE /v1/compositions/cmp-84f1a09
Authorization: Bearer <token>

The composition phase transitions to destroying. Cleanup is asynchronous, repeatable, and idempotent.

GET, PUT, and DELETE /v1/projects/{project}/onboarding-draft manage one draft per installation, project, and authenticated author. PUT requires the current revision (0 creates a draft); DELETE requires ?revision=N. Stale revisions return 409. Drafts exclude environment and selected ConfigMap values, credentials, and messaging configuration. They do not register catalog entries or create previews. Shared-token and anonymous modes use a common draft author; person-level separation requires identity-bearing access.

GET /v1/compositions/{id}/diagnosis explains recorded conditions with state, blockers, notes, verification, and optional evidence_id. GET /v1/compositions/{id}/verification?limit=20&after=<next_cursor> retains individual checks and derives freshness when read. A changed inherited image, Service route, selected workload, or verification contract can invalidate old proof without incrementing the composition generation. The API reports unknown or unavailable coverage rather than inferring a successful result. See Diagnostics & Error Codes for interpretation and api/openapi.yaml for complete response schemas.

See the setup and permissions guide before enabling a repository policy. These routes use the normal authenticated Envy API:

MethodPathPurpose
GET/v1/github/statusApp configuration, webhook and reconciliation health.
GET/v1/github/installations?page=1Discover App installations.
GET/v1/github/installations/{id}/repositories?page=1Discover accessible repositories.
GET/v1/github/preview-policiesList repository policies.
GET, PUT/v1/projects/{project}/repositories/{repository}/preview-policyRead or configure a policy.
GET/v1/github/previews?project=shop&limit=20List previews; use after for pagination.
GET/v1/github/previews/{id}Preview detail and lifecycle status.
POST/v1/github/previews/{id}/stopSuppress automation and request cleanup.
POST/v1/github/previews/{id}/restartRequest a fresh lifecycle for an open labelled PR.

Stop/restart return 200 when accepted; resource transitions are asynchronous. Full request/response schemas are in the OpenAPI specification.

POST /webhooks/github is a separate public ingestion route authenticated with the GitHub raw-body HMAC signature, not an Envy bearer token. Valid deliveries are persisted and deduplicated before 202 Accepted, then processed asynchronously.