Skip to content
Subako Docs
Esc
navigateopen⌘Jpreview
On this page

Quickstart

Create an organization, publish an agent version, and run your first session — start to finish, from the terminal and one HTTP call.

Everything here happens in a terminal. By the end you will have an organization, a workspace, a published agent version, an API key, and a session that answers a message.

Install the CLI

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/subako-ai/subako-cli/releases/latest/download/subako-cli-installer.sh | sh

The installer puts subako in $XDG_BIN_HOME when you have one set, and ~/.local/bin otherwise. Check it:

subako --version

Set up an organization

Sign up

An organization is the billing and identity boundary. It starts on the Free plan with 500 SC to try things with — see Plans and billing for what the paid plans add and how to subscribe.

subako cloud signup --org acme --name "Acme, Inc."

--org is the organization’s handle. It is what identifies the organization: no two share one, it appears in its URLs, and it cannot be changed once the organization exists. It is also the name you sign in against — subako login --org acme in the next step, and every login after that — so pick one you can live with, and keep it. --name is only the display name, and that one you can change at any time.

This stores nothing locally. It prints the Core server your organization lives on — https://api.us.cloud.subako.ai unless you asked for another one — which is what you sign in against next.

Sign in

Signing in runs the OAuth device-authorization flow: the CLI prints a code and opens your browser, and the credential lands in ~/.config/subako/credentials.json once you approve it.

subako login --org acme

Use --profile to store the login under a name other than the organization handle — that is how you hold several organizations, or a staging and a production login, side by side. --server points the login at a Core server other than the default, https://api.us.cloud.subako.ai; subako profile list prints the server each stored profile is bound to.

subako whoami

Create a workspace

Every unit of work belongs to a workspace: agents, skills, vaults, API keys, and the sessions they run. use records the selection in your profile, so later commands need no --workspace flag.

subako workspace create --name production
subako workspace use production
subako workspace list

Publish an agent

Pick a model provider

Subako calls the model on your behalf, so a version publishes against a provider. Every workspace already sees the platform providers — they are configured for you and need no key of your own, so start there.

subako model-provider list
workspace: production (01a0877c-03d9-7823-b997-f42147b8b607)
01a07f90-238c-7de3-b55e-6fe53de063cf  type=platform  format=openai_responses  label=Subako  description=(none)
  model=crow  label=Crow
  model=hawk  label=Hawk
  model=sparrow  label=Sparrow

A workspace that has created nothing of its own sees exactly this: the Subako platform provider and the three models it serves. That is enough to finish the quickstart — providers you create yourself are listed alongside it.

Keep two things from the listing: the provider id you will publish against, and one of the model ids indented under it. Nothing else tells you which model ids a provider accepts.

To run against your own account instead, create a provider of your own. The key is read from stdin — never a flag — so it stays out of your shell history and out of the process list.

subako model-provider create \
  --format anthropic \
  --display-name "Anthropic production" \
  --base-url https://api.anthropic.com < key.txt

subako model-provider formats lists the formats this server accepts. An agent version may only publish against a provider whose format matches the one its model speaks.

Create the agent

An agent is just a name and an identity. It holds no configuration of its own — its versions do.

subako agent create --name support-triage

It prints the agent id, which agent publish takes as its argument. subako agent list shows it again later.

Write a version config

agent config-example prints the smallest configuration that publishes as it stands. It needs no server, so you can start editing before anything else exists.

Pass the format of the provider you picked, since the example differs between them.

subako agent config-example --format openai_responses > agent.json
{
  "system_prompt": "You are a helpful assistant.",
  "model": {
    "format": "openai_responses",
    "model": "your-model-id",
    "max_tokens": 8192,
    "context_window": 128000
  }
}

Replace your-model-id with a model id from the provider’s listing — hawk, say. The placeholder publishes happily and then fails at run time, so this edit is not optional.

Grants — MCP servers and skills — are optional and go in this same document. The provider is named by --model-provider at publish time, not in the file.

Publish it

subako agent publish <agent-id> \
  --config agent.json \
  --model-provider <provider-id>

The version is immutable. Publishing again makes a new one, and new sessions bind the newest live version; sessions already running stay on the version they bound.

Run a session

The rest is HTTP, against the same Core server you signed in to — the default, https://api.us.cloud.subako.ai, in the calls below. If you signed in against another one, subako profile list prints the server each profile is bound to.

Mint an API key

An API key is the machine credential your product runs under. Its secret is printed once and never again.

subako api-key mint \
  --label "support-triage backend" \
  --permission session.create \
  --permission session.read \
  --permission session.manage
minted api key support-triage backend (01a0877e-…) in workspace production (01a0877c-…)
permissions: session.create, session.read, session.manage
expires: (never)
prefix: sbk_ak_4f50c2aa
the secret below is shown once and cannot be retrieved again:
sbk_ak_4f50c2aa8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Copy that last line — the whole sbk_ak_… secret, not the prefix, which is only a label for recognizing the key in api-key list. The calls below read it from SUBAKO_API_KEY, so put it there now:

export SUBAKO_API_KEY=sbk_ak_4f50c2aa8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

This is a shell variable of your own, for the curl examples. The CLI never reads it — subako authenticates with the stored login from subako login, not with an API key.

subako api-key permissions lists what this server will grant a key. Grant the narrowest set that works — see Permissions.

Create the session

curl -X POST https://api.us.cloud.subako.ai/v1/sessions \
  -H "Authorization: Bearer $SUBAKO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "<agent-id>", "display_name": "ticket-4192"}'
{
  "id": "01a0877f-d3b3-7e73-9eed-a16caee8cff7",
  "status": "idle",
  "session_token": "sbk_st_...",
  "session_token_expires_at": "2026-09-09T19:48:16Z"
}

session_token is a credential scoped to this one session, carrying no permissions, shown once. It is what you hand a browser tab; the API key stays on your server. It expires at session_token_expires_at — mint more from POST /v1/sessions/{session_id}/tokens with the API key.

The two remaining steps need the session’s id and that token, so keep both — again as shell variables of your own:

export SESSION_ID=<the id from the response>
export SUBAKO_SESSION_TOKEN=<the session_token from the response>

Note which credential each call takes: creating a session is the API key’s job, and everything inside the session is the session token’s.

Send a message

Appending a user turn starts a run.

curl -X POST https://api.us.cloud.subako.ai/v1/sessions/$SESSION_ID/events \
  -H "Authorization: Bearer $SUBAKO_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type": "input", "text": "Summarize ticket 4192."}'

The reply names the run this started:

{ "run_id": "01a08780-611d-7290-a9a0-e8a27b64ad9c", "outcome": "new_run" }

Watch it work

The stream tails from the log’s head, so a run that already finished has nothing left to send. Pass after_seq=0 to replay the session from its first event and then continue live.

curl -N "https://api.us.cloud.subako.ai/v1/sessions/$SESSION_ID/events/stream?after_seq=0" \
  -H "Authorization: Bearer $SUBAKO_SESSION_TOKEN"

Events arrive as SSE, each with the sequence number a reconnect resumes from. The run is over at run_completed, run_failed, or run_cancelled.

id: 2
event: message_user
data: {"seq":2,"type":"message_user",...}

id: 5
event: message_assistant
data: {"seq":5,"type":"message_assistant",...}

id: 6
event: run_completed
data: {"seq":6,"type":"run_completed","run_id":"01a08780-..."}

The stream stays open after that, waiting for the next run — curl will not exit on its own, so interrupt it once you see run_completed.

Next steps

Was this page helpful?