Deploy a catalog app
Installs an app from the curated catalog on the target agent. Returns immediately with status: pending; poll GET /platform/deployments/{id} until it reaches running (typically 30 s – 3 min depending on the app).
You can install the same app multiple times on one agent — the platform assigns each instance its own host port automatically, so they coexist without conflict. (Fixed-protocol apps like RustDesk are the exception — one per server.)
Network mode (declared on the catalog manifest, not passed in the request — every catalog app picks one). Drives whether the response carries a domain (HTTP path) or a connection_info: {ip, ports, public_key} block (raw TCP/UDP path) for reachability:
- http (default) — app speaks HTTP. Behind Caddy + Let's Encrypt at an imprezaapps.com subdomain (or a customer domain). The domain handling rules below apply.
- host_ports — app speaks raw TCP/UDP (RustDesk: 21115/tcp, 21116/tcp + 21116/udp, 21117/tcp, 21118/tcp, 21119/tcp). No Caddy, no cert, no domain. Response carries connection_info with the reachable ip, the ports list (with manifest labels), and — for apps that emit one on the boot log — a public_key the server auto-captures (RustDesk does this). Clients connect to <ip>:<port> with the app's own encryption. The domain field in the body is ignored.
- hybrid — raw protocol ports AND an HTTP admin UI behind Caddy on a subdomain. Response carries BOTH domain (admin UI) and connection_info (raw ports).
Port-conflict guard: fixed protocol ports can only be bound once per host, so a second host_ports/hybrid deploy on the same agent that reuses a port returns 409 CONFLICT.
Domain handling — match the clientarea behavior across all callers (API, CLI, MCP). Applies to http + hybrid modes; host_ports ignores the domain field entirely:
- Leave domain empty → server auto-generates <app-slug>-<6hex>.imprezaapps.com, creates the Cloudflare A record at the agent's public IP, and uses it as the deployment hostname. Most common path for new customers.
- Pass domain ending in .imprezaapps.com → server ensures a Cloudflare A record exists for that exact name (idempotent — reuses if already there).
- Pass a domain you own → passthrough; you handle DNS (point an A record at the agent's public IP before deploy so Let's Encrypt can issue). Cold standby exception: with standby: true, no hostname is generated. Omit domain, onion and vars.domain; only the reviewed Memos 0.31.0 recipe is accepted.
Request
- Base URL: https://api.imprezahost.com/v1
- URL: https://api.imprezahost.com/v1/platform/deployments
- Auth: API key in header X-API-Key and API key in header X-API-Secret
Request body
Example request
{
"app_name": "vaultwarden",
"agent_id": "agt_4bcbffef132a2089",
"app_version": "1.32.0",
"domain": "vault.example.com",
"vars": {
"signups_allowed": "true"
}
}Response
Deployment enqueued
Changes
No recorded changes to this operation across all 1 revision of this API.