Files
PiCloud/docs/dev-guide/src/reference/rest-api/apps.md
MechaCat02 05ea29fbd0 docs: add comprehensive developer guide (mdBook)
Add a browsable mdBook developer guide under docs/dev-guide/ covering the
full PiCloud v1.1.9 surface for developers building on the platform:

- Guide: introduction, 10-minute quickstart, core concepts, writing scripts
- Tutorials: 5 end-to-end example apps (URL shortener, webhook receiver,
  TODO API with auth, scheduled report, file-upload service) + feature matrix
- SDK reference: kv/docs/files, pubsub/queue, http, email, users, secrets,
  invoke/retry/dead_letters, stdlib, ctx & events
- HTTP API reference: every /api/v1 endpoint, auth, and capability
- CLI reference: the `pic` client + the server admin recovery command
- Config: every PICLOUD_* env var, capabilities & roles
- Deployment: Docker Compose, bare binary, Caddy/TLS, production checklist
- Operations: security, best practices, troubleshooting

Every example was built and run against a live instance; SDK signatures,
endpoint paths, and env vars were verified against source. Build the site
with `mdbook serve docs/dev-guide`. A pointer is added to README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 13:54:23 +02:00

2.6 KiB

Apps & domains

Apps are tenants; domains route hosts to apps. See Core concepts.

Apps

Method & path Capability Notes
GET /api/v1/admin/apps authenticated lists apps the caller can see (members: only theirs)
POST /api/v1/admin/apps InstanceCreateApp (owner/admin) create
GET /api/v1/admin/apps/{id_or_slug} AppRead one app
PATCH /api/v1/admin/apps/{id_or_slug} AppAdmin update name/description/slug
DELETE /api/v1/admin/apps/{id_or_slug} AppAdmin delete (cascades scripts, routes, data)
POST /api/v1/admin/apps/{id_or_slug}/slug:check AppAdmin {"new_slug":"…"}{ok, conflict_kind?, current_app?, reason?}

Create:

curl -X POST $PICLOUD/api/v1/admin/apps -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"slug":"demo","name":"Demo App","description":"…"}'
{"id":"41f42060-…","slug":"demo","name":"Demo App","description":null,
 "created_at":"2026-…Z","updated_at":"2026-…Z"}

Slug rules: ^[a-z0-9][a-z0-9-]{0,62}$, and not one of the reserved words (new, api, admin, apps, login, healthz, version, …). Renaming a slug records the old one for redirects; reclaim a released slug with "force_takeover": true in the create/patch body.

Domains

A non-default app's routes only match once the app claims the request Host.

Method & path Capability
GET /api/v1/admin/apps/{id_or_slug}/domains AppRead
POST /api/v1/admin/apps/{id_or_slug}/domains AppManageDomains
DELETE /api/v1/admin/apps/{id_or_slug}/domains/{domain_id} AppManageDomains
curl -X POST $PICLOUD/api/v1/admin/apps/demo/domains -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"pattern":"demo.localhost"}'
{"id":"6ff04d56-…","app_id":"41f42060-…","pattern":"demo.localhost",
 "shape":"exact","shape_key":"exact:demo.localhost","created_at":"2026-…Z"}

Pattern shapes (use {name}, never :name, in domains):

  • exact — app.example.com
  • wildcard — *.example.com
  • parameterized — {tenant}.example.com (the segment is captured into a route param)

The most specific claim wins. Claiming a host another app already holds (in the same shape) returns 409. The default app ships claiming localhost. Locally, claim something.localhost and test with curl -H 'Host: something.localhost' $PICLOUD/....

CLI: pic apps create demo --name "Demo App", pic apps domains add demo demo.localhost, pic apps ls, pic apps show demo.