Skip to content

HTTP API

Base URL: https://deploy.tja.nrw. Every request needs a deploy token:

Terminal window
curl -H "Authorization: Bearer $VIBE_TOKEN" https://deploy.tja.nrw/v1/apps

Responses are JSON. Errors look like {"error": "…", "hint": "…"}, sometimes with a code such as app_limit_reached. Rate limits are in Limits.

GET /v1/me Who the token belongs to, with its tokens.
GET /v1/usage Apps used and allowed, per-app limits, databases, rate limits.
POST /v1/me/tokens {name, expiresInDays?} → new token, shown once.
DELETE /v1/me/tokens/:id Revoke a token.
GET /v1/org/tokens All tokens of the organization (its admins).
DELETE /v1/org/tokens/:id Revoke one of them.
GET /v1/apps Apps with URL, health and last deploy.
GET /v1/apps/:name Status: health, problem, pods, events, volume, last deploys.
DELETE /v1/apps/:name Delete the app.
POST /v1/apps/:name/deploys Upload a .tar.gz of the folder as the body → 202 {id, url, statusUrl}. Query: port, volume=1, link=db1,db2.
GET /v1/apps/:name/deploys?limit= Deploy history.
GET /v1/deploys/:id One deploy with status and log; poll it until live or failed.
GET /v1/apps/:name/logs?tail= Recent output.
GET /v1/apps/:name/logs?follow=1&tail=&since= Live logs as Server-Sent Events (below).
GET /v1/apps/:name/metrics CPU and memory with share of the limits.
GET /v1/apps/:name/env {keys}: variable names.
PATCH /v1/apps/:name/env {set: {K: "v"}, unset: ["K"]}, restarts the app.
DELETE /v1/apps/:name/volume Delete the volume and its data.
GET /v1/apps/:name/domains Domains with status pending, issuing, active or error.
POST /v1/apps/:name/domains {domain} → DNS instructions.
POST /v1/apps/:name/domains/:domain/verify Check DNS and go live.
DELETE /v1/apps/:name/domains/:domain
GET /v1/databases Databases with status and links; connection strings masked.
POST /v1/databases {name, type: "postgres" | "redis"} → 201.
GET /v1/databases/:name Status and linked apps.
GET /v1/databases/:name/connection Full connection string (recorded in the activity log).
POST /v1/databases/:name/links {app, envName?}: set the variable in the app and restart it.
DELETE /v1/databases/:name/links/:app
DELETE /v1/databases/:name Delete with all data.

GET /v1/audit?app=&action=&result=&before=&limit= → {events, next}, newest first. result takes a list such as denied,failed; pass next as before for the next page.

GET /v1/apps/:name/logs?follow=1 answers with text/event-stream:

Event Data
attach Now streaming a container; newPod after a deploy, restarts after a crash.
log {lines: [{t, text}]}. t is an RFC 3339 timestamp with nanoseconds.
status The container is not running: state, reason, exit code, hint.
end The server closes the stream (after 30 minutes).

To resume after a disconnect, reconnect with since=<t of the last line>; lines are neither repeated nor skipped. A : ping comment every 15 seconds keeps proxies from closing the stream.