Developers
SDKs & Clients
HTTP client patterns, retry logic, and error handling for Sentinel API integration.
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}")