---
title: "Run a briq from an image spec or a recipe"
method: POST
path: "/v1/briqs"
tags: ["briqs"]
---

# Run a briq from an image spec or a recipe

`POST /v1/briqs`

## Request

- Base URL: `https://api.briq.cloud`
- URL: `https://api.briq.cloud/v1/briqs`
- Auth: HTTP bearer

Creates the briqs and answers once they are ready (healthcheck passed, or process started), for up to `waitTimeoutMs`, unless `wait: false`. A briq still `creating` then is on its way. `expose` publishes as it creates, the URL in `outputs.URL`.

## Request body

- union
  - object
    - `spec` BriqSpec, required
      - `name` string, required
      - `image` string, required
      - `cmd` union: The command: a string, run with sh -c ("npm start"), or the argv. Default: the image's
        - string
        - string[]
      - `entrypoint` string[]
      - `env` object: A string; { secret: NAME } for a value briq generates; { secret: NAME, value } for a credential you have, stored encrypted and never returned. Plain values are shown in status. {{briq:NAME}} in a plain value becomes the address of briq NAME in the stack; {{self:host}}, the hostname of its own URL when it is published as it is created (localhost without one)
      - `ports` integer[]: The ports the image listens on
      - `size` 'nano' | 'small' | 'medium' | 'large'
      - `volume` object
        - `mount` string, required
        - `gb` integer
      - `files` object: Boot files, absolute path → text or { base64 }: written before the process starts and again whenever it starts over. At most 64 files and 256 KB in all
      - `healthcheck` object
        - `cmd` string[], required
        - `intervalMs` integer
        - `timeoutMs` integer
      - `sleep` string: When the briq goes to sleep: after this long without use (agent calls, visits to its stack's URLs). A string: "30m", "3h", "7d" or "never", never a number. A sleeping briq keeps its disk, costs nothing for compute, and the next use wakes it. "never" keeps it always on (Pro plan and above)
      - `expose` integer: The port a public URL delivers to, when the briq has several: its front door. Declaring it publishes nothing
    - `stack` string
    - `expose` 'public' | 'private': Publish it as it is created: "private" for only whoever has the URL (it carries a secret), "public" for anyone. Left out, nothing is published. The URL comes back as outputs.URL. The port is spec.expose, or the only one in spec.ports
    - `wait` boolean: Answer once the briqs are ready (healthcheck passed, or process started)
    - `waitTimeoutMs` integer: How long to wait; a briq still creating then is on its way
  - object
    - `image` string: Another tag (postgres:17) or a compatible image (pgvector/pgvector:pg16). Default: the recipe's
    - `env` object: Added to the recipe's env, or replacing one of its values: a string, or { secret: NAME, value } for a credential
    - `cmd` union: The command: a string run with sh -c ("npm start"), or the argv. A language recipe's start command
      - string
      - string[]
    - `size` 'nano' | 'small' | 'medium' | 'large'
    - `volume` object: The volume: { gb }
      - `gb` integer, required
    - `files` object: Files, path → text or { base64 }: an app's code for a language recipe
    - `ports` integer[]: A language recipe: the port the app listens on, [8080] by default
    - `checkout` object: A language or static recipe: the code from a repo, as actions/checkout. { repo: "github.com/owner/app", ref?, path?, token? }
      - `repo` string, required
      - `ref` string
      - `path` string
      - `token` object
        - `secret` string, required
        - `value` string
    - `steps` object[]: A language recipe: shell commands run before the app starts, as GitHub Actions steps. [{ run: "npm ci" }, { run: "npm run build" }]
      - `run` string, required
    - `routes` object: The nginx recipe: path prefix → "briq:port", e.g. { "/api/": "backend:8080" }
    - `recipe` string, required: A recipe (GET /v1/recipes). Beside it, the fields of the service it makes, as a GitHub Actions service: image, env, cmd, size, volume, files; a language recipe also takes checkout, steps and ports. GET /v1/recipes/{name} lists what each takes and its defaults
    - `name` string
    - `stack` string
    - `expose` 'public' | 'private': Publish the recipe's front door as it is created: "private" for only whoever has the URL (it carries a secret), "public" for anyone. Left out, nothing is published. The URL comes back as outputs.URL. A recipe with no front door (a database) refuses it
    - `sleep` string: When the briq goes to sleep: after this long without use (agent calls, visits to its stack's URLs). A string: "30m", "3h", "7d" or "never", never a number. A sleeping briq keeps its disk, costs nothing for compute, and the next use wakes it. "never" keeps it always on (Pro plan and above). One window for every briq the recipe makes; left out, the environment's default
    - `wait` boolean: Answer once the briqs are ready (healthcheck passed, or process started)
    - `waitTimeoutMs` integer: How long to wait; a briq still creating then is on its way

## Response `201`

created

- RunResult
  - `briqs` Briq[], required
    - `id` string, required
    - `teamId` string, required
    - `stackId` string, required
    - `name` string, required
    - `image` string, required
    - `size` 'nano' | 'small' | 'medium' | 'large', required
    - `state` 'creating' | 'running' | 'stopping' | 'stopped' | 'sleeping' | 'starting' | 'destroying' | 'destroyed' | 'error', required
    - `internalHost` string, required: Its address on the team's private network
    - `endpoints` object[], required: Its URL, once published (one at most), and its TCP endpoint, once published
      - `id` string, required
      - `port` integer, required
      - `protocol` 'http' | 'postgres' | 'mysql' | 'redis' | 'mongodb' | 'amqp' | 'bolt' | 'grpc': http: a URL; a database protocol (postgres, mysql, redis, mongodb, amqp, bolt, grpc): a TCP endpoint, reachable from outside over TLS, url is its address without the password
      - `mode` 'public' | 'private', required: public: anyone can open the URL; private: only whoever has the URL, which carries a secret checked before a request reaches the briq
      - `url` string, uri, required
    - `ports` integer[]
    - `databasePorts` object[]: Its recipe's database ports: briq_expose one with its protocol for a TCP endpoint
      - `port` integer, required
      - `protocol` 'http' | 'postgres' | 'mysql' | 'redis' | 'mongodb' | 'amqp' | 'bolt' | 'grpc', required
    - `expose` integer, nullable
    - `env` object: As declared: plain values, and { secret: NAME } for secrets, whose values never appear
    - `createdAt` string, date-time, required
    - `startedAt` string, date-time, nullable, required: When its current run started (its last run, while it is not running)
    - `sleep` string, required: When the briq goes to sleep: after this long without use (agent calls, visits to its stack's URLs). A string: "30m", "3h", "7d" or "never", never a number. A sleeping briq keeps its disk, costs nothing for compute, and the next use wakes it. "never" keeps it always on (Pro plan and above)
    - `sleepsAt` string, date-time, nullable, required: When it goes to sleep unless it is used before then: every use moves this later. Null when it is not running or never sleeps
    - `lastUsedAt` string, date-time, nullable, required
    - `costCentsSoFar` number, required: Euro cents billed so far, fractions of a cent included
    - `error` string, nullable, required
    - `destroysAt` string, date-time, nullable: When a briq in error is destroyed automatically; null in any other state
    - `stoppedReason` 'idle' | 'cap' | 'credits' | 'user' | 'provider' | 'exited', nullable: Why it is stopped or sleeping. idle and provider: asleep, the next call or visit wakes it. cap and credits: a limit, asleep again once it has cleared. user and exited: only briq_start runs it again
    - `lastExit` object, nullable: The last time its process ended on its own: exit code (128 + n for signal n), whether it ran out of memory, and when
      - `code` integer, required
      - `oomKilled` boolean, required
      - `at` string, date-time, required
    - `files` object[]: Its boot files, by path and size; their content is not returned
      - `path` string, required
      - `bytes` integer, required
    - `forkedFrom` string, nullable
  - `outputs` object: A recipe's connection strings, the secrets briq generated (never ones you passed in), and URL when published
  - `recipe` string, nullable, required
  - `costLine` string, required

## Other responses

- `400`: validation
- `401`: unauthorized
- `402`: policy_violation or quota_exceeded (the key's policy), or payment_required (no credits: retrying cannot help)
- `403`: forbidden, or plan_limit (the team's plan does not allow it)
- `404`: not found
- `409`: invalid_state: not possible in the briq's current state; the message says why
- `413`: validation: the body, the command or its output is too large
- `429`: rate limited: retry after the `retry-after` header
- `502`: provider_error: the infrastructure refused the change
- `503`: provider_error: the infrastructure did not answer; retry in a moment

---

[API](https://skmtc.dev/briq/apis/briq-api.md) · [All operations](https://skmtc.dev/briq/apis/briq-api/llms.txt) · [OpenAPI document](https://skmtc.dev/briq/apis/briq-api/revisions/609b424459cb?raw)
