Quick start (cloud)

1. Sign in and create an app

npm install -g @substructure.ai/cli
subs login

login authenticates in your browser and stores a token under ~/.config/substructure. Create an app:

subs apps create my-bot

In your project root.

This prints the app id and its signing secret, shown once — save the secret now. Pin the app so later commands need no --app:

subs link

2. Make sure to verify the signature in your worker

The hosted engine signs every decision it POSTs with the app's signing secret. Your worker should verify that signature before acting on a decision. Add the check:

server.mjs
import { createHmac, timingSafeEqual } from "node:crypto";

const SECRET = process.env.SUBS_SIGNING_SECRET;

function verify(body, header) {
    const expected = "sha256=" + createHmac("sha256", SECRET).update(body).digest("hex");
    const a = Buffer.from(expected);
    const b = Buffer.from(header ?? "");
    return a.length === b.length && timingSafeEqual(a, b);
}

Then reject unsigned requests in the server's handler, before calling decide:

server.mjs
if (!verify(body, req.headers["x-substructure-signature"])) {
    res.writeHead(401).end();
    return;
}

The provider key stays out of this. By default the hosted engine runs the LLM against its own provider and bills the app, so your worker sets no ANTHROPIC_API_KEY.

3. Deploy the worker

The engine reaches your worker over the public internet, so deploy it wherever you run Node and set the signing secret in its environment:

subs webhook secret   # prints the secret; set it as SUBS_SIGNING_SECRET where the worker runs

The deploy gives the worker a public HTTPS URL to point the app at.

4. Point the app at it

subs webhook set https://my-worker.example.com/

The engine now POSTs each decision to that URL, signed with the app's secret.

5. Send a message

Mint an app API key and submit on a user's behalf through the machine API.

export SUBS_API_KEY=$(subs keys create --label quickstart)
export BASE=https://api.substructure.ai

curl $BASE/api/machine/sessions/submit \
    -H "Authorization: Bearer $SUBS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "agent_id": "my-agent",
      "identity": { "id": "user_42" },
      "payload": { "type": "client.message", "message": { "role": "user", "content": "hi" } }
    }'

The response returns the session_id and turn_id. The engine delivered the decision to your worker, ran the loop, and called the model itself.

6. Watch it run

subs sessions list
subs sessions events <session-id> --stream
subs open

The reply, tool calls, and results stream as events. The whole session lives in the cloud; resume it by passing the same session_id to another submit.

Next

  • Cloud: apps, keys, webhooks, and where provider keys live.
  • Authentication: client tokens for browsers, and worker signing.
  • Client API: the machine and client surfaces this used.
  • Quick start: build the worker, add tools and a sub-agent.