DaytonaDocs

Functions

Deploy, invoke, schedule, and observe managed serverless functions.

Functions are managed, serverless handlers: an OCI image plus a wire contract (an HTTP server on a port) that Daytona invokes on demand, scaling microVM instances up and to zero for you and billing per invocation duration. All routes below are project-scoped by your API key (Authorization: Bearer $RLP_API_KEY) except the public web endpoint POST /fn/:project/:name, which is called without a key. For the conceptual model, see the Functions guides.

POST /fns

Deploy a function, creating a new immutable version and pointing current at it. Redeploying the same name rolls forward. Accepts JSON (a registry or named image source) or multipart/form-data to build from a Dockerfile (fields: name, dockerfile, config text parts, and a context tar; ~8 MiB cap). Every field except name and image has a default.

Request

FieldTypeRequired / defaultDescription
namestringrequiredPer-project unique name; [a-z0-9]([a-z0-9-]*[a-z0-9])?, 1–64 chars.
imageobjectrequired{"type":"registry","ref":"<image>"} or {"type":"named","name":"<project-image>"}.
handlerstring[][] (image entrypoint)Argv that starts the HTTP server on port.
portint8080Port the handler listens on (RLP_FN_PORT); 1–65535.
vcpusint1Provisioned vCPUs; ≥ 1.
mem_mibint512Provisioned memory (MiB); ≥ 128.
scratch_mibint512Scratch disk (MiB); ≥ 64.
timeout_sint300Max seconds per invocation; 1–172800 (48h).
scaledown_window_sint60Idle seconds before scale-to-zero; ≥ 2.
max_concurrencyint1Invocations one instance serves at once; ≥ 1.
max_instancesintnull (unbounded)Spend guard capping concurrent instances; ≥ 1 when set.
envobject{}Handler env vars; names match [A-Za-z_][A-Za-z0-9_]*.
snapshot_kindstringpre_entrypointpre_entrypoint or fn_ready (pre-warmed handler; falls back automatically).

Functions are always non-spot, non-persistent, and burstable, homed in the caller's default region — there is no region, spot, persistent, secrets, or mode field.

cURL
curl -X POST https://api.rl.trydaytona.com/fns \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "greet",
    "image": { "type": "registry", "ref": "ghcr.io/acme/greet:latest" },
    "mem_mib": 512,
    "timeout_s": 30,
    "env": { "LOG_LEVEL": "info" }
  }'
{
  "function_id": "b6f2c0a1-3d4e-4f5a-8b9c-0d1e2f3a4b5c",
  "version_id": "d1e2f3a4-b5c6-4d7e-8f90-1a2b3c4d5e6f",
  "name": "greet",
  "version": 1,
  "image_ref": "ghcr.io/acme/greet:latest",
  "build_job": null,
  "template_state": "published"
}

Errors

  • 400 — invalid name, port out of range, vcpus/mem_mib/scratch_mib below minimums, timeout_s out of range, scaledown_window_s < 2, max_concurrency < 1, max_instances < 1, invalid snapshot_kind, or invalid env name.

GET /fns

List the project's functions, newest first, each with its current version and template state.

cURL
curl https://api.rl.trydaytona.com/fns \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "functions": [
    {
      "id": "b6f2c0a1-3d4e-4f5a-8b9c-0d1e2f3a4b5c",
      "name": "greet",
      "current_version": 1,
      "image_ref": "ghcr.io/acme/greet:latest",
      "template_state": "published",
      "snapshot_kind": "pre_entrypoint",
      "created_at": "2026-08-01T12:00:00Z"
    }
  ]
}

GET /fns/:name

Fetch one function's detail, including its current version's full configuration.

cURL
curl https://api.rl.trydaytona.com/fns/greet \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "id": "b6f2c0a1-3d4e-4f5a-8b9c-0d1e2f3a4b5c",
  "name": "greet",
  "created_at": "2026-08-01T12:00:00Z",
  "current_version": {
    "version": 1,
    "image_ref": "ghcr.io/acme/greet:latest",
    "port": 8080,
    "vcpus": 1,
    "mem_mib": 512,
    "scratch_mib": 512,
    "timeout_s": 30,
    "scaledown_window_s": 60,
    "max_concurrency": 1,
    "max_instances": null,
    "env": { "LOG_LEVEL": "info" },
    "template_state": "published",
    "snapshot_kind": "pre_entrypoint"
  }
}

Errors

  • 404 — unknown function, or a function in another project.

GET /fns/:name/versions

List a function's version history, newest first. Each entry is the full version projection.

cURL
curl https://api.rl.trydaytona.com/fns/greet/versions \
  -H "Authorization: Bearer $RLP_API_KEY"
{ "versions": [ { "version": 2, "image_ref": "ghcr.io/acme/greet:v2" }, { "version": 1, "image_ref": "ghcr.io/acme/greet:latest" } ] }

