Consume Dirigex programmatically — discover governed agents, invoke them, and automate your tenant — through one typed API. The platform does the trust, verification, and dispatch; you call a small, stable surface and get back exactly what you expect, or a typed error that tells you why.
Humans use the hosted console at app.dirigex.ai; programs use the API at api.dirigex.ai. Both are first-class — this guide is the programmatic path.
Choose your path
| Path | When |
|---|---|
| TypeScript / Python SDK | Typed clients wrapping the core tenant routes with full type safety. The Python SDK ships sync and async clients with an identical method surface (snake_case). Use an SDK when you stay within the wrapped core routes. |
| Raw HTTPS | Required for any OpenAPI route neither SDK wraps (API-key lifecycle, SSO config, user management, allowlist, offboarding, metrics, audit-event detail, public catalog). Supported for every OpenAPI route. |
All core self-service routes are OpenAPI-documented with matching SDK helpers — that mapping is the source of truth for integration contracts.
Install the SDK
Once 0.1.0 is published, install the SDK for your language:
npm install @dirigexai/sdk
pip install dirigex-sdk
Pin the version in production (@dirigexai/sdk@0.1.0 or dirigex-sdk==0.1.0) so retries, validation, and error-code handling do not change underneath an integration. The SDKs are published from the Dirigex repository through trusted-publishing workflows; no long-lived registry tokens are used.
Authentication
Two bearer-token schemes, by caller:
Cognito ID token — for /self/* routes. Pass a Cognito ID token (not an access token) in Authorization. The backend validates token_use="id" and rejects access tokens. This is the most common gotcha: a working bearer that suddenly 401s on a /self/* call is usually an access token where an ID token is required.
API keys — for server-to-server. Mint via POST /self/tenant/api-keys and send as a bearer in the form dgx_<base64>. Keys carry scoped permissions:
| Scope | Grants |
|---|---|
catalog:read | Read the catalog |
agent:invoke | Invoke agents |
usage:read | Read usage |
metrics:read | Read metrics |
audit:read | Read audit events |
ingest:write | Register agents |
scim:provision | SCIM user provisioning (Phase-1: Users.create / Users.read only) |
Account-management capabilities (e.g. manage_tenant_users, manage_approvals) are deliberately not grantable to API keys. DSAR export is Cognito-only and tenant-owner-gated — API-key bearers are rejected there.
Quickstart
Bootstrap your tenant context, then read your own identity. Initialize the client with your API base URL and a token callable returning a Cognito ID token:
from dirigex_sdk import create_dirigex_client
with create_dirigex_client(
base_url="https://api.dirigex.ai",
get_token=lambda: my_auth.get_id_token(),
) as client:
client.self.bootstrap() # auto-generates an Idempotency-Key if not supplied
me = client.self.me()
create_dirigex_client() returns the sync client; create_async_dirigex_client() returns the async client with the identical surface. Context managers are supported.
What you can call
The SDKs wrap these ten core tenant routes with full type safety (TypeScript camelCase; Python snake_case, e.g. client.tenant.audit_events.list()); cross-language parity is enforced by tests:
client.self.bootstrap()client.self.me()client.self.refreshContext()client.tenant.catalog.list()client.tenant.agents.invoke()client.tenant.agents.register()client.tenant.usage.read()client.tenant.auditEvents.list()client.tenant.dsar.export()client.tenant.webhooks.*(create / list / revoke)
Raw-HTTPS-only (not SDK-wrapped): API-key lifecycle, SSO config, user management, allowlist, offboarding, metrics, and audit-event detail lookups (the list is wrapped, the detail is not).
Public catalog — GET /v1/catalog/agents, GET /v1/catalog/agents/{id}, and POST /v1/catalog/agents/{id}/invoke — are OpenAPI routes, not SDK-wrapped. (The unversioned /catalog/* aliases remain only for migration.)
Idempotency, rate limits, and errors
Idempotency (varies by route):
self.bootstrap()auto-generates anIdempotency-Keyif you don't supply one.tenant.agents.invoke()accepts optionalidempotency-keyandx-correlation-idheaders.tenant.agents.register()uses the JSON body fieldidempotencyKey(not a header).
Rate limits. SDK retry/backoff is configurable. The quota fields on /self/tenant/usage are advisory (enforcement is backend-owned). The public catalog has per-IP limits — list 60/30min, detail 60/30min, invoke 20/10min; anonymous callers are bucketed by XFF-first + TCP source to resist spoofing. Admin routes have separate buckets with a configurable policy mode (off / log / enforce).
Errors. Responses follow a {code, message} envelope — no stack traces, no datastore internals. The SDKs preserve typed error codes and the raw server codes; malformed responses raise rather than returning half-populated records. The status classes are distinct:
| Status | Meaning |
|---|---|
401 | Missing or invalid token |
403 | Insufficient scope or membership |
404 | Not found in the caller's tenant scope — existence is masked for privacy |
Going to production
- Pin the SDK version and configure retry/backoff for your traffic shape.
- Use API keys (scoped to the minimum needed) for machine-to-machine; never ship account-management on a key — it isn't grantable anyway.
- Treat
404as "not visible to you," not "definitely doesn't exist." - Send idempotency context on every retryable mutation.
Next: Trust & verification for what a catalog listing guarantees · Reference for the OpenAPI document and full auth/scope/error detail · Build a governed agent to publish one. Back to documentation home.