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>
4.1 KiB
SDK reference — overview
The SDK is the set of functions your Rhai scripts can call. It comes in two layers:
- Services — stateful, app-scoped capabilities backed by the platform:
kv,docs,files,http,email,users,pubsub,queue,secrets,invoke,retry,dead_letters, andlog. These appear and disappear with releases (each is tagged with the SDK minor that added it). - Standard library — pure, stateless helpers:
json,base64,hex,url,regex,random,time. See Standard library.
This page covers the conventions that hold across every service. The per-service pages give exact signatures.
Namespacing and the handle pattern
Functions live in namespaces, called with :::
let id = random::uuid();
log::info("hi");
Storage services are collection-scoped: you first get a handle to a named collection, then call
methods on it. This is intentional — it makes the (app, collection, key) identity explicit.
let users = docs::collection("users"); // handle
let id = users.create(#{ name: "Ada" }); // method on the handle
let doc = users.get(id);
So it's kv::collection("x").get(k), not kv::get("x", k). Collections are mandatory; a
collection name may not be empty.
App scoping is automatic and non-negotiable
Every service call resolves the app from the server-side execution context. Nothing your script
passes can change which app's data it touches — there is no app_id argument anywhere in the SDK.
This is the isolation boundary described in Core concepts; treat it as
a hard guarantee, not a convention.
Error conventions
Uniform across all services (also covered in Writing scripts):
| Situation | Behavior |
|---|---|
| Real failure (DB error, payload too large, authorization denied) | throws — catch with try/catch, or let it become a 502 |
| Item not found / no result | returns () — test == () |
| Existence / was-present check | returns a bool |
Value encoding
Values you store or send are JSON-encoded on the wire:
- Maps, arrays, strings, numbers, booleans round-trip cleanly.
()(Rhai unit) becomes JSONnull.- Blobs (byte arrays, e.g. from
base64::decode) are base64-encoded inside JSON payloads (pubsub,queue).filesstores raw bytes directly. - Function pointers / closures cannot be serialized and are rejected by
queue,invoke, etc.
Size caps
Several services cap payload size to protect Postgres. Defaults (all tunable, see env vars):
| Service | Env var | Default |
|---|---|---|
kv value |
PICLOUD_KV_MAX_VALUE_BYTES |
256 KiB |
docs document |
PICLOUD_DOCS_MAX_VALUE_BYTES |
256 KiB |
pubsub message |
PICLOUD_PUBSUB_MAX_MESSAGE_BYTES |
256 KiB |
queue message |
PICLOUD_QUEUE_MAX_PAYLOAD_BYTES |
256 KiB |
files blob |
PICLOUD_FILES_MAX_FILE_SIZE_BYTES |
100 MiB |
Exceeding a cap throws. For kv/queue the size is checked before authorization so a public
script can't be used to hammer the database.
The full surface at a glance
| Namespace | Since SDK | Page |
|---|---|---|
log |
1.0 | Writing scripts |
kv |
1.2 | Storage |
docs |
1.3 | Storage |
files |
1.6 | Storage |
http |
1.5 | Outbound HTTP |
pubsub |
1.6 / 1.7 | Messaging |
secrets, email |
1.8 | Secrets, Email |
users |
1.9 | Users & auth |
queue, invoke, retry |
1.10 | Messaging, Composition |
dead_letters |
1.2 | Composition |
json base64 hex url regex random time |
1.0 | Standard library |
Many services also have an admin/inspection side on the HTTP API and the pic CLI (e.g. browse KV,
download files, read secret names). Those are read-mostly; writing data is the script's job. Each SDK
page links to its admin counterpart.