← Back to Home

HaltState AI: Quickstart Guide

Get HaltState up and running in under 5 minutes.

1. Install the SDK

Choose your language:

# Create a virtual environment (recommended)
python3 -m venv haltstate-env
source haltstate-env/bin/activate

# Install the SDK
pip install haltstate-sdk
npm install @haltstate/sdk
go get github.com/haltstate-ai/sdk-go@v1.0.1
// build.gradle.kts
repositories {
    maven { url = uri("https://jitpack.io") }
}
dependencies {
    implementation("com.github.haltstate-ai:sdk-java:v0.2.0")
}
# Cargo.toml
[dependencies]
haltstate = { git = "https://github.com/haltstate-ai/sdk-rust", tag = "v0.1.0" }

2. Get Your Credentials

Sign up at the HaltState Dashboard to get your: - Tenant ID - Your organization identifier - API Key - Starts with hs_

3. Use the Guard Pattern

The guard() context manager is the recommended way to gate agent actions:

from haltstate import HaltStateClient, ApprovalPending, ActionDenied
import sys

client = HaltStateClient(
    tenant_id="your-tenant-id",
    api_key="hs_your_api_key"
)

try:
    with client.guard(
        action="database.delete",
        params={"table": "users", "id": 123},
        idempotency_key="delete-user-123"
    ) as permit:
        # This block ONLY executes if approved
        delete_user(123)
        print(f"Approved by: {permit.approver}")

except ApprovalPending as e:
    print(f"Awaiting approval: {e.approval_id}")
    sys.exit(0)

except ActionDenied as e:
    print(f"Action denied: {e}")
    sys.exit(1)
import { HaltStateClient, ApprovalPending, ActionDenied } from '@haltstate/sdk';

const client = new HaltStateClient({
    tenantId: 'your-tenant-id',
    apiKey: 'hs_your_api_key'
});

try {
    const permit = await client.guard(
        'database.delete',
        { table: 'users', id: 123 },
        'delete-user-123'
    );
    // This executes only if approved
    await deleteUser(123);
    console.log(`Approved by: ${permit.approver}`);
    await permit.complete();
} catch (e) {
    if (e instanceof ApprovalPending) {
        console.log(`Awaiting approval: ${e.approvalId}`);
    } else if (e instanceof ActionDenied) {
        console.log(`Action denied: ${e.message}`);
        process.exit(1);
    }
}
import hs "github.com/haltstate-ai/sdk-go"

client, _ := hs.NewClient(hs.Config{
    TenantID: "your-tenant-id",
    APIKey:   "hs_your_api_key",
})

permit, err := client.Guard(ctx, "database.delete",
    map[string]any{"table": "users", "id": 123},
    "delete-user-123",
)

if errors.Is(err, hs.ErrApprovalPending) {
    fmt.Printf("Awaiting approval: %s\n", err.(*hs.ApprovalPendingError).ApprovalID)
    return
} else if errors.Is(err, hs.ErrActionDenied) {
    fmt.Printf("Action denied: %v\n", err)
    os.Exit(1)
}

// Approved - execute action
deleteUser(123)
fmt.Printf("Approved by: %s\n", permit.Approver)
permit.Complete(ctx)
import ai.haltstate.HaltStateClient;
import ai.haltstate.HaltStateConfig;
import ai.haltstate.exception.ApprovalPending;
import ai.haltstate.exception.ActionDenied;

HaltStateConfig config = HaltStateConfig.builder("your-tenant", "hs_...").build();

try (HaltStateClient client = new HaltStateClient(config)) {
    try (GuardContext guard = client.guard(
            "database.delete",
            Map.of("table", "users", "id", 123),
            "delete-user-123")) {
        // Approved - execute action
        deleteUser(123);
    } catch (ApprovalPending e) {
        System.out.println("Awaiting approval: " + e.getApprovalId());
    } catch (ActionDenied e) {
        System.out.println("Action denied: " + e.getMessage());
        System.exit(1);
    }
}
use haltstate::{Client, Config, Error};

let client = Client::new(Config {
    tenant_id: Some("your-tenant".to_string()),
    api_key: Some("hs_...".to_string()),
    ..Default::default()
})?;

match client.guard("database.delete",
    json!({"table": "users", "id": 123}),
    Some("delete-user-123")).await {
    Ok(permit) => {
        // Approved - execute action
        delete_user(123).await;
        println!("Approved by: {}", permit.approver);
        permit.complete().await;
    }
    Err(Error::ApprovalPending { approval_id, .. }) => {
        println!("Awaiting approval: {}", approval_id);
    }
    Err(Error::ActionDenied { reason, .. }) => {
        println!("Action denied: {}", reason);
        std::process::exit(1);
    }
    Err(e) => return Err(e.into()),
}

What Just Happened?

  1. Guard checks policy - HaltState evaluates if the action is allowed
  2. Three possible outcomes:
  3. Allowed - Guard block executes immediately
  4. Approval Required - ApprovalPending raised, human reviews in dashboard
  5. Denied - ActionDenied raised, policy blocked it
  6. Idempotency key - If you retry with the same key after approval, it remembers and executes