Add SDK to Your App
This page shows the smallest SDK integration in TypeScript, Python, and Go. Each example opens an agent session, calls a Gateway-protected resource, and leaves authorization and action-result audit behind.
Complete First Protected Call first so you have a generated runtime profile, a resource ID, and a protected path.
Use the Runtime Profile
Section titled “Use the Runtime Profile”All SDKs can read the runtime profile generated by Console guided setup.
export CARACAL_CONFIG=/path/to/caracal.tomlexport CARACAL_RESOURCE_ID=resource://example-apiexport CARACAL_RESOURCE_PATH=/On Windows PowerShell:
$env:CARACAL_CONFIG = "C:\path\to\caracal.toml"$env:CARACAL_RESOURCE_ID = "resource://example-api"$env:CARACAL_RESOURCE_PATH = "/"The profile supplies the zone, application, STS URL, Coordinator URL, app secret file, Gateway URL, and resource bindings. The resource variables choose which configured resource and path these examples call.
Install the SDK
Section titled “Install the SDK”Install the package for your application language.
| Language | Install command | Runtime requirement |
|---|---|---|
| TypeScript | npm install @caracalai/sdk or pnpm add @caracalai/sdk | Node.js 22+ |
| Python | pip install caracalai-sdk | Python 3.12+ |
| Go | go get github.com/garudex-labs/caracal/packages/sdk/go | Go 1.26+ |
TypeScript
Section titled “TypeScript”import { Caracal } from "@caracalai/sdk";
const caracal = new Caracal();const resourceId = process.env.CARACAL_RESOURCE_ID;const resourcePath = process.env.CARACAL_RESOURCE_PATH;
if (!resourceId) throw new Error("CARACAL_RESOURCE_ID is required");if (!resourcePath) throw new Error("CARACAL_RESOURCE_PATH is required");
await caracal.spawn(async () => { const ctx = caracal.current(); console.log("Agent session:", ctx?.agentSessionId);
const response = await caracal.fetch(resourceId, resourcePath, { method: "GET", });
console.log(await response.text());});Python
Section titled “Python”import asyncioimport os
from caracalai import Caracal
caracal = Caracal()resource_id = os.environ["CARACAL_RESOURCE_ID"]resource_path = os.environ["CARACAL_RESOURCE_PATH"]
async def main(): async with caracal.spawn() as ctx: print("Agent session:", ctx.agent_session_id)
response = await caracal.fetch( resource_id, resource_path, method="GET", ) print(response.text)
asyncio.run(main())package main
import ( "context" "fmt" "io" "net/http" "os"
caracal "github.com/garudex-labs/caracal/packages/sdk/go")
func main() { c, err := caracal.New() if err != nil { panic(err) }
resourceID := os.Getenv("CARACAL_RESOURCE_ID") resourcePath := os.Getenv("CARACAL_RESOURCE_PATH") if resourceID == "" || resourcePath == "" { panic("CARACAL_RESOURCE_ID and CARACAL_RESOURCE_PATH are required") }
err = c.Spawn(context.Background(), func(ctx context.Context) error { cc, _ := c.Current(ctx) fmt.Println("Agent session:", cc.AgentSessionID)
resp, err := c.Fetch(ctx, http.MethodGet, resourceID, resourcePath) if err != nil { return err } defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body) fmt.Println(string(body)) return nil }) if err != nil { panic(err) }}SDK Calls
Section titled “SDK Calls”| Call | Role |
|---|---|
new Caracal() / Caracal() / New() | Loads the generated profile or environment configuration and prepares token exchange. |
spawn() / Spawn() | Creates an agent session, binds context for the work, and terminates the session when the block exits. |
fetch() / Fetch() | Sends one request to a resource through the Gateway with context and authority injected. |
gatewayRequest() / GatewayRequest() | Builds the Gateway URL and X-Caracal-Resource header for explicit resource routing. |
transport() / Transport() | Injects Caracal context, authorization, trace, and baggage headers on outbound calls. |
spawn() creates an agent session under the application from your runtime profile. You reuse that one application for every agent session your workload spawns; you do not register an application per agent. See Should I create one application per agent?.
If policy denies the exchange, STS returns HTTP 403 and the SDK surfaces an error. Open Console audit or explain with the request ID to see the policy and diagnostics that determined the result.
Next Step
Section titled “Next Step”Use First-Run Troubleshooting if the SDK cannot read the profile, exchange authority, call the Gateway, or find audit evidence. Otherwise continue to Tutorials.

