Skip to main content

CLI

EmbedHub has a CLI for managing files and todos in your projects from your laptop or CI environment (GitHub Actions, GitLab Runners, etc.).

Installation

Download a prebuilt binary

PlatformArchitectureDownload
macOS (Apple Silicon)arm64embedhub-darwin-arm64
macOS (Intel)amd64embedhub-darwin-amd64
Linuxamd64embedhub-linux-amd64
Linuxarm64embedhub-linux-arm64
Windowsamd64embedhub-windows-amd64.exe

After downloading, chmod +x it (macOS/Linux) and move it onto your PATH:

chmod +x embedhub-darwin-arm64
sudo mv embedhub-darwin-arm64 /usr/local/bin/embedhub
embedhub --version

Configure your API key

Before using the CLI you need to give it an API key. The key tells EmbedHub which user the CLI is acting as and which projects it has access to.

1. Create a key in the web UI

  1. Log in to embedhub.com and click your name in the top right → Settings.
  2. Open the API Keys tab.
  3. Click Create API Key, name it (e.g. "laptop", "ci"), and tick which organizations the key should have access to.
  4. Copy the full key — it's shown only once. Treat it like a password.

API keys look like ehk_<16-char-prefix>_<40-char-secret>.

2. Tell the CLI about it

embedhub config set api-key ehk_1234567890123456_abcdef1234567890abcdef1234567890abcdef12

This writes the key to ~/.embedhub/config.yaml (file mode 0600). Confirm it stuck:

embedhub config list

The key will be shown masked.

Alternative: environment variables

If you'd rather not write the key to disk (CI runners, ephemeral containers), set it in the environment instead:

VariablePurpose
EMBEDHUB_API_KEYAPI key — overrides the config file.
EMBEDHUB_VERBOSESet to true for verbose output.

For GitHub Actions, see the GitHub Action integration — it takes the key as a secret and runs embedhub push for you.

Rotating or revoking

To rotate: create a new key in the web UI, run embedhub config set api-key <new>, then revoke the old one from the API Keys tab.

To revoke a key without replacing it: open the API Keys tab and click Revoke on the row you want to disable. The key stops working immediately.

Command reference

embedhub [command]

Available Commands:
config Manage configuration settings
push Upload a file or folder to a project
pull Download a file from a project
list List files in a project
search Search files by extension or substring
todos Manage project todos
help Help about any command

All commands take the project as org/project-name.

embedhub push

Upload files (with glob support) to a project. The last argument is always the project; any number of files, folders, or glob patterns may precede it.

embedhub push app.bin myorg/myproject --path releases/v1.0.0/
embedhub push *.zip myorg/myproject --path releases/latest/
embedhub push app.bin app.map app.elf myorg/myproject --path releases/v1.0.0/
embedhub push build/ docs/ myorg/myproject

Supported file types

EmbedHub auto-routes uploads into the right section based on the file extension:

CategoryExtensionsDestinationPurpose
Photos.jpg, .jpeg, .png, .svg, .webp, .gifphotosVisual assets
Documents.pdfdocumentsSpecs, guides
Releases.bin, .map, .elfreleasesFirmware, binaries

.zip files containing PDFs are auto-processed. The folder you pass via --path is preserved.

embedhub list

embedhub list myorg/myproject
embedhub list myorg/myproject --prefix releases/
embedhub list myorg/myproject --json
embedhub search myorg/myproject .bin              # match by extension
embedhub search myorg/myproject firmware # substring match in path
embedhub search myorg/myproject .pdf --prefix documents/

embedhub pull

embedhub pull myorg/myproject releases/app.bin
embedhub pull myorg/myproject releases/app.bin --output ./local-app.bin

embedhub todos

Manage project todos. Each todo is a small markdown file in the project — see the Todos page for the file format.

embedhub todos list myorg/myproject                          [--status done|wip|cancel] [--json]
embedhub todos add myorg/myproject --title "..." [--notes "..."] [--assignee <user>]
embedhub todos show myorg/myproject <id-or-prefix> [--json]
embedhub todos status myorg/myproject <id-or-prefix> <new> # in_progress | complete | cancelled
embedhub todos assign myorg/myproject <id-or-prefix> <user> # or --unassign
embedhub todos rm myorg/myproject <id-or-prefix> [--yes]
embedhub todos members myorg/myproject [--json]

<id-or-prefix> accepts a full UUID or any unique prefix (8 chars is usually enough — same as the IDs shown by embedhub todos list). Status accepts the short aliases done, wip, and cancel.

Examples

# Daily flow
embedhub todos list anuj/firmware
embedhub todos add anuj/firmware --title "review LED driver PR" --assignee tanvi
embedhub todos status anuj/firmware 9f3e2c1d done

# CI pipeline — file a follow-up todo when a build fails
if ! make test; then
embedhub todos add anuj/firmware \
--title "Fix failing test on $(git rev-parse --short HEAD)" \
--notes "$(make test 2>&1 | tail -3)"
fi

# Agent flow — pick up the next in-progress todo and complete it
ID=$(embedhub todos list anuj/firmware --status wip --json | jq -r '.[0].id')
embedhub todos status anuj/firmware "$ID" done

CI/CD example

#!/bin/bash
go build -o app .

embedhub push app john/my-app --path "releases/$(git describe --tags)/"
embedhub push app john/my-app --path "releases/latest/"

echo "✓ Deployed to EmbedHub"

Security

  • API keys are stored in ~/.embedhub/config.yaml and masked when displayed.
  • All communication uses HTTPS.
  • API keys only work with your personal organization's projects.

Troubleshooting

"API key not configured" — run embedhub config set api-key YOUR_KEY.

"Access denied" — ensure the key is valid and the project belongs to your personal organization.

"Not found" on todos commands — confirm your role on the project grants read/write/delete on /todos/* (org owners always have full access).