Platform

Authentication

Self-host needs no Caspian API key. Hosted does. Always pass via so it is obvious which you meant.

SDK

cx = Caspian()
cx.channels.add("telegram", via="self-host", bot_token=TG, webhook_url=URL)
# no CASPIAN_API_KEY — you own inbound

cx = Caspian(api_key=KEY)
cx.channels.add("telegram", via="hosted", bot_token=TG)
cx.run()
# api_key is required for hosted add() and run()
const cx = new Caspian()
await cx.channels.add("telegram", {
  via: "self-host",
  bot_token: TG,
  webhook_url: URL,
})
// no CASPIAN_API_KEY — you own inbound

await cx.channels.add("telegram", { via: "hosted", bot_token: TG })
await cx.run({ apiKey: KEY })
// apiKey is required for hosted run(); add() still needs via: "hosted"

cx.run() without a key returns AuthRequired. Self-host handle / poll / listen never talk to the gateway. Python takes the key on Caspian(api_key=…); TypeScript takes it on run({ apiKey }).

CLI

The CLI stores the secret in ~/.caspian/.env (override with CASPIAN_HOME). Sign-in is device-auth in the browser. caspian init project can also write a project .env.

caspian init                 # asks: cli, project, or agent
caspian init cli             # CLI secret → ~/.caspian/.env
caspian init project         # writes ./.env in a folder
caspian init agent           # CLI secret + ./.env + .caspian/AGENT.md
caspian login                # sign in only

Hosted jobs also accept --api-key / CASPIAN_API_KEY and --gateway / CASPIAN_BASE_URL. Catalog and self-host channels add do not need a key.

Telegram still needs BotFather

Hosted Telegram does not mint a bot. Pass bot_token in both modes. Discord/Slack hosted can return an authorize URL instead of asking you for a token.