API Reference

OpenBoot provides a REST API for programmatic access to configs, package search, and utilities. All endpoints are hosted at https://openboot.dev.

Base URL

https://openboot.dev

Authentication

Most write endpoints and dashboard-style read endpoints require authentication. Two mechanisms are supported:

  • Browser session — set automatically after OAuth login (httpOnly session cookie).

  • CLI token — sent via the Authorization header:

    Authorization: Bearer obt_xxxxxxxxxxxxxxxx

    Get a token by running openboot login — it’s saved to ~/.openboot/auth.json and starts with the obt_ prefix.


Configs

List User Configs

Get all configs for the authenticated user.

GET /api/configs

Auth required: Yes

Response:

{
  "username": "alex",
  "configs": [
    {
      "id": "cfg_abc123",
      "slug": "my-setup",
      "name": "My Dev Setup",
      "description": "Personal development environment",
      "base_preset": "developer",
      "packages": [{ "name": "node", "type": "formula" }],
      "snapshot": null,
      "snapshot_at": null,
      "visibility": "unlisted",
      "alias": null,
      "install_count": 12,
      "updated_at": "2024-02-10T14:20:00Z"
    }
  ]
}

packages and snapshot are returned as parsed JSON (not strings). For the full row (including custom_script, dotfiles_repo, etc.), use GET /api/configs/:slug.

Get Config (Dashboard)

Get one of the authenticated user’s configs by slug, with installation URL. This is the dashboard endpoint — for the CLI-flattened shape, see GET /:username/:slug/config further down.

GET /api/configs/:slug

Auth required: Yes (returns 401 otherwise). Only returns configs owned by the caller; other users’ configs return 404 regardless of visibility.

Response:

{
  "config": {
    "id": "cfg_abc123",
    "slug": "my-setup",
    "name": "My Dev Setup",
    "description": "Personal development environment",
    "base_preset": "developer",
    "packages": [
      { "name": "node", "type": "formula" }
    ],
    "custom_script": "mkdir -p ~/projects",
    "dotfiles_repo": "https://github.com/user/dotfiles.git",
    "visibility": "unlisted",
    "alias": "mine",
    "snapshot": { "...": "parsed snapshot or null" },
    "macos_prefs": [
      { "domain": "com.apple.dock", "key": "tilesize", "value": "48", "type": "int" }
    ]
  },
  "install_url": "https://openboot.dev/mine"
}

Create Config

Create a new config.

POST /api/configs

Auth required: Yes

Request body:

{
  "name": "My Setup",
  "description": "Dev environment",
  "base_preset": "developer",
  "packages": [
    { "name": "node", "type": "formula" }
  ],
  "custom_script": "",
  "dotfiles_repo": "",
  "visibility": "unlisted",
  "alias": "mine"
}

Response: 201 Created

{
  "id": "cfg_abc123",
  "slug": "my-setup",
  "alias": "mine",
  "install_url": "https://openboot.dev/mine"
}

Constraints: name ≤ 100 chars; description ≤ 500 chars; alias 2–20 chars (lowercase alphanumeric + hyphens, reserved words rejected); max 500 packages; max 20 configs per user.

Update Config

Update an existing config. All fields are optional — only the fields you send are changed.

PUT /api/configs/:slug

Auth required: Yes (must own the config)

Request body: Same shape as create. Setting alias to "" or null removes the alias.

Response:

{
  "success": true,
  "slug": "my-setup",
  "alias": "mine",
  "install_url": "https://openboot.dev/mine"
}

Renaming via name regenerates the slug — the new slug is returned.

Delete Config

Delete a config.

DELETE /api/configs/:slug

Auth required: Yes (must own the config)

Response: 200 OK

{ "success": true }

Create or Update Config from Snapshot

Upload a snapshot captured by openboot snapshot. Creates a new config, or updates an existing one when config_slug is provided. POST and PUT both route here.

