Documentation

Build on Darwa

Darwa runs applications from your repository — web services, static sites, workers, agents, databases, and object storage — without you configuring infrastructure. This reference covers every service, the REST API, and the CLI.

API v1CLI 0.2.0Updated 13 Aug 2026Base api.darwa.com/api/v1

Quickstart

Install the CLI, authenticate, and deploy the repository you are standing in. Darwa detects the framework, writes the build and start commands, and returns a URL.

terminal
# 1 — install on macOS
brew install haqiq-app/tap/darwa

# Alternative: install the release with npm
npm i -g https://github.com/haqiq-app/darwa-cli/releases/download/v0.2.0/darwa-cli-0.2.0.tgz

# 2 — authenticate (opens a browser)
darwa login

# 3 — deploy the current directory
darwa deploy

# 4 — inspect the project
darwa projects list
Note

darwa deploy creates the service on first run and updates it after that. Nothing is asked interactively unless detection is ambiguous.

Core concepts

ConceptMeaning
ProjectA repository and everything deployed from it. Billing and team access attach here.
ServiceOne running thing — a web service, static site, worker, or agent.
Environmentdevelopment, testing, staging, production, or a temporary preview. Same build, different values.
ReleaseAn immutable build plus its configuration. Rollbacks restore a release.
ResourceA database or storage bucket attached to a project and injected into services.

darwa.yaml reference

Detection covers most projects. Commit darwa.yaml when you want the configuration in version control, or when one repository holds several services.

darwa.yaml
services:
  - name: storefront          # web service
    type: web
    runtime: node22
    build: npm ci && npm run build
    start: npm start
    regions: [us-east, eu-central]
    scale: { min: 1, max: 8, on: cpu }

  - name: image-worker        # background worker
    type: worker
    runtime: node22
    start: node worker.js
    queue: { name: images, type: priority }
    concurrency: 20
    retries: { attempts: 5, backoff: exponential }

resources:
  - postgres: storefront-db
  - bucket: user-uploads

Web services

A web service is a process that listens for HTTP requests and stays running. It gets adarwa.app subdomain immediately, plus any custom domains you add.

Port binding

Bind to the port in PORT on host 0.0.0.0. If you bind elsewhere, Darwa detects the listening port at build time rather than failing the deploy.

server.js
const port = process.env.PORT || 3000;
app.listen(port, "0.0.0.0", () => console.log(`listening on ${port}`));

Environment variables

Values are set per environment and injected at runtime. Secrets are never written to build output or logs, and a value matching a stored secret is redacted wherever it appears.

terminal
darwa env set DATABASE_URL=... --env production
darwa env set LOG_LEVEL=debug     --env preview
darwa env diff staging production

Scaling rules

FieldTypeDescription
minrequiredintegerInstances kept running at all times. 0 allows scale to zero.
maxrequiredintegerHard ceiling. Never exceeded, even under a traffic spike.
onenumcpu | memory | requests | queue_depth. Defaults to cpu.
targetintegerUtilisation percentage to hold. Defaults to 70.
predictivebooleanScale ahead of recurring traffic patterns. Defaults to true on Pro.

Static websites

Framework, build command, and output directory are read from the project. Node version comes from .nvmrc, package.json, or the latest LTS.

Redirects, rewrites, and headers

darwa.json
{
  "redirects": [
    { "from": "/old-page", "to": "/new-page", "status": 301 },
    { "from": "/blog/:slug", "to": "/articles/:slug" }
  ],
  "rewrites": [
    { "from": "/api/*", "to": "https://api.acme.com/*" }
  ],
  "headers": [
    { "for": "/*", "set": { "X-Frame-Options": "DENY" } }
  ]
}

Image optimization

Reference the original path. The response is AVIF or WebP with a JPEG fallback, sized to the request, with a blur placeholder available at ?blur.

index.html
<img src="/hero.jpg" width="1600" height="900" alt="…" />
<!-- served as AVIF 188 KB instead of JPEG 4.2 MB -->