Errors

  • 404 — unknown function.

PATCH /fns/:name/config

Update the runtime scaling knobs on the current version in place, without a rebuild. The change takes effect on the next invocation. Only the fields below may be updated here; changing the image or handler requires a redeploy via POST /fns. Send max_instances: null to remove a previously set cap (absent leaves it unchanged).

Request

FieldTypeDescription
max_concurrencyintInvocations one instance serves at once; ≥ 1.
max_instancesint | nullSpend-guard cap; null removes it.
timeout_sintMax seconds per invocation; 1–172800.
scaledown_window_sintIdle seconds before scale-to-zero; ≥ 2.
cURL
curl -X PATCH https://api.rl.trydaytona.com/fns/greet/config \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "max_concurrency": 8, "scaledown_window_s": 120 }'
{ "version": 1, "max_concurrency": 8, "scaledown_window_s": 120, "timeout_s": 30, "max_instances": null }

Errors

  • 400max_concurrency < 1, max_instances < 1, timeout_s out of range, or scaledown_window_s < 2.
  • 404 — unknown function.

POST /fns/:name/invoke

Synchronous invoke. The request body is forwarded verbatim to the handler as POST /, and the connection is held until the handler responds or timeout_s elapses. The response body is the handler's response. Response headers: x-rlp-invocation-id, x-rlp-fn-status (the handler's own status), and x-rlp-cold (1 if a cold start, else 0). The payload cap is ~6 MiB.

cURL
curl -X POST https://api.rl.trydaytona.com/fns/greet/invoke \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ada" }'
{ "greeting": "hello Ada" }

Errors

  • 404 — unknown function, or no current version.
  • 429 — no capacity could be placed within the queue budget (~30 s). Honor the Retry-After: 5 header and retry.
  • 502 — the handler instance was unreachable.
  • 504 — the handler exceeded timeout_s.

POST /fns/:name/spawn

Async invoke. Returns an invocation id immediately and runs the work in the background; poll GET /invocations/:id for the outcome. The retrievable async result is limited to 256 KiB of JSON.

cURL
curl -X POST https://api.rl.trydaytona.com/fns/greet/spawn \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ada" }'
{ "invocation_id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d", "status": "pending" }

Errors

  • 404 — unknown function, or no current version.

POST /fns/:name/map

Fan-out: submit up to 1000 payloads in one call and get back that many invocation ids to poll in parallel. Each payload is forwarded verbatim as a handler POST / body.

Request

FieldTypeDescription
payloadsarrayOne entry per parallel invocation; non-empty, ≤ 1000.
cURL
curl -X POST https://api.rl.trydaytona.com/fns/greet/map \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "payloads": [ {"name":"Ada"}, {"name":"Alan"} ] }'
{ "invocation_ids": [ "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d", "1f2e3d4c-5b6a-7980-a1b2-c3d4e5f60718" ], "count": 2 }

Errors

  • 400 — empty payloads, or more than 1000 entries.
  • 404 — unknown function, or no current version.

GET /invocations/:id

Poll an async, map, or scheduled invocation for its status and result. status is one of pending, running, succeeded, failed, timeout, or shed; done is true once terminal. result is present only for a succeeded invocation whose result was ≤ 256 KiB of JSON.

cURL
curl https://api.rl.trydaytona.com/invocations/9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d",
  "version": 1,
  "status": "succeeded",
  "duration_ms": 42,
  "cold": false,
  "error": null,
  "result": { "greeting": "hello Ada" },
  "queued_at": "2026-08-01T12:00:00Z",
  "finished_at": "2026-08-01T12:00:00Z",
  "done": true
}

Errors

  • 404 — unknown invocation, or one in another project.

POST /fns/:name/schedules

Create a cron schedule for the function. cron is a 5-field expression (minute hour day-of-month month day-of-week) evaluated in UTC; payload is forwarded verbatim on each fire.

Request

FieldTypeRequired / defaultDescription
cronstringrequired5-field cron expression, UTC.
payloadanynullJSON body sent to the handler on each fire.
enabledbooltrueWhether the schedule fires.
cURL
curl -X POST https://api.rl.trydaytona.com/fns/nightly-etl/schedules \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "cron": "0 2 * * *", "payload": { "mode": "full" } }'
{ "id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f", "cron": "0 2 * * *", "enabled": true, "next_run_at": "2026-08-02T02:00:00Z" }

Errors

  • 400 — invalid cron expression, or one that never fires.
  • 404 — unknown function.

GET /fns/:name/schedules

List the function's schedules, newest first.

cURL
curl https://api.rl.trydaytona.com/fns/nightly-etl/schedules \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "schedules": [
    {
      "id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
      "cron": "0 2 * * *",
      "payload": { "mode": "full" },
      "enabled": true,
      "next_run_at": "2026-08-02T02:00:00Z",
      "last_run_at": "2026-08-01T02:00:00Z"
    }
  ]
}

