Pools
Base: https://api.dodil.io/v1/appid · platform bearer · see conventions.
The Pool object
{
"id": "…", "organization": "acme", "name": "my-app", "displayName": "My App",
"issuer": "https://appid.dodil.io/acme/my-app",
"jwksUri": "https://appid.dodil.io/acme/my-app/.well-known/jwks.json",
"audience": "pool:my-app",
"state": "active",
"policiesJson": "{…}", "settingsJson": "{…}",
"brandingJson": "{…}", "roleCatalogJson": "{…}",
"userStore": { "kind": "USER_STORE_KIND_K3", "bucket": "my-users-bucket",
"host": "pg.uk-lon-1.dodil.io:5432", "serviceAccount": "svc-appid" },
"migration": { "phase": "warm_copy", "usersTotal": 12000, "usersCopied": 8100, "…": "…" },
"createdAt": "…"
}state ∈ active | migrating | migration_failed. userStore is always credential-free. migration appears while one is running.
Lifecycle
| Method + path | Body | Notes |
|---|---|---|
POST /pools | { "name", "displayName?" } | Name is the issuer path segment — immutable |
GET /pools | — | All pools in your org |
GET /pools/{pool} | — | Includes live migration |
PATCH /pools/{pool} | any of displayName, policiesJson, settingsJson, brandingJson, roleCatalogJson | Partial — absent fields untouched; "{}" clears a document |
DELETE /pools/{pool} | { "wipeBucketData?" } | Deletes the pool; bucket data kept unless asked |
POST /pools/{pool}/rotate-keys | — | New Ed25519 key; old key remains in JWKS |
The JSON documents’ contents — settings knobs, policy keys (rate limits, cors_allowed_origins), the branding schema, and the role catalog shape — are covered in Core Concepts and the CLI guide.
Connections
| Method + path | Body |
|---|---|
POST /pools/{pool}/connections | { "kind": "local", "configJson": "{}", "enabled": true } — upsert by kind |
GET /pools/{pool}/connections | — |
DELETE /pools/{pool}/connections/{kind} | — |
local is the implemented kind; other kind names are accepted for storage but do not activate a sign-in method yet.
User store
| Method + path | Body | Notes |
|---|---|---|
POST /pools/{pool}/user-store | { "userStore": "" | "k3+sa://sa@host:port/bucket" | "postgres://…" } | Re-points without copying; "" = managed store |
POST /pools/{pool}/user-store/migrate | { "target", "keepSource?" } | Live migration with data |
POST /pools/{pool}/user-store/migrate/abort | — | Abort + roll back |
Migration phases (migration.phase): warm_copy → locked_delta → verifying → (cutover) → purging → done | failed. During locked_delta the pool’s issuer and mutating admin calls answer 503; a verification mismatch rolls back automatically. Semantics: CLI → User stores.
Health
GET /v1/appid/healthz — unauthenticated liveness probe.