Background workers

A worker consumes jobs from a managed, Redis-compatible queue. Existing BullMQ, Celery, Sidekiq, and Asynq code connects with the injected connection string.

worker.js
import { Worker } from "bullmq";

new Worker("images", async job => {
  await resize(job.data.key);
}, { connection: { url: process.env.QUEUE_URL } });

Schedules

terminal
darwa schedule add nightly-export --cron "0 2 * * *" --overlap skip
darwa schedule add health-sweep   --every "5 minutes"
darwa schedule run nightly-export        # trigger once, now

Retries and dead letters

FieldTypeDescription
attemptsrequiredintegerTotal tries including the first. Maximum 25.
backoffenumfixed | linear | exponential. Defaults to exponential.
dead_letterbooleanMove exhausted jobs to the dead-letter queue. Defaults to true.
timeoutdurationKill and retry a job that exceeds this. Defaults to 15m.

AI agents

Deploy event-driven or long-running agents with triggers, durable memory, scoped tools, human approval gates, and step-level traces. The full runtime guide now has its own documentation page.

Databases

Creating a database injects DATABASE_URL into the services you select. TLS is required and certificates are managed for you.

terminal
darwa db create storefront-db --engine postgres:17 --size standard
darwa db url storefront-db --pooled
darwa db psql storefront-db          # opens a session, no tunnel needed

Connection pooling

Use the pooled URL (:6543) for serverless and worker pools, and the direct URL (:5432) for migrations and anything needing session state.

Careful

Prepared statements and LISTEN/NOTIFY require the direct connection. Running migrations through the pooler can fail with transaction-mode errors.

Backups and recovery

terminal
darwa db backups storefront-db
darwa db restore storefront-db --to "2026-08-02 14:12:09"
# restores into a NEW instance; promote it once you have verified it

Cloud storage

Buckets are S3-compatible. Point any existing SDK at the injected endpoint and credentials.

upload.ts
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: process.env.DARWA_STORAGE_ENDPOINT,
  region: "eu-central",
});

await s3.send(new PutObjectCommand({
  Bucket: "user-uploads",
  Key: "2026/06/IMG_4482.jpg",
  Body: file,
}));

Signed uploads

terminal
darwa storage sign user-uploads/2026/06/photo.jpg --put --expires 15m
POST/v1/buckets/{bucket}/searchSearch by content
Request
{
  "q": "product images with blue shoes",
  "limit": 10,
  "filter": { "size_gt": "1MB" }
}
Response · 200
{
  "results": [
    {
      "key": "uploads/2026/06/IMG_4482.jpg",
      "score": 0.94,
      "why": "blue suede trainers on a wooden floor",
      "tags": ["shoes", "blue", "product"],
      "size": 2411520
    }
  ],
  "searched": 1204882,
  "took_ms": 310
}

Developer interfaces

Use the CLI for terminal workflows and the REST API for applications and automation. Both use the same workspace → project → service → deployment resource model.

Platform agents

Give your own agent scoped access to Darwa so it can deploy, inspect logs, and open pull requests on your behalf. Tokens are scoped by action and by project, and every call an agent makes appears in activity history attributed to that token.

terminal
darwa tokens create ci-agent \
  --scope deploy:staging,logs:read,metrics:read \
  --project storefront --expires 90d

Available tools

ToolScopeWhat an agent can do
deploydeploy:{env}Trigger a deploy or roll back a release
logslogs:readRead build and runtime logs, filtered by service
metricsmetrics:readLatency, error rate, saturation, queue depth
diagnosediagnose:readFetch the platform's own analysis of a failure
envenv:writeSet environment values — never read secret values back
dbdb:readRun read-only queries against a nominated database
Design note

Secret values cannot be read through the API at all — an agent may set a value or check that one exists, but never retrieve it. Anything else would make a leaked token a leaked vault.