Live App →

SDKs & Clients

Official SDKs are on the roadmap. Until then, use these production-ready patterns.


Roadmap

SDK Language Status ETA
sentinel-python Python Design phase Q3 2026
sentinel-ts TypeScript Design phase Q3 2026
sentinel-go Go Backlog Q4 2026

Python Client Pattern

import requests
import time
from typing import Optional, Dict, Any

class SentinelClient:
    def __init__(self, base_url: str, access_token: str):
        self.base = base_url.rstrip("/")
        self.session = requests.Session()
        self.session.headers["Authorization"] = f"Bearer {access_token}"
        self.session.headers["Content-Type"] = "application/json"

    def _request(self, method: str, path: str, **kwargs) -> Dict[str, Any]:
        url = f"{self.base}{path}"
        for attempt in range(3):
            try:
                resp = self.session.request(method, url, timeout=30, **kwargs)
                if resp.status_code == 429:
                    time.sleep(2 ** attempt)
                    continue
                resp.raise_for_status()
                return resp.json()
            except requests.exceptions.RequestException as e:
                if attempt == 2:
                    raise
                time.sleep(2 ** attempt)
        raise RuntimeError("Max retries exceeded")

    def upload_document(self, file_path: str) -> Dict:
        with open(file_path, "rb") as f:
            return self._request("POST", "/api/v1/nexus/upload",
                                 files={"file": f})

    def get_document(self, doc_id: str) -> Dict:
        return self._request("GET", f"/api/v2/status/process/{doc_id}/progress")

    def send_chat_message(self, session_id: str, message: str) -> Dict:
        return self._request("POST", f"/api/v1/chat/{session_id}/messages",
                             json={"message": message})

TypeScript / Node.js Pattern

class SentinelClient {
  constructor(private baseUrl: string, private token: string) {}

  private async request(path: string, options: RequestInit = {}): Promise<any> {
    const url = `${this.baseUrl}${path}`;
    const headers = {
      "Authorization": `Bearer ${this.token}`,
      "Content-Type": "application/json",
      ...options.headers,
    };

    for (let attempt = 0; attempt < 3; attempt++) {
      const resp = await fetch(url, { ...options, headers });
      if (resp.status === 429) {
        await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
        continue;
      }
      if (!resp.ok) {
        const err = await resp.json().catch(() => ({}));
        throw new Error(`Sentinel API error ${resp.status}: ${err.detail || resp.statusText}`);
      }
      return resp.json();
    }
    throw new Error("Max retries exceeded");
  }

  async uploadDocument(file: File): Promise<any> {
    const form = new FormData();
    form.append("file", file);
    return this.request("/api/v1/nexus/upload", {
      method: "POST",
      body: form,
      headers: {}, // Let browser set Content-Type for multipart
    });
  }
}

Retry & Backoff

Status Retry? Delay
429 Too Many Requests ✅ Yes Exponential: 1s, 2s, 4s
500 Internal Error ✅ Yes Exponential: 1s, 2s, 4s
502/503/504 Gateway ✅ Yes Exponential: 1s, 2s, 4s
400 Bad Request ❌ No Fix request
401 Unauthorized ❌ No Refresh token
403 Forbidden ❌ No Check permissions

Error Handling

try:
    result = client.upload_document("cas.pdf")
except SentinelAuthError:
    # Refresh token and retry
    pass
except SentinelRateLimitError as e:
    # Back off and retry
    time.sleep(e.retry_after)
except SentinelAPIError as e:
    # Log and alert
    logger.error(f"API error {e.status}: {e.detail}")