POST /api/configs/from-snapshot
PUT  /api/configs/from-snapshot

Auth required: Yes

Payload size limit: 1 MB

Request body:

{
  "name": "My Mac Setup",
  "description": "Captured 2026-05-17",
  "visibility": "unlisted",
  "config_slug": "my-mac-setup",
  "message": "added pnpm",
  "snapshot": {
    "matched_preset": "developer",
    "packages": {
      "formulae": ["node", "go"],
      "casks": ["visual-studio-code"],
      "npm": ["typescript"],
      "taps": ["homebrew/cask-fonts"]
    },
    "macos_prefs": [
      { "domain": "com.apple.dock", "key": "tilesize", "value": "48", "type": "int" }
    ],
    "shell": { "...": "..." },
    "git": { "...": "..." }
  }
}
  • config_slug is optional; when present, the snapshot updates that existing config and records a revision with message.
  • snapshot.packages must be an object with formulae, casks, npm, taps arrays.

Response: the created or updated config row, with packages and snapshot parsed. Status is 201 Created for a new config or 200 OK for an update.

{
  "id": "cfg_abc123",
  "slug": "my-mac-setup",
  "name": "My Mac Setup",
  "packages": [{ "name": "node", "type": "formula" }],
  "snapshot": { "...": "the snapshot you uploaded" },
  "visibility": "unlisted"
}

Config Endpoints (Public / CLI)

Get Config (CLI)

Returns a flattened, CLI-friendly shape used by openboot install. Different fields than GET /api/configs/:slug.

GET /:username/:slug/config

Auth required: Only for private configs (Bearer token belonging to the owner). Public and unlisted configs are open.

Response:

{
  "username": "alex",
  "slug": "my-setup",
  "name": "My Dev Setup",
  "preset": "developer",
  "packages": [{ "name": "node", "desc": "JavaScript runtime" }],
  "casks":    [{ "name": "visual-studio-code", "desc": "Code editor" }],
  "taps":     ["homebrew/cask-fonts"],
  "npm":      [{ "name": "typescript", "desc": "..." }],
  "dotfiles_repo": "",
  "post_install": ["mkdir -p ~/projects"],
  "macos_prefs": [
    { "domain": "com.apple.dock", "key": "tilesize", "value": "48", "type": "int" }
  ]
}

post_install is the custom_script split into trimmed non-empty lines.

Get Install Script

Get the shell install script for a config. The CLI’s install.sh curls this URL.

GET /:username/:slug/install

Auth required: Only for private configs. Send a Bearer token belonging to the owner; otherwise the endpoint returns 403 Config is private as plain text. (The page route /:username/:slug returns 404 for non-owners of a private config — there is no interactive auth prompt.)

Response: Shell script, Content-Type: text/plain; charset=utf-8.

#!/bin/bash
# OpenBoot install script for username/slug
# ...

Package Catalog

List All Packages

Returns the complete package catalog with metadata. Used by the CLI to fetch package descriptions and installer types. Cached 1h client / 24h CDN.

GET /api/packages

Auth required: No

Response:

{
  "packages": [
    {
      "name": "git",
      "desc": "Distributed version control system",
      "category": "essential",
      "type": "cli",
      "installer": "formula"
    },
    {
      "name": "visual-studio-code",
      "desc": "Code editor with extensions and debugging",
      "category": "essential",
      "type": "gui",
      "installer": "cask"
    },
    {
      "name": "typescript",
      "desc": "Typed superset of JavaScript",
      "category": "essential",
      "type": "language",
      "installer": "npm"
    }
  ]
}

Fields:

  • name — Package identifier
  • desc — Human-readable description
  • categoryessential, development, productivity, or optional
  • type — Package kind: cli, gui, language, devops, or database
  • installer — Install method: formula (Homebrew), cask (Homebrew Cask), or npm

Search Homebrew Packages

Search for Homebrew formulae and casks. Results are limited to 30.

GET /api/homebrew/search?q=<query>

