API authentication
Everything the Depllo dashboard does goes through the REST API — and the same API is open to your scripts, CI jobs and agents. The simplest credential for them is a workspace API key.
Base URL
https://depllo.forjio.com/api/v1
Create an API key
- Open Dashboard → API Keys in the workspace the key should act in (use the workspace switcher first).
- Create key, name it after what will use it (
deploy script,Catent, …). - Copy the key from the dialog. It looks like
sk_live_followed by 48 hex characters, and this is the only time it is shown — store it like a password (a secret manager, a CI variable marked masked).
Keys are also available over the API (POST /api/v1/api-keys) — but only
to a signed-in person: a request authenticated by a key cannot create,
list or revoke keys (403 FORBIDDEN), so a leaked key cannot mint more.
Send it
Put the key in the Authorization header as a Bearer token, on any
/api/v1 route:
Authorization: Bearer sk_live_…
What a key is:
- Workspace-scoped. Every call acts in the workspace the key was
created in — its projects, pipelines, runners, variables, schedules,
usage and audit log — as the person who created it. Audit-log entries
made through a key are labelled
API key "<name>". - Shown once, stored hashed. Depllo keeps only a SHA-256 hash and a
display prefix (
sk_live_+ 4 characters) — the dashboard lists the prefix, when the key was created and when it was last used. - Long-lived until revoked. Keys don't expire. Revoking one (dashboard,
or
DELETE /api/v1/api-keys/:id) takes effect immediately: the next request with it gets401 INVALID_TOKEN.
A Huudis access token (what depllo auth login stores) is accepted the same
way — Authorization: Bearer <access-token> — but it is short-lived; use a
key for anything unattended. The runner protocol uses its own runner
tokens, not API keys.
Examples
curl
export DEPLLO_TOKEN=sk_live_…
# List projects
curl -H "Authorization: Bearer $DEPLLO_TOKEN" \
https://depllo.forjio.com/api/v1/projects
# Run a pipeline on main
curl -X POST https://depllo.forjio.com/api/v1/projects/proj_01hx…/pipelines \
-H "Authorization: Bearer $DEPLLO_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deploy-$(date +%s)" \
-d '{"ref": "main", "variables": {"DEPLOY_ENV": "staging"}}'
JavaScript / TypeScript
import { DeplloClient } from "@forjio/depllo";
// token defaults to process.env.DEPLLO_TOKEN
const depllo = new DeplloClient({ token: process.env.DEPLLO_TOKEN! });
const { data: projects } = await depllo.projects.list();
await depllo.pipelines.run(projects[0]!.id, { ref: "main" });
// Every route also has a method on depllo.api (generated from the spec):
const usage = await depllo.api.usageList();
Python
from forjio_depllo import DeplloClient
depllo = DeplloClient() # token= or the DEPLLO_TOKEN env var
projects = depllo.api.projects_list()["data"]
depllo.api.projects_create_pipelines(projects[0]["id"], ref="main")
Go
c := depllo.New(depllo.Config{Token: os.Getenv("DEPLLO_TOKEN")}) // sk_live_…
raw, err := c.API.ProjectsList(ctx)
CLI
The CLI uses DEPLLO_TOKEN when it is set, otherwise what depllo auth login saved — an API key (depllo auth login --api-key - reads it from
stdin) or your Huudis session:
export DEPLLO_TOKEN=sk_live_… # or, once: depllo auth login --api-key - < key.txt
depllo api projects list
depllo api projects create-pipelines proj_01hx… --ref main
depllo pipeline logs job_01hx… --follow
depllo api <area> <action> has a command for every API route — run
depllo api --help to browse them.
Response envelope
Every response — success or failure — has the same shape:
{
"data": { },
"error": null,
"meta": { "requestId": "req_01jx…", "timestamp": "2026-09-30T03:00:00.000Z" }
}
On failure data is null, error carries an UPPER_SNAKE_CASE code
and a message, and the HTTP status matches:
| Code | HTTP | Meaning |
|---|---|---|
AUTH_REQUIRED |
401 | No Authorization header (or session) |
INVALID_TOKEN |
401 | Unknown, malformed or revoked API key; invalid access token |
FORBIDDEN |
403 | Authenticated, but not allowed (e.g. a key managing keys) |
NOT_FOUND |
404 | No such resource in this workspace |
VALIDATION_ERROR |
400 | A field is missing or invalid — error.param names it |
CONFLICT |
409 | State conflict |
INTERNAL_ERROR |
500 | Our side — retry, then contact support with meta.requestId |
Match on error.code, not the message. Mutating requests accept an
Idempotency-Key header; the SDKs and the CLI send one for you.
See also
- API reference — the API's main resources.
- Every route — generated from Depllo's own code.
- SDKs & CLI — install and configure the JS and Python SDKs and the CLI.