Functions, Cron & Queues
Functions
Run your code on demand. Each execution runs in an isolated container; your code exports a handler that receives the request and returns a result.
curl -X POST "https://base.finiteskills.com/v1/functions" -H "X-Appwrite-Project: <YOUR_PROJECT_ID>" \
-H "X-Appwrite-Key: <API_KEY>" -H "Content-Type: application/json" \
-d '{"functionId":"double","name":"Double","code":"module.exports=({req})=>({n:(req.body.n||0)*2})"}'
curl -X POST "https://base.finiteskills.com/v1/functions/double/executions" \
-H "X-Appwrite-Project: <YOUR_PROJECT_ID>" -H "X-Appwrite-Key: <API_KEY>" \
-H "Content-Type: application/json" -d '{"body":{"n":21}}'
The handler signature is ({ req, res, log }) => result. Return a value or call
res.json(obj, statusCode). Executions record status, logs, errors and duration. Each function has a
configurable timeout (1–300 s) and a memory cap.
Runtimes
Set runtime on create (default node-22). Each execution runs in an isolated
container:
node-22 // entrypoint index.js
python-3.12 // entrypoint index.py
deno-1 // entrypoint index.js (ESM)
Event triggers
Invoke a function automatically when engine events fire — no polling. Subscribe to one or more event names
(or * for all):
POST /functions/{id}/triggers { "events": ["documentCreated","documentDeleted"] }
GET /functions/{id}/triggers
DELETE /functions/{id}/triggers/{triggerId}
Event names are the same set the webhook service exposes
(documentCreated, documentUpdated, documentDeleted,
fileCreated, fileDeleted, sessionCreated, sessionDeleted).
The event payload is delivered to the handler.
Variables & secrets
Attach environment variables to a function; they are injected into the runtime. Mark a variable
secret to make it write-only — the value is stored encrypted and never returned by
GET:
POST /functions/{id}/variables { "key":"STRIPE_KEY", "value":"sk_live_...", "secret":true }
GET /functions/{id}/variables # secret values come back as null
DELETE /functions/{id}/variables/{key}
Deployments & rollback
Each deployment is an immutable, versioned snapshot of the code. Creating one makes it the active version; re-activating an older one is an instant rollback:
POST /functions/{id}/deployments { "code":"module.exports=({req})=>({ok:true})" }
-> { "$id":"dep_...", "version": 4, "status":"active" }
GET /functions/{id}/deployments # history, newest first
POST /functions/{id}/deployments/{depId}/activate # roll back / roll forward
Cron
POST /cron schedules a recurring job targeting a function or a webhook. Schedules:
@every 30s|5m|1h, @hourly, @daily, or a */n * * * * cadence.
Queues
A durable, Postgres-native message queue:
POST /queues/{queue}/messages { body, delaySeconds } # enqueue (delaySeconds: hold before first delivery)
POST /queues/{queue}/receive { max, visibilityTimeout } # claim
POST /queues/{queue}/messages/{id}/ack # delete (done)
POST /queues/{queue}/messages/{id}/nack # return to the queue
A received message becomes invisible for its visibility timeout; ack removes it,
nack makes it immediately visible again. delaySeconds (up to 900) postpones a
message's first delivery.
Dead-letter set
A message that is received more than QUEUE_MAX_RECEIVES times (5 by default) without being
acked is treated as poison and moved to the queue's dead-letter set instead of being redelivered forever.
Inspect and replay them:
GET /queues/{queue}/dead # list dead-lettered messages
POST /queues/{queue}/messages/{id}/requeue # reset delivery count + make visible again