Auth required: No

Query parameters:

  • q — Search query (min 2 chars)

Response:

{
  "results": [
    { "name": "node",               "desc": "JavaScript runtime",     "type": "formula" },
    { "name": "visual-studio-code", "desc": "Code editor",            "type": "cask" }
  ]
}

When the query is too short or rate-limited, the response is { "results": [], "error": "..." }.

Search NPM Packages

Search for npm packages (proxies the npm registry, up to 30 results).

GET /api/npm/search?q=<query>

Auth required: No

Query parameters:

  • q — Search query (min 2 chars)

Response:

{
  "results": [
    { "name": "typescript", "desc": "TypeScript language", "type": "npm" }
  ]
}

Utilities

Parse Brewfile

Parse a Brewfile and extract package lists. Used by the dashboard’s Brewfile import.

POST /api/brewfile/parse

Auth required: No

Request body: JSON

{
  "content": "brew "node"\nbrew "go"\ncask "visual-studio-code""
}

Max content length: 50 KB.

Response:

{
  "packages": ["node", "go", "visual-studio-code"],
  "formulas": ["node", "go"],
  "casks":    ["visual-studio-code"],
  "taps":     []
}

packages is the combined formulas + casks list for convenience. Note the field is formulas, not formulae.


Authentication

Get Current User

Get the authenticated user’s information.

GET /api/user

Auth required: Yes

Response:

{
  "user": {
    "id": "usr_abc123",
    "username": "johndoe",
    "email": "john@example.com",
    "avatar_url": "https://avatars.githubusercontent.com/u/123?v=4"
  }
}

Rate Limits

Rate limits are enforced in-memory per Cloudflare Worker isolate (not globally consistent — see src/lib/server/rate-limit.ts).

Endpoint TypeLimit
Config reads (/api/configs, /api/configs/:slug)30 requests per minute
Config writes (POST/PUT/DELETE configs, snapshot upload)30 requests per minute
Search (/api/homebrew/search, /api/npm/search, /api/brewfile/parse)30 requests per minute
Auth login10 requests per minute
CLI device flow (start / approve / poll)5–20 requests per minute

When the limit is exceeded, the response is 429 Too Many Requests with body { "error": "Rate limit exceeded" } and a Retry-After header (seconds). No X-RateLimit-* headers are returned.


Visibility Modes

Configs have three visibility levels:

VisibilityListingInstall URLAPI Read
publicListed on /explore and your profileAnyone can installAnyone (via /:username/:slug/config)
unlistedNot listed publiclyAnyone with the link can installAnyone with the link
privateOwner onlyRequires owner’s Bearer token (403 otherwise)Requires owner’s Bearer token

For private configs, run openboot login first to authenticate before installing.


Error Responses

All errors return JSON with an error field, except plain-text install endpoints which return text:

{ "error": "Config not found" }

HTTP Status Codes:

CodeMeaning
200Success
201Created
400Bad Request (invalid input)
401Unauthorized (missing or invalid auth)
403Forbidden (no permission, e.g. private config)
404Not Found
409Conflict (slug or alias already taken)
413Payload Too Large (snapshot > 1 MB)
429Too Many Requests (rate limit exceeded)
500Internal Server Error

Examples

Create a Config

TOKEN=$(jq -r '.token' ~/.openboot/auth.json)

curl -X POST https://openboot.dev/api/configs 
  -H "Authorization: Bearer $TOKEN" 
  -H "Content-Type: application/json" 
  -d '{
    "name": "My Setup",
    "base_preset": "developer",
    "packages": [
      {"name": "node",                "type": "formula"},
      {"name": "visual-studio-code",  "type": "cask"}
    ]
  }'

Search Packages

curl "https://openboot.dev/api/homebrew/search?q=docker"

Get Config JSON (CLI shape)

curl https://openboot.dev/johndoe/my-setup/config

See also: CLI Reference for the openboot command-line tool.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.