Skip to main content

REST API Reference

All API endpoints are prefixed with /api/v1. Requests must include Authorization: Bearer <token> unless noted as public. The browser UI can also authenticate same-origin requests with the gantry_session cookie set by POST /api/v1/auth/login.

Entities

List All Entities

GET /api/v1/entities

Query parameters:

ParamDescription
namespaceFilter by namespace (default: all)
ownerFilter by owner name
tagFilter by tag
curl "http://localhost:8080/api/v1/entities?tag=critical" \
-H "Authorization: Bearer <token>"

List Entities by Kind

GET /api/v1/entities/{kind}

{kind} is case-insensitive: service, Service, SERVICE all work.

curl http://localhost:8080/api/v1/entities/service \
-H "Authorization: Bearer <token>"

Get Entity

GET /api/v1/entities/{kind}/{name}?namespace=default
curl "http://localhost:8080/api/v1/entities/service/payment-api?namespace=default" \
-H "Authorization: Bearer <token>"

Response:

{
"kind": "Service",
"apiVersion": "gantry.io/v1",
"metadata": {
"name": "payment-api",
"namespace": "default",
"title": "Payment API",
"description": "Handles all payment processing",
"owner": "platform-team",
"tags": ["payments", "critical"],
"labels": {"tier": "backend"},
"annotations": {},
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-01T00:00:00Z",
"createdBy": "alice"
},
"spec": {
"type": "backend",
"lifecycle": "production",
"repoUrl": "https://github.com/acme/payment-api"
}
}

Create Entity

POST /api/v1/entities

Requires developer role. Body is the full entity JSON:

curl -X POST http://localhost:8080/api/v1/entities \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"kind": "Service",
"apiVersion": "gantry.io/v1",
"metadata": {
"name": "my-new-service",
"description": "A new service"
},
"spec": {
"type": "backend",
"lifecycle": "development"
}
}'

Returns 201 Created with the created entity.

Update Entity

PUT /api/v1/entities/{kind}/{name}

Requires developer role. Replaces the full entity spec.

curl -X PUT http://localhost:8080/api/v1/entities/service/payment-api \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{...full entity JSON...}'

Delete Entity

DELETE /api/v1/entities/{kind}/{name}?namespace=default

Requires developer role.

curl -X DELETE "http://localhost:8080/api/v1/entities/service/payment-api" \
-H "Authorization: Bearer <token>"
GET /api/v1/search?q={query}

Full-text search across all entities. Searches name, title, description, tags, and owner fields.

curl "http://localhost:8080/api/v1/search?q=payment" \
-H "Authorization: Bearer <token>"

Response:

[
{
"kind": "Service",
"name": "payment-api",
"title": "Payment API",
"description": "Handles all payment processing",
"owner": "platform-team",
"tags": ["payments"]
}
]

Relationship Graph

GET /api/v1/graph/{kind}/{name}?namespace=default

Returns a graph of entities related to the given entity (dependencies, APIs, environments).

curl "http://localhost:8080/api/v1/graph/service/payment-api" \
-H "Authorization: Bearer <token>"

Response:

{
"nodes": [
{"id": "service/payment-api", "kind": "Service", "name": "payment-api"},
{"id": "infrastructure/postgres-payments", "kind": "Infrastructure", "name": "postgres-payments"}
],
"edges": [
{"from": "service/payment-api", "to": "infrastructure/postgres-payments", "type": "dependsOn"}
]
}

Schemas

List All Schemas

GET /api/v1/schemas

Returns JSON Schema for all entity kinds.

Get Schema for Kind

GET /api/v1/schemas/{kind}
curl http://localhost:8080/api/v1/schemas/service

Actions

List Actions

GET /api/v1/actions

Returns all Action entities.

Execute Action

POST /api/v1/actions/{name}/execute

Requires developer role.

curl -X POST http://localhost:8080/api/v1/actions/deploy-service/execute \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"inputs": {"environment": "staging", "service": "payment-api"}}'

Response:

{
"id": "run-uuid",
"actionName": "deploy-service",
"status": "running",
"inputs": {"environment": "staging"},
"triggeredBy": "alice",
"startedAt": "2025-01-01T12:00:00Z"
}

List Action Runs

GET /api/v1/actions/{name}/runs
GET /api/v1/actions/runs (all actions)

Get Action Run

GET /api/v1/actions/{name}/runs/{id}

Audit Log

GET /api/v1/audit?limit=50&offset=0

Returns audit log entries in reverse chronological order.

curl "http://localhost:8080/api/v1/audit?limit=20" \
-H "Authorization: Bearer <token>"

Response entries:

[
{
"id": "uuid",
"timestamp": "2025-01-01T12:00:00Z",
"userName": "alice",
"action": "create",
"resourceType": "Service",
"resourceName": "payment-api",
"source": "api",
"ipAddress": "10.0.0.1"
}
]

