Skip to content

Connect Your App with the SDK

This tutorial connects application code to Caracal. The examples use a generated runtime profile, open one agent session, and call a Gateway-protected resource.

In the Console, confirm that the selected zone has:

  • one confidential agent app;
  • a client secret stored in the secret file named by the generated runtime profile;
  • one protected resource with an active policy;
  • a Gateway URL and resource binding when using Gateway-routed HTTP.

Set the profile path and the resource target for the examples:

Terminal window
export CARACAL_CONFIG=/path/to/caracal.toml
export CARACAL_RESOURCE_ID=resource://billing-api
export CARACAL_RESOURCE_PATH=/charge

The client constructor is the standard entry point. It loads the generated profile when available, then falls back to environment configuration. See Configuration Order for the exact resolution order.

Terminal window
npm install @caracalai/sdk
import { Caracal } from "@caracalai/sdk";
const caracal = new Caracal();
const resourceId = process.env.CARACAL_RESOURCE_ID!;
const resourcePath = process.env.CARACAL_RESOURCE_PATH!;
await caracal.spawn(async () => {
const request = caracal.gatewayRequest(resourceId, resourcePath);
const response = await caracal.transport()(request.url, {
method: "POST",
headers: { ...request.headers, "Content-Type": "application/json" },
body: JSON.stringify({ amount: 1200 }),
});
console.log(await response.text());
});
Terminal window
pip install caracalai-sdk
import asyncio
import 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():
request = caracal.gateway_request(resource_id, resource_path)
async with caracal.transport() as client:
response = await client.post(
request.url,
headers=request.headers,
json={"amount": 1200},
)
print(response.text)
asyncio.run(main())
Terminal window
go get github.com/garudex-labs/caracal/packages/sdk/go
c, err := caracal.New()
if err != nil {
panic(err)
}
resourceID := os.Getenv("CARACAL_RESOURCE_ID")
resourcePath := os.Getenv("CARACAL_RESOURCE_PATH")
err = c.Spawn(context.Background(), func(ctx context.Context) error {
target, err := c.GatewayRequest(resourceID, resourcePath)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, target.URL, strings.NewReader(`{"amount":1200}`))
if err != nil {
return err
}
req.Header = target.Header.Clone()
req.Header.Set("Content-Type", "application/json")
resp, err := c.Transport(nil).Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
})
if err != nil {
panic(err)
}
SDK callWhat happens
new Caracal() / Caracal() / New()Loads configuration and prepares app-secret token exchange.
spawn() / Spawn()Creates an agent session, binds context, and tears it down after the block returns.
gatewayRequest() / GatewayRequest()Builds the Gateway URL and X-Caracal-Resource header.
transport() / Transport()Injects Authorization, trace, baggage, and Gateway routing behavior.

spawn() is the session boundary. If the function exits or raises, the SDK terminates the agent session and active authority for that session is revoked.

One application credential backs every agent session you spawn. A workload registers one application, then opens an agent session per unit of work — you do not register a new application per agent. See Should I create one application per agent?.

If your app spawns child agents or delegates work, continue to Implement Multi-Agent Delegation after this tutorial path.

Open Console audit and find the request. A complete Gateway-routed call produces:

  1. an authorization event from STS;
  2. an action-result event from Gateway.

Open explain with the request ID to confirm the application, resource, scopes, policy, policy set version, and decision.

Continue with Trace One Protected Request to investigate the request you just made.