Errors

  • 404 — unknown function.

DELETE /fns/:name/schedules/:id

Delete a schedule by id. Returns 204 No Content.

cURL
curl -X DELETE https://api.rl.trydaytona.com/fns/nightly-etl/schedules/3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f \
  -H "Authorization: Bearer $RLP_API_KEY"

Errors

  • 404 — unknown function, or unknown schedule for that function.

POST /fns/:name/public

Enable or disable the function's public web endpoint. With require_token: true while enabling, a bearer token is minted and returned once in the response (null otherwise) — store it, as it isn't retrievable again.

Request

FieldTypeRequired / defaultDescription
enabledboolrequiredTurn the public endpoint on or off.
require_tokenboolfalseRequire a per-function bearer token on the public URL.
cURL
curl -X POST https://api.rl.trydaytona.com/fns/webhook/public \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "require_token": true }'
{
  "public": true,
  "url": "/fn/b6f2c0a1-3d4e-4f5a-8b9c-0d1e2f3a4b5c/webhook",
  "requires_token": true,
  "token": "rlpf_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d"
}

Errors

  • 404 — unknown function.

POST /fn/:project/:name

The public web endpoint — invoked with no project API key. The request body is forwarded to the handler as POST / and the handler's response is returned, exactly like a keyed synchronous invoke. If the function requires a token, pass it as a bearer token; otherwise omit the Authorization header.

cURL
curl -X POST https://api.rl.trydaytona.com/fn/b6f2c0a1-3d4e-4f5a-8b9c-0d1e2f3a4b5c/webhook \
  -H "Authorization: Bearer rlpf_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d" \
  -H "Content-Type: application/json" \
  -d '{ "event": "push" }'
{ "ok": true }

Errors

  • 401 — a token is required and the presented bearer token is wrong or missing.
  • 404 — no such function, or the function is not public (its existence is not revealed on the public host).
  • 429 — no capacity within the queue budget; honor Retry-After: 5.
  • 504 — the handler exceeded timeout_s.

GET /fns/:name/invocations

The invocation log for a function: past invocations newest first, with per-invocation status, duration, cold/warm, and error. Supports filtering and pagination.

Query paramTypeDefaultDescription
statusstringFilter by status (succeeded, failed, timeout, shed, …).
versionintFilter by function version.
limitint100Page size, clamped to [1, 1000].
offsetint0Offset for pagination.
cURL
curl "https://api.rl.trydaytona.com/fns/greet/invocations?status=succeeded&limit=2" \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "invocations": [
    {
      "id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d",
      "version": 1,
      "status": "succeeded",
      "queued_at": "2026-08-01T12:00:00Z",
      "finished_at": "2026-08-01T12:00:00Z",
      "duration_ms": 42,
      "cold": false,
      "error": null
    }
  ],
  "limit": 2,
  "offset": 0
}

Errors

  • 404 — unknown function.

GET /fns/:name/usage/series

Time-bucketed invocation counts for a function, for charting. Buckets are hourly by default or daily, with totals, outcome breakdowns, and cold/warm counts per bucket.

Query paramTypeDefaultDescription
resolutionstringhh (hourly) or d (daily).
fromRFC333924h/30d agoWindow start.
toRFC3339nowWindow end.
cURL
curl "https://api.rl.trydaytona.com/fns/greet/usage/series?resolution=h" \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "resolution": "hour",
  "from": "2026-07-31T12:00:00Z",
  "to": "2026-08-01T12:00:00Z",
  "points": [
    { "bucket": "2026-08-01T11:00:00Z", "total": 120, "succeeded": 118, "errors": 2, "shed": 0, "cold": 3, "warm": 117, "avg_ms": 44.5 }
  ]
}

Errors

  • 404 — unknown function.

GET /fns/usage/report

Aggregate usage and billing report across the project's functions for a window: per-function counts by outcome, latency percentiles (p50/p95/p99), cold-vs-warm split, and total billed credits.

Query paramTypeDefaultDescription
fromRFC333924h agoWindow start.
toRFC3339nowWindow end.
fnstringRestrict to one function by name.
cURL
curl "https://api.rl.trydaytona.com/fns/usage/report" \
  -H "Authorization: Bearer $RLP_API_KEY"
{
  "from": "2026-07-31T12:00:00Z",
  "to": "2026-08-01T12:00:00Z",
  "billed_credits": "1.2400",
  "functions": [
    {
      "name": "greet",
      "total": 2400,
      "succeeded": 2390,
      "failed": 6,
      "timeout": 2,
      "shed": 2,
      "cold": 40,
      "warm": 2360,
      "cold_ratio": 0.0167,
      "avg_ms": 43.1,
      "p50_ms": 39.0,
      "p95_ms": 88.0,
      "p99_ms": 140.0,
      "sum_ms": 103440
    }
  ]
}