Actions
Every client method, the API call it makes, and what it returns. Click a method
for its full signature; click a type in Returns for every field it carries
(see Response types). {ws} is a workspace id. List
methods return the records already unwrapped from {"items": [...]}.
Names work everywhere. A workspace, detector, guardrail, policy or virtual
key argument takes its id, its name, or its record. Detector, guardrail and
policy names are unique in a workspace (8.0.2 refuses a duplicate with 409), so
a name is looked up in the method's ws_id (org-wide without one). A detector
name may also be a built-in detector's name or slug (a custom detector sharing
one is refused as ambiguous). Key names are NOT unique:
two keys with one name raise ValueError; a key can also be given by its
faig_... secret. An unknown name raises LookupError.
Session & raw calls
| Method |
HTTP |
Returns |
Notes |
login(username, password) |
POST /api/v1/login |
None |
Optional: the client logs in on its first call. Falls back to the legacy /api/login. |
close() |
POST /api/v1/logout |
None |
Also runs on leaving a with block. |
me() |
GET /api/v1/user |
Me |
The logged-in user: email, role, memberships, ... |
default_workspace() |
GET /api/v1/user, GET /api/v1/me/workspaces (once) |
str | None |
Where a call without ws_id goes: workspace= (or FAIG_WORKSPACE), else a workspace login's only workspace. None for an org admin: admin paths. |
request(method, path, body, params) |
any |
JSON (untyped) |
Raw management call with auth, CSRF and retries. |
get(path, params) |
GET |
JSON (untyped) |
|
post(path, body) |
POST |
JSON (untyped) |
Sends {} when there is no body. |
put(path, body) |
PUT |
JSON (untyped) |
|
patch(path, body) |
PATCH |
JSON (untyped) |
|
delete(path) |
DELETE |
JSON (untyped) |
|
Users & invitations
Workspaces
Every method that takes a workspace (ws_id) accepts its id, its name
(names are unique), or its record from workspaces() / workspace_by_name().
Names are resolved once and cached; an unknown name raises LookupError.
| Method |
HTTP |
Returns |
Notes |
resolve_workspace(ws) |
GET /api/v1/admin/workspaces (or /api/v1/me/workspaces) |
str |
A workspace's id from its id, name or record; cached. |
workspaces() |
GET /api/v1/admin/workspaces |
list[Workspace] |
Every workspace (org admin). |
my_workspaces() |
GET /api/v1/me/workspaces |
list[MyWorkspace] |
Workspaces the caller belongs to. |
workspace_by_name(name) |
GET /api/v1/admin/workspaces |
Workspace | None |
|
create_workspace(name, admin_ids, provider_ids, description) |
POST /api/v1/admin/workspaces |
Workspace |
Admins must be existing users. |
delete_workspace(ws_id) |
DELETE /api/v1/admin/workspaces/{ws} |
None |
|
workspace(ws_id) |
GET /api/v1/workspaces/{ws} |
WorkspaceSettings |
Settings: allowedModels, allowedPolicies, budgets, member defaults. |
workspace_members(ws_id) |
GET /api/v1/workspaces/{ws}/members |
WorkspaceMembers |
|
workspace_budget(ws_id) |
GET /api/v1/workspaces/{ws}/budget |
WorkspaceBudget |
|
workspace_analytics(ws_id, frm, to, limit) |
GET /api/v1/workspaces/{ws}/analytics |
Analytics |
Same as analytics(..., ws_id=). |
Detectors
| Method |
HTTP |
Returns |
Notes |
detectors(ws_id=None) |
GET /api/v1/workspaces/{ws}/detectors or GET /api/v1/admin/detectors |
list[Detector] |
Custom detectors. |
builtin_detectors(ws_id=None) |
GET /api/v1/workspaces/{ws}/built-in-detectors or GET /api/v1/admin/built-in-detectors |
list[BuiltinDetector] |
Identified by slug id. |
detector_by_name(ws_id, name) |
GET /api/v1/workspaces/{ws}/detectors |
Detector | None |
|
create_detector(ws_id, body) |
POST /api/v1/workspaces/{ws}/detectors |
Detector |
Build body with regex_detector_body / dlp_detector_body. |
update_detector(ws_id, uuid, body) |
PUT /api/v1/workspaces/{ws}/detectors/{uuid} |
Detector |
An active detector changes at once. |
delete_detector(uuid, ws_id=None) |
DELETE /api/v1/workspaces/{ws}/detectors/{uuid} or DELETE /api/v1/admin/detectors/{uuid} |
None |
|
playground(text, body, ws_id=None) |
POST /api/v1/workspaces/{ws}/detectors/test or POST /api/v1/admin/detectors/test (builds without it: a regex body is matched locally, checkedLocally) |
DetectorTest |
Scan text with an UNSAVED detector body (the console Playground). |
test_detector(ws_id, uuid, text) |
POST /api/v1/workspaces/{ws}/detectors/{uuid}/test |
DetectorTest |
Scan with a SAVED detector: matched, score, spans. |
resolve_detector(ref, ws_id=None) |
GET .../detectors (+ built-ins, cached) |
str |
A detector's uuid from its uuid, name, slug or record. |
ensure_detector(ws_id, body, approve=True) |
list, then POST or PUT, then approval |
Ensured |
Create, update or leave alone, by body["name"]. Returns Ensured. |
Guardrails
| Method |
HTTP |
Returns |
Notes |
guardrails(ws_id=None) |
GET /api/v1/workspaces/{ws}/guardrails or GET /api/v1/admin/guardrails |
list[Guardrail] |
|
guardrail(gid, ws_id=None) |
GET /api/v1/workspaces/{ws}/guardrails/{id} or GET /api/v1/admin/guardrails/{id} |
Guardrail |
|
guardrail_by_name(ws_id, name) |
as guardrails |
Guardrail | None |
ws_id=None searches org guardrails. |
create_guardrail(ws_id, name, detector_ids, description, deny_suspicious_characters=) |
POST /api/v1/workspaces/{ws}/guardrails |
Guardrail |
Needs at least one detector (ids or names). |
update_guardrail(ws_id, gid, name, detector_ids, description, deny_suspicious_characters=) |
PUT /api/v1/workspaces/{ws}/guardrails/{id} |
Guardrail |
|
delete_guardrail(gid, ws_id=None) |
DELETE /api/v1/workspaces/{ws}/guardrails/{id} or DELETE /api/v1/admin/guardrails/{id} |
None |
|
test_guardrail(text, detector_ids, guardrail_id=, deny_suspicious_characters=, ws_id=) |
POST /api/v1/workspaces/{ws}/guardrails/test or POST /api/v1/admin/guardrails/test (builds without it: one POST .../detectors/{uuid}/test per custom detector; built-ins untested) |
GuardrailTest |
The guardrail tester: scans text without an LLM; finalDisposition plus a result per detector. |
resolve_guardrail(ref, ws_id=None) |
GET .../guardrails |
str |
A guardrail's id from its id, name or record. |
ensure_guardrail(ws_id, name, detector_ids, description, deny_suspicious_characters=, approve=True) |
list, then POST or PUT, then approval |
Ensured |
Returns Ensured. |
Policies
| Method |
HTTP |
Returns |
Notes |
policies(ws_id=None) |
GET /api/v1/workspaces/{ws}/policies or GET /api/v1/admin/policies |
list[Policy] |
|
policy(pid, ws_id=None) |
GET /api/v1/admin/policies/{id} |
Policy |
ws_id scopes a name lookup. |
policy_by_name(ws_id, name) |
as policies |
Policy | None |
|
create_policy(ws_id, name, input_guardrail_ids, output_guardrail_ids, provider_ids=, description=, response_scan_mode=) |
POST /api/v1/workspaces/{ws}/policies |
Policy |
provider_ids grants all of those providers' models; some builds require at least one. |
update_policy(ws_id, pid, name, input_guardrail_ids, output_guardrail_ids, provider_ids=, description=, response_scan_mode=) |
PUT /api/v1/workspaces/{ws}/policies/{id} |
Policy |
By an org admin, an edit to an active policy applies at once. |
delete_policy(pid, ws_id=None) |
DELETE /api/v1/workspaces/{ws}/policies/{id} or DELETE /api/v1/admin/policies/{id} |
None |
|
resolve_policy(ref, ws_id=None) |
GET .../policies |
str |
A policy's id from its id, name or record. |
ensure_policy(ws_id, name, input_guardrail_ids, output_guardrail_ids, provider_ids=, description=, response_scan_mode=, approve=True) |
list, then POST or PUT, then approval |
Ensured |
Guardrails by id or name. Returns Ensured. |
Approval workflow
| Method |
HTTP |
Returns |
Notes |
submit(ws_id, kind, obj_id) |
POST /api/v1/workspaces/{ws}/{kind}/{id}/submit |
Detector | Guardrail | Policy |
kind: detectors, guardrails, policies. |
withdraw(ws_id, kind, obj_id) |
DELETE /api/v1/workspaces/{ws}/{kind}/{id}/pending |
None |
Cancel a pending submission or change. |
approve(kind, obj_id, ws_id=None) |
POST /api/v1/admin/{kind}/{id}/approve |
Detector | Guardrail | Policy |
By name only with ws_id (a name can be pending in several workspaces). |
reject(kind, obj_id, reason, ws_id=None) |
POST /api/v1/admin/{kind}/{id}/reject |
Detector | Guardrail | Policy |
As approve. |
review_queue() |
GET /api/v1/admin/review-queue |
list[ReviewItem] |
Map an item's type with QUEUE_KIND. |
See also approve_new.
Virtual keys
| Method |
HTTP |
Returns |
Notes |
virtual_keys(ws_id=None, status=) |
GET /api/v1/workspaces/{ws}/virtual-keys or GET /api/v1/admin/virtual-keys |
list[VirtualKey] |
|
virtual_key(key_id, ws_id=None) |
GET /api/v1/workspaces/{ws}/virtual-keys/{id} or GET /api/v1/admin/virtual-keys/{id} |
VirtualKey |
Every key call takes ws_id= for the workspace path. |
create_virtual_key(ws_id, name, policy_ids=, provider_ids=, expires_at=, tpm=, rpm=) |
POST /api/v1/workspaces/{ws}/virtual-keys |
NewVirtualKey |
The secret is returned once. |
update_virtual_key(key_id, expires_at=, tpm=, rpm=, policy_ids=, provider_ids=, ws_id=) |
GET + PUT .../virtual-keys/{id} |
VirtualKey |
Resends the record's writable fields with your changes. |
rotate_virtual_key(key_id, ws_id=None) |
POST .../virtual-keys/{id}/rotate |
NewVirtualKey |
New secret, once. |
renew_virtual_key(key_id, expires_in_days=, ws_id=) |
GET, PUT (expired only), then POST .../rotate |
Renewed |
A new secret for the same key: rotates an active key, and extends an expired one first (8.0.2 only rotates an active key). Refuses a revoked or suspended key. |
revoke_virtual_key(key_id, reason, ws_id=None) |
POST .../virtual-keys/{id}/revoke |
VirtualKey |
The secret stops working; a reason is required. |
delete_virtual_key(key_id, ws_id=None) |
DELETE .../virtual-keys/{id} |
None |
|
resolve_virtual_key(ref, ws_id=None) |
GET .../virtual-keys |
str |
A key's id from its id, name, record or faig_... secret. |
ensure_virtual_key(ws_id, name, policy_ids=, provider_ids=, expires_at=, tpm=, rpm=) |
list, then POST or GET + PUT |
Ensured |
Create the active key name (secret in Ensured.secret) or bring it in line. |
Models & what a key can use
Usage, cost & analytics
Dates are date objects or "YYYY-MM-DD"; omitted, the window is the last 30
days. ws_id= switches every call to the workspace path. Values are
checked before sending: by workspace | user | key | model; interval hourly |
daily | weekly | monthly; end top | bottom | both. Read ranking rows with
rank_items(result, end): the API answers items, top/bottom lists, or
only meta when nothing was used.
| Method |
HTTP |
Returns |
Notes |
usage_summary(frm, to, ws_id=) |
GET .../usage/summary |
UsageSummary |
Requests, tokens, previous window, key/user adoption. |
usage_trend(frm, to, interval, ws_id=) |
GET .../usage/trend |
UsageTrend |
points: [{at, requests, tokens}]. |
usage_rankings(frm, to, by, limit, end=, order_by=, interval=, ws_id=) |
GET .../usage/rankings |
Rankings |
order_by: tokens | requests. |
usage_breakdown(by, item_id, frm, to, ws_id=) |
GET .../usage/breakdown |
Breakdown |
A key/user/workspace by model; a model by who used it. Rows: breakdown_items(). 404 for a deleted key. |
cost_summary(frm, to, ws_id=) |
GET .../cost/summary |
CostSummary |
totals.chargebackSpend, volume, unit costs. |
cost_trend(frm, to, interval, ws_id=) |
GET .../cost/trend |
CostTrend |
|
cost_rankings(frm, to, by, limit, end=, order_by=, interval=, ws_id=) |
GET .../cost/rankings |
Rankings |
order_by: providerSpend | chargebackSpend | per1kTokens | perRequest. |
cost_breakdown(by, item_id, frm, to, ws_id=) |
GET .../cost/breakdown |
Breakdown |
As usage_breakdown, with spend. Rows: breakdown_items(). |
analytics(frm, to, limit, ws_id=) |
GET /api/v1/admin/analytics or .../workspaces/{ws}/analytics |
Analytics |
Guardrail violations, severity, trend, scanner latency. |
Traffic & ICAP logs
Time: range= 24h (default) | 7d | month | all, or start=/end=
(datetime or epoch ms). filters= maps a field to a value, a list (is), or
{"operator": "is" | "is not" | "contains" | "does not contain", "value": [...]}.
Unknown fields or operators raise ValueError: the API would silently ignore
them and return every row.
| Method |
HTTP |
Returns |
Notes |
traffic_logs(range=, start=, end=, filters=, max_items=, page_size=, ws_id=) |
GET .../traffic-logs |
Iterator[TrafficLogRow] |
Iterator; follows nextCursor. Filters: verdict, user, workspace, virtual_key, model, traffic_type, request_path. |
traffic_logs_page(cursor, ...) |
GET .../traffic-logs |
TrafficLogPage |
One page with nextCursor, hasNext, total (first page). |
traffic_log(uuid, ws_id=) |
GET .../traffic-logs/{uuid} |
TrafficLog |
Full record: verdict, action, detector, guardrail, policy, prompt, cost, latency. |
traffic_log_filter_options(range=, start=, end=, ws_id=) |
GET .../traffic-logs/filter-options |
TrafficFilterOptions |
Values each filter can take. |
blocked_requests(since=, until=, range=, max_items=, ws_id=) |
GET .../traffic-logs + one GET .../traffic-logs/{uuid} per row + GET .../virtual-keys |
list[BlockedRequest] |
Blocked requests with the prompt, the detectors that fired and why, and the sending key's id, status and owner email (looked up by keyAlias). since alone means since then until now: a poller's last-pull time. |
wait_for_traffic(since, filters=, count=1, timeout=60, interval=2, ws_id=) |
GET .../traffic-logs (polled) |
list[TrafficLogRow] |
Rows land seconds after a request: wait for count rows from since on. TimeoutError otherwise. |
icap_logs(...) |
GET .../icap-logs |
Iterator[dict[str, Any]] |
Iterator (offset paging). Filters: verdict, direction, user, application, fortigate, shadow_ai, inspection. 404 when ICAP is off. |
icap_logs_page(offset, ...) |
GET .../icap-logs |
IcapLogPage |
|
icap_log(uuid, ws_id=) |
GET .../icap-logs/{uuid} |
dict[str, Any] |
|
icap_log_filter_options(...) |
GET .../icap-logs/filter-options |
dict[str, Any] |
|
Audit log & licenses
The audit log takes the same range= / start= / end= and filters= as the
traffic log. Filters: user, role, action, message, workspace; spell actions as
audit_log_filter_options() lists them (Approve, Create, ...).
| Method |
HTTP |
Returns |
Notes |
iter_audit_logs(range=, start=, end=, filters=, max_items=, page_size=, ws_id=) |
GET .../audit-logs |
Iterator[AuditLogRow] |
Iterator; follows nextCursor. |
audit_logs_page(cursor, ...) |
GET .../audit-logs |
AuditLogPage |
One page. |
audit_logs(offset, limit) |
GET /api/v1/admin/audit-logs |
AuditLogPage |
One page by offset, no filters. |
audit_log_filter_options(range=, start=, end=, ws_id=) |
GET .../audit-logs/filter-options |
AuditFilterOptions |
Users, roles, actions, workspaces seen. |
licenses() |
GET /api/v1/licenses |
Licenses |
Serial, status, end date, GPU mapping. |
Gateway (data plane)
Authenticated with a virtual key secret, never the session.
| Method |
HTTP |
Returns |
Notes |
check_key(api_key) |
GET /ai/openai/v1/models |
KeyCheck |
{"valid", "model_count", "http_status"}. |
available_models(api_key) |
GET /ai/openai/v1/models |
list[str] |
Model names the key may call. A model missing here 404s with "model not available to this API key". |
can_use_model(api_key, model) |
GET /ai/openai/v1/models |
bool |
model in available_models(api_key). |
chat_completion(api_key, model, messages, max_tokens=, temperature=, **extra) |
POST /ai/openai/v1/chat/completions |
ChatCompletion |
A guardrail block is a 200; test it with blocked(). A model the key lacks raises ModelNotAvailable. |
chat_completion_stream(api_key, model, messages, max_tokens=, temperature=, **extra) |
POST /ai/openai/v1/chat/completions (stream: true) |
Iterator[dict[str, Any]] |
Yields chunks; a block arrives as a content_filter chunk. collect_stream() joins them. |