User History

Record Entity View

POST /api/v1/history
{
"kind": "Service",
"name": "payment-api",
"namespace": "default"
}

The UI calls this automatically when you navigate to an entity detail page.

Get Browsing History

GET /api/v1/history?limit=10

Returns the current user's recently viewed entities (max 20 per user).

Plugins

List Plugins

GET /api/v1/plugins

Returns all bundled plugins with their current enabled state.

Get Plugin Detail

GET /api/v1/plugins/{name}

Requires platform-engineer role.

Get Plugin Config

GET /api/v1/plugins/{name}/config

Requires platform-engineer role.

Update Plugin Config

PUT /api/v1/plugins/{name}/config

Requires platform-engineer role. Body is a JSON object that matches the plugin's config schema. Secret fields are redacted on reads as __GANTRY_SECRET_REDACTED__; sending that placeholder back preserves the stored secret.

Enable/Disable Plugin

PUT /api/v1/plugins/{name}/enable

Body: {"enabled": true} or {"enabled": false}

Requires platform-engineer role.

Trigger Sync

POST /api/v1/plugins/{name}/sync

Requires platform-engineer role.

GitOps

The GitOps plugin endpoints are available when the GitOps plugin is enabled.

Get Sync Status

GET /api/v1/plugins/gitops/status

Returns the current connection and sync state.

curl http://localhost:8080/api/v1/plugins/gitops/status \
-H "Authorization: Bearer <token>"

Response:

{
"connected": true,
"repoUrl": "https://github.com/org/gantry-catalog.git",
"branch": "main",
"lastCommit": "a1b2c3d4e5f6",
"lastCommitAt": "2026-03-12T10:30:00Z",
"lastPushAt": "2026-03-12T10:30:00Z",
"lastPullAt": "2026-03-12T10:25:00Z",
"lastError": "",
"pendingFiles": 0
}

Get Sync History

GET /api/v1/plugins/gitops/history

Returns recent push and pull operations (up to 100 entries).

List Tracked Files

GET /api/v1/plugins/gitops/files

Returns all entity YAML files tracked in the Git repository.

Response:

[
{"path": "Service/default/user-service.yaml", "kind": "Service", "namespace": "default", "name": "user-service"},
{"path": "Team/default/backend-services.yaml", "kind": "Team", "namespace": "default", "name": "backend-services"}
]

Trigger Full Sync (Push)

POST /api/v1/plugins/gitops/sync

Requires admin role. Exports all entities from the database to the Git repo, commits, and pushes. Runs asynchronously — returns 202 Accepted.

curl -X POST http://localhost:8080/api/v1/plugins/gitops/sync \
-H "Authorization: Bearer <token>"

Trigger Pull

POST /api/v1/plugins/gitops/pull

Requires admin role. Fetches the latest changes from the remote Git repo and reconciles with the database. Runs asynchronously — returns 202 Accepted.

curl -X POST http://localhost:8080/api/v1/plugins/gitops/pull \
-H "Authorization: Bearer <token>"

Dashboard

Get Dashboard Config

GET /api/v1/dashboard/config

Update Dashboard Config (Admin Only)

PUT /api/v1/dashboard/config
{
"widgets": [
{"id": "entity_stats", "enabled": true},
{"id": "recent_activity", "enabled": true}
],
"announcements": [
{
"title": "Scheduled Maintenance",
"message": "Downtime on Saturday 2am-4am UTC",
"severity": "warning"
}
]
}

Health Checks

GET /healthz    → {"status": "ok"}
GET /readyz → {"status": "ok"} or 503 if DB unreachable
GET /metrics → Prometheus text format metrics

Health Check Proxy

GET /api/v1/health-check?url=https://example.com/healthz

Authenticated endpoint used by the frontend status monitor. Only absolute http and https URLs to public targets are allowed. Loopback, private, link-local, and userinfo-containing URLs are rejected.

WebSocket

GET /api/v1/ws

Real-time entity and action notifications. WebSocket handshakes must authenticate with either a same-origin gantry_session cookie or an Authorization: Bearer <token> header. Query-string token auth is rejected.

Connect with a WebSocket client:

const ws = new WebSocket('ws://localhost:8080/api/v1/ws');

ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
// msg.type: "entity.created" | "entity.updated" | "entity.deleted"
// msg.payload: entity object
};

Subscribe to a specific channel:

ws.send(JSON.stringify({
action: "subscribe",
channel: "entities"
}));

Error Responses

All errors return JSON:

{
"error": "entity not found"
}

Common status codes:

CodeMeaning
400Bad request — invalid JSON or failed schema validation
401Unauthorized — missing or invalid token
403Forbidden — insufficient role
404Entity not found
409Conflict — entity already exists (use PUT to update)
422Unprocessable — entity failed JSON Schema validation
500Internal server error