Installation

Catentio ships two flavors of tooling for talking to the control plane:

  • CLIcatentio-saas on your terminal. Best for one-off operations, scripting, and exploration. Uses Huudis device flow for sign-in.
  • SDKs — libraries in Node.js, Python, and Go. Best for embedding Catentio in another product or wiring up integrations.

The portal itself doesn't need anything installed locally — just a browser.

Note: this page covers the SaaS CLI and SDKs (@forjio/catentio-saas-cli, @forjio/catentio-saas-node, catentio-saas on PyPI, and the Go module under sdk/go/). The agent runtime CLI — the one that ships to a customer VPS — is a separate package in the catentio repo.

The public API is live at https://catent.io/v1/. Authenticate with an API key (Authorization: Bearer cat_pk_...) created in the portal under API keys.

It is a small, explicit surface — nine endpoints (agents, workflows, runs, projects, outbound webhooks). It is not a general-purpose window onto the control plane, and it never will be: anything not on that list returns 404 by design. See the API reference for the list.

There is still no api.catent.io, and the control plane's own port is not publicly reachable. https://catentio.com/v1/* 301s to https://catent.io/v1/*, which now serves the public API.

CLI

The CLI's package name is @forjio/catentio-saas-cli (bin: catentio-saas), currently at version 0.3.0.

Not on the public npm registry. npm install -g @forjio/catentio-saas-cli returns a 404 as of this writing — the package hasn't been published. (@forjio/catentio-saas-node, below, is published; only the CLI wrapper isn't.) Until that changes, run it from source:

git clone https://github.com/hachimi-cat/catentio-saas-node.git
cd saas-catentio/cli
npm install
npm run build
node bin/catentio-saas.js --version

npm link from that directory will put catentio-saas on your PATH if you want to invoke it like the published examples below.

Verify the install:

catentio-saas --version

You should see a bare version string, e.g. 0.3.0 — not a name/version string.

The next step is signing in. The CLI uses Huudis OIDC device flow — no client secret, no copy-pasting tokens:

catentio-saas auth login

The CLI opens a browser tab on huudis.com/device, you confirm the code shown in the terminal, and the CLI stores the session at ~/.catentio-saas/credentials (an INI file). From then on every command auto-refreshes the access token before it expires. Other identity commands: auth whoami (shows the signed-in identity) and auth logout (deletes the local credentials file).

Real defaults (all overridable by env var):

Setting Default Env override
Issuer https://huudis.com CATENTIO_SAAS_ISSUER
Client ID catentio-saas-cli CATENTIO_SAAS_CLIENT_ID
Base URL https://catentio.com CATENTIO_SAAS_BASE_URL
Scope openid profile email catentio:admin CATENTIO_SAAS_SCOPE
Credential profile default CATENTIO_SAAS_PROFILE

Signing in works independently of the control-plane reachability problem above — it talks to Huudis, not Catentio. Commands that then call the control plane (almost everything past auth) will fail against the default base URL per the warning at the top of this page.

Command groups: agents, api-keys, auth, billing, chat, cost, events, feature-flags, files, heartbeats, integrations, memory, output-destinations, projects, runs, scheduled-jobs, skills, system, tools, webhooks, workspaces.

Two commands are broken even once the network problem above is solved:

  • catentio-saas agents invoke <slug> --message <text> sends {"message": ...} to the control plane's invoke route. That route requires a prompt field, not message — and it proxies to a runtime endpoint that doesn't exist upstream, so it 404s regardless.
  • catentio-saas runs show <id> calls GET /v1/runs/{id}, which does not exist on the control plane (the real per-run detail route is /v1/runs/{id}/detail).

runs list, runs cancel, runs events, runs retry, and the rest of the command surface target real routes.

Node.js SDK

The Node SDK is @forjio/catentio-saas-node, published on npm at version 0.1.0:

npm install @forjio/catentio-saas-node

It's compatible with Node 20 and later. It ships with TypeScript types out of the box.

There are two ways to authenticate — pick the one that fits your context. Neither will reach anything at the default base URL today (see the warning above); this is the shape to build against, not a working example against production.

Static API key (server-to-server)

import { CatentioSaasClient } from '@forjio/catentio-saas-node';

