Internal Services

HTTP APIs for zectre-scheduler, zectre-registry, zectre-build, and zectre-catalog.

These services run alongside zectre-api as separate processes. You typically don't call them directly — the API, CLI, and agents do it for you. But when operating or extending the platform, knowing these endpoints is useful.

zectre-scheduler

Handles task placement, node coordination, and deployment orchestration. Default port 47091.

Agents call this service to register, heartbeat, and report task state. zectre-api calls it to trigger deployments and stop tasks.

MethodPathDescription
GET/healthHealth check
POST/api/v1/nodes/registerAgent registers a node on startup
POST/api/v1/nodes/heartbeatAgent heartbeat — keeps the node alive
POST/api/v1/nodes/task-published-portAgent reports the port a task is listening on
GET/api/v1/nodesNode list from the scheduler's view
GET/api/v1/nodes/{id}Single node
POST/api/v1/scheduler/deployPlace a deployment on available nodes
GET/api/v1/scheduler/statusScheduler's view of cluster state
POST/api/v1/scheduler/assign-pendingForce assignment of pending tasks
POST/api/v1/scheduler/wakeWake a scale-to-zero deployment (called by proxy)
POST/api/v1/scheduler/reconcile-deployment/{id}Reconcile tasks for a deployment — called by zectre-api after PATCH
POST/api/v1/scheduler/stop-task/{id}Stop a specific task

Example: check cluster status

curl http://localhost:47091/api/v1/scheduler/status | jq

Example: force-assign pending tasks

Useful when a node comes back online and you want tasks to run immediately.

curl -X POST http://localhost:47091/api/v1/scheduler/assign-pending

zectre-registry

Stores and serves artifact binaries on disk, keyed by SHA-256. Default port 47092.

zectre-api proxies artifact upload/download calls to this service.

MethodPathDescription
GET/healthHealth check
POST/api/v1/artifacts/{id}/uploadUpload artifact bytes
GET/api/v1/artifacts/{id}/downloadDownload by artifact UUID
GET/artifacts/{sha256}/{name}Download directly by content hash

The /artifacts/{sha256}/{name} route is for direct content-addressed access — useful for caching and integrity verification.


zectre-build

Receives build jobs (from zectre-api or directly), compiles them, and uploads the resulting artifact to the registry. Default port 47093.

MethodPathDescription
GET/healthHealth check
POST/api/v1/buildsStart a build (same multipart format as the API)
GET/api/v1/builds/{id}Get build status

zectre-api's /api/v1/builds endpoint proxies to this service. See Builds & artifacts for the request format.


zectre-catalog

Identity provider and cluster registry. Handles GitHub OAuth → RS256 JWT issuance, organizations, and cluster targets. Default port 47100.

When configured, zectre-api fetches the catalog's JWKS (/.well-known/jwks.json) to verify RS256 tokens — allowing users authenticated via catalog to use the cluster API without a separate cluster account.

Public endpoints (no auth)

MethodPathDescription
GET/healthHealth check
GET/.well-known/jwks.jsonPublic JWKS — used by zectre-api to verify catalog JWTs
GET/.well-known/openid-configurationOIDC discovery document
GET/oauth/authorizeStart GitHub OAuth (PKCE) — redirect here with client_id, redirect_uri, code_challenge
GET/oauth/github/callbackGitHub's redirect target — internal, not called directly
POST/oauth/tokenExchange PKCE authorization code for a catalog JWT

OAuth flow

# 1. Redirect the user's browser to:
# /oauth/authorize?response_type=code&client_id=zectre-cli&redirect_uri=http://localhost:PORT/cb
#   &state=RANDOM&code_challenge=BASE64URL(SHA256(verifier))&code_challenge_method=S256
#   &audience=CLUSTER_AUDIENCE_STRING
 
# 2. GitHub authenticates the user and redirects back to redirect_uri with ?code=...&state=...
 
# 3. Exchange for a JWT:
curl -X POST http://localhost:47100/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code&code=CODE&redirect_uri=REDIRECT_URI&code_verifier=VERIFIER'

client_id must be "zectre-cli" or "zectre-dashboard". Redirect URIs must match the allowed patterns (localhost for CLI, any HTTPS URL for dashboard).

Authenticated API (Bearer required)

All /api/v1/* routes require Authorization: Bearer <catalog-jwt> (the RS256 token from /oauth/token).

MethodPathDescription
GET/api/v1/meCurrent user — { "email": "...", "name": "..." }
GET/api/v1/organizationsList orgs you belong to
POST/api/v1/organizationsCreate an org — body: { "name": "..." }
GET/api/v1/organizations/{id}Get org
PATCH/api/v1/organizations/{id}Update name/slug
DELETE/api/v1/organizations/{id}Delete org
GET/api/v1/organizations/{id}/membersList members
POST/api/v1/organizations/{id}/membersAdd member
PATCH/api/v1/organizations/{id}/members/{user_id}Change role: owner, admin, member
DELETE/api/v1/organizations/{id}/members/{user_id}Remove member
GET/api/v1/clustersList cluster targets (?organization_id=uuid or omit for personal)
POST/api/v1/clustersRegister a cluster target — body: { "name": "...", "api_base_url": "...", "audience": "..." }
PATCH/api/v1/clusters/{id}Update cluster target
DELETE/api/v1/clusters/{id}Remove cluster target

Example: list your cluster targets

CATALOG_TOKEN=$(cat ~/.config/zectre/catalog_token)
 
curl http://localhost:47100/api/v1/clusters \
  -H "Authorization: Bearer $CATALOG_TOKEN" | jq

See also