Connecting Other Systems

Reading and writing xSwarm data from another application, with a worked example.

xSwarm’s own CLI is a thin client over its REST API — every command it runs is a call any other program could make with the same credential. This is the general pattern for building something else on top of it.

Authentication

The credential is the same one xswarm login produces: an API key (prefixed xsk_), sent as a Bearer token.

Authorization: Bearer xsk_...

The simplest way to get one for a service (rather than a person at a terminal) is to run xswarm login once, on any machine, under the account the integration should act as, and read the resulting key from ~/.xswarm/config.json. Manage keys — list them, revoke one — through the /api/keys endpoints; a compromised or retired integration’s key can be revoked without touching anything else connected to the account.

Worked example: reading and registering projects

This is the exact call xswarm project list makes:

curl -s https://api.xswarm.ai/api/projects \
  -H "Authorization: Bearer $XSWARM_TOKEN"

Registering one — the same call xswarm project add makes after reading a local repo:

curl -s -X POST https://api.xswarm.ai/api/projects \
  -H "Authorization: Bearer $XSWARM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-project",
    "slug": "my-project",
    "repo_url": "https://github.com/you/my-project.git",
    "local_path": "/home/you/Projects/my-project",
    "tech_stack": "[\"astro\",\"cloudflare\"]"
  }'

The same pattern applies to blockers and requests — an external tool can read what’s open, file its own request on xSwarm’s behalf, or poll for a blocker’s answer, using the identical Authorization header against /api/blockers and /api/requests.

One API shape note if you’re writing a client: list endpoints don’t all shape their response the same way. /api/projects and /api/workers return a bare array; /api/blockers and /api/requests wrap it in a named key ({ "blockers": [...] }). Check the actual response rather than assuming one shape everywhere — a client that does will work against some endpoints and silently get nothing from others.

Worked example: a personal planning tool

A concrete integration this pattern is designed for: a personal planning application that budgets a person’s day across every kind of work, not only development, and needs to pull in “what development work needs attention today” as one input alongside everything else. The intended shape — decided, not yet built — is a small set of purpose-built endpoints (a project list, pending decisions, and a daily brief with time estimates) that such a planner polls or calls once a day, so it can slot dev work alongside non-dev tasks without re-deriving xSwarm’s own state by hand.

That specific integration doesn’t exist yet as running code — the endpoints above (/api/projects, /api/blockers, /api/requests) are what’s available today and already sufficient to build a version of it, just more general-purpose than the purpose-built version would be.