API & MCP Server

Manage skills and Brain from scripts, CI, and AI clients with workspace API keys - REST API and MCP server.

API & MCP Server

Hubi has a public REST API and a remote MCP server, both authenticated with workspace API keys. Use them to manage Skills and Brain from scripts, CI pipelines, and AI clients like Claude Code or Cursor.

Version 1 covers Skills and Brain (plus an identity endpoint for checking a key). Other parts of Hubi - automations, conversations, integrations - are not exposed yet.

The API is available on paid plans and to partner workspaces. If your workspace has neither, requests return a 403 with a clear message - upgrade the workspace or contact support.

Base URL for all examples: https://app.gethubi.ai.

This guide covers the happy paths; the endpoint-by-endpoint reference (parameters, schemas, every error code) lives in the API Reference section of this documentation site.

API Keys

Keys live in Capabilities -> API. Only workspace owners and admins can create them; members see the keys they created, admins see all of them.

Creating a key takes four choices:

  • Name - what the key is for, e.g. "CI deploy bot". This name also shows up in usage attribution.
  • Type - You keys act as you: they carry your current workspace role, drop to member-level reach if you are demoted, and stop working the moment you leave the workspace. Machine keys act as a workspace service account and survive member changes - the right pick for CI and integrations.
  • Permissions - All access can read and write. Read only can only fetch data; every mutation is rejected. Permissions cap what a key may do; they never grant more reach than the person behind it has.
  • Expiration - 30, 90, or 365 days, or no expiration. Expired keys are rejected automatically.

The full key (hubi_sk_...) is shown exactly once, right after creation. Copy it then - afterwards only a masked hint (hubi_sk_...ab12) remains, and there is no way to reveal the key again. Store it like a password.

Revoking a key takes effect immediately: the next request with that key gets a 401. Revoking a Machine key also disables its service account.

REST Quickstart

Every request carries the key as a bearer token. Start with the identity echo - it confirms the key works and tells you which workspace and actor it resolves to:

curl https://app.gethubi.ai/api/v1/me \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY"
{
  "ok": true,
  "data": {
    "workspaceId": "...",
    "actorId": "...",
    "keyId": "...",
    "permissions": "all"
  }
}

Every response uses the same envelope: { "ok": true, "data": ... } on success, { "ok": false, "error": "..." } on failure. Validation errors (400) additionally carry a details object. Rate limiting is per key (300 requests per minute); a 429 response includes a Retry-After header.

List the workspace skills:

curl https://app.gethubi.ai/api/v1/workspaces/WORKSPACE_ID/skills \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY"

Bulk-Importing Skills

The import primitive is PUT /skills/by-name/{slug} - an idempotent upsert. Missing skill gets created (201), existing skill gets overwritten (200). Re-running the same import is safe: no duplicates, no conflicts.

curl -X PUT https://app.gethubi.ai/api/v1/workspaces/WORKSPACE_ID/skills/by-name/write-release-notes \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Write release notes",
    "description": "Turns merged PRs into release notes in our voice.",
    "content": "# Write release notes\n\nStep-by-step instructions..."
  }'

The slug must be lowercase and hyphen-separated (max 64 characters) - the API tells you the canonical form if you get it wrong.

Mapping a skill bundle (SKILL.md + references)

A GitHub-style skill bundle does not map 1:1 onto a Hubi skill:

  • The SKILL.md body becomes content. The frontmatter description (single line, max 1024 characters) becomes description.
  • Sibling files (references/*.md and friends) are not servable as files next to the skill. Upload each one as a Brain file, then attach it as a skill reference - up to 50 references per skill:
# 1. Upsert the reference file into Brain (idempotent, keyed by folder + name)
curl -X PUT https://app.gethubi.ai/api/v1/workspaces/WORKSPACE_ID/brain/files/by-name \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"folder": "Skill references", "name": "style-guide", "content": "..."}'

# 2. Attach the returned file ids to the skill
curl -X PUT https://app.gethubi.ai/api/v1/workspaces/WORKSPACE_ID/skills/SKILL_ID/references \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fileIds": ["FILE_ID"]}'

You can also pass referenceFileIds directly in the upsert body to do both in one call.

Brain Files and Binary Uploads

Text content goes straight through PUT /brain/files/by-name (shown above). Binary files - images, PDFs, spreadsheets - take two steps: upload the bytes, then create the file row.

# 1. Upload the binary (multipart, max 20 MB)
curl -X POST https://app.gethubi.ai/api/v1/workspaces/WORKSPACE_ID/brain/upload \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY" \
  -F "[email protected]"
# -> data: { storagePath, mime, size, ext }

# 2. Create the Brain file pointing at the upload
curl -X POST https://app.gethubi.ai/api/v1/workspaces/WORKSPACE_ID/brain/files \
  -H "Authorization: Bearer hubi_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "parentId": null,
    "type": "document",
    "name": "style-guide",
    "body": {"type": "document", "storagePath": "...", "mime": "application/pdf", "size": 12345, "ext": "pdf"}
  }'

Folder structure is available at GET /brain/tree and GET /brain/folders/{id} (use root for the workspace root). System folders and files are read-only through the API.

Connecting the MCP Server

The MCP endpoint is https://app.gethubi.ai/api/mcp (streamable HTTP) and uses the same API keys. It exposes tools for listing, fetching, upserting, and deleting skills, browsing Brain, upserting text files, and the binary-upload recipe. The key pins the workspace, so no tool asks which workspace you mean.

Claude Code:

claude mcp add --transport http hubi https://app.gethubi.ai/api/mcp \
  --header "Authorization: Bearer hubi_sk_YOUR_KEY"

Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "hubi": {
      "url": "https://app.gethubi.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer hubi_sk_YOUR_KEY"
      }
    }
  }
}

Claude.ai custom connector (org admins, beta): add a custom connector with URL https://app.gethubi.ai/api/mcp and a static Authorization: Bearer hubi_sk_YOUR_KEY header.

With a Read only key the read tools work and every mutating tool returns a clear error - handy for giving an AI client safe, look-but-don't-touch access.

Good to Know

  • One reveal. The key secret is shown once at creation and stored only as a hash.
  • Revocation is instant. Revoked and expired keys get 401 on the next request.
  • Machine keys own what they create. Skills and files created by a Machine key are attributed to its service account, and survive any member leaving.
  • A key never outranks its owner. A "You" key follows your current role, so losing admin or leaving the workspace immediately narrows or kills the key. GET /api/v1/me reports the effective role alongside permissions.
  • Rate limit: 300 requests per minute per key, Retry-After tells you when to retry.

Did this page help you?