const catentio = new CatentioSaasClient({
  apiKey: process.env.CATENTIO_API_KEY,
});

const agents = await catentio.agents.list();
console.log(agents);

API keys are minted in Dashboard → API keys and look like cat_pk_xxxxxxxxxxxxxxxx. They never expire on their own — rotate them when team members leave or you suspect compromise.

The control plane doesn't check API keys. A cat_pk_... key is verified by the catentio runtime (for the runtime's own customer-facing endpoints) — the control plane, which is what this SDK talks to, never validates one. Sending apiKey here has no effect on any control-plane route today.

Bearer session (device-flow)

If your code is running interactively (a CLI, a script you'll run yourself), use the same device-flow Session the CLI uses:

import { CatentioSaasClient, Session, startDeviceFlow, pollDeviceToken } from '@forjio/catentio-saas-node';

const flow = await startDeviceFlow({ issuer: 'https://huudis.com', clientId: 'catentio-saas-cli' });
console.log('Visit', flow.verificationUriComplete);

const tokens = await pollDeviceToken(flow);
const session = new Session({ ...tokens, issuer: 'https://huudis.com', clientId: 'catentio-saas-cli' });

const catentio = new CatentioSaasClient({ session });

Session handles proactive refresh so long-running processes don't 401 mid-run. The resulting Huudis JWT is honoured only on the control plane's billing, chat, and workspaces routes — not the rest of the API surface.

Python SDK

The Python SDK's package name is catentio-saas, import name catentio_saas (PEP 8 underscore-naming). It supports Python 3.9+.

Not on PyPI. pip install catentio-saas 404s — the package has never been published to the public index. Install from source instead:

git clone https://github.com/hachimi-cat/catentio-saas-node.git
pip install -e saas-catentio/sdk/python

(As of this writing github.com/hachimi-cat/catentio-saas-node itself also isn't publicly reachable, so this only works if you have access to the repo.)

from catentio_saas import CatentioClient
import os

with CatentioClient(api_key=os.environ["CATENTIO_API_KEY"]) as catentio:
    agents = catentio.agents.list()
    print(agents)

For device-flow Bearer auth:

from catentio_saas import CatentioClient, Session

session = Session(
    access_token="...",
    refresh_token="...",
    expires_at=1_800_000_000,
    issuer="https://huudis.com",
    client_id="catentio-saas-cli",
)

with CatentioClient(session=session) as catentio:
    runs = catentio.runs.list()

Go SDK

The Go SDK lives in the same repo as Catentio itself, under module path github.com/hachimi-cat/catentio-saas-go:

go get github.com/hachimi-cat/catentio-saas-go

As with the Python SDK above, github.com/hachimi-cat/catentio-saas-node is not publicly reachable as of this writing, so go get against the public URL will fail outside the team.

Import it as catentio:

import catentio "github.com/hachimi-cat/catentio-saas-go"

Minimal usage — NewClient doesn't return an error, and every resource method takes a trailing per-call token override (pass "" to fall back to the client-level key/session):

package main

import (
    "context"
    "fmt"
    "os"

    catentio "github.com/hachimi-cat/catentio-saas-go"
)

func main() {
    client := catentio.NewClient(catentio.ClientOptions{
        APIKey: os.Getenv("CATENTIO_API_KEY"),
    })

    agents, err := client.Agents.List(context.Background(), "")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(agents))
}

It uses only the Go standard library — no external dependencies. Requires Go 1.22+.

Get an API key

For server-to-server use you'll want a static API key — keeping in mind, per the warnings above, that the control plane doesn't validate one on any route today:

  1. Sign in to the Catentio portal.
  2. Navigate to Dashboard → API keys.
  3. Click Create API key and give it a name.
  4. Copy the secret immediately — we show it once.

There is no scope picker: the API-keys endpoint accepts a scopes field but discards it (v1 grants full access to the customer's data, unscoped) — there's nothing to configure beyond a name.

The convention across SDKs is to read credentials from environment variables:

Variable Purpose
CATENTIO_API_KEY The full key string — secret, never commit
CATENTIO_BASE_URL Optional — only set if you're pointing at a non-default instance

Don't bake the key into source. Use your environment's secret manager. For local dev, a gitignored .env file is fine. For production, use Vault or your platform's equivalent.

Next