Skip to content

Portal search & analytics API

This page documents three related API surface areas: portal global search, the complete analytics dashboard specification, and config changelog enhancements. The portal search endpoint provides full-text search across all entity types — users, groups, models, audit events, DLP rules, and more — with relevance scoring and grouped results. The analytics dashboard endpoint provides the complete specification for aggregated organization usage data, extending the partial coverage in the avatar and analytics reference. The config changelog section documents new resource types and response fields added in recent sprints.

Base URL: https://api.arbitex.ai


The portal search endpoint indexes all major entity types in real time. Search is full-text across a defined set of fields per entity type. Results are grouped by entity type, sorted by relevance score within each group, and returned in a single response. The endpoint is suitable for powering a global search bar in the admin UI, as well as for programmatic entity discovery.

Method Path Auth Description
GET /v1/portal/search Bearer token or Admin API key Full-text search across all portal entity types

Full-text search across all portal entity types. Returns results grouped by entity type with relevance scoring. Entity types not matched by the query are omitted from the response.

Authentication: Bearer token (org-scoped JWT) or Admin API key. The search scope is implicitly restricted to the caller’s organization. Multi-tenant administrators who supply an explicit org_id can search across organizations, subject to their cross-org permission grants.

Parameter Type Required Default Description
q string Yes Search query. Minimum 2 characters.
types string No all Comma-separated entity types to search. Valid values: users, groups, models, conversations, audit_events, dlp_rules, policy_rules, api_keys, webhooks, organizations.
limit integer No 20 Maximum results per entity type (1–50).
offset integer No 0 Pagination offset applied per entity type.
org_id string (UUID) No from token Organization scope. Multi-tenant admins can override to search within a specific organization.
Terminal window
curl -s "https://api.arbitex.ai/v1/portal/search?q=john&types=users,groups&limit=10" \
-H "Authorization: Bearer $TOKEN"
{
"query": "john",
"total_results": 15,
"results": {
"users": {
"count": 12,
"items": [
{
"id": "usr_01HZ_JOHN",
"type": "user",
"title": "John Smith",
"subtitle": "[email protected]",
"matched_fields": ["display_name", "email"],
"score": 0.95,
"url": "/admin/users/usr_01HZ_JOHN",
"metadata": {
"status": "active",
"role": "member",
"last_active": "2026-03-14T12:00:00Z"
}
}
],
"has_more": true
},
"groups": {
"count": 3,
"items": [
{
"id": "grp_01HZ_ENG",
"type": "group",
"title": "Engineering",
"subtitle": "12 members",
"matched_fields": ["member_names"],
"score": 0.72,
"url": "/admin/groups/grp_01HZ_ENG",
"metadata": {
"member_count": 12,
"policy_count": 3
}
}
],
"has_more": false
}
},
"search_duration_ms": 42
}
Field Type Description
query string Echo of the search query as submitted
total_results integer Total match count across all entity types
results object Map of entity type name → result set. Only types with at least one match are included.
results.{type}.count integer Total matches found for this entity type (may exceed limit)
results.{type}.items array Matching items up to the requested limit
results.{type}.items[].id string Entity identifier
results.{type}.items[].type string Entity type name (e.g., "user", "group")
results.{type}.items[].title string Primary display text (e.g., display name, rule name)
results.{type}.items[].subtitle string Secondary display text (e.g., email address, member count)
results.{type}.items[].matched_fields array Fields that contributed to the match for this item
results.{type}.items[].score number Relevance score from 0.0 (weakest) to 1.0 (strongest)
results.{type}.items[].url string Portal path to the entity detail page, suitable for navigation
results.{type}.items[].metadata object Entity-type-specific supplemental fields (see per-type details below)
results.{type}.has_more boolean true if the total count for this entity type exceeds the requested limit
search_duration_ms integer Server-side search execution time in milliseconds
Entity Type Searchable Fields
users display_name, email, username, external_id
groups name, description, member_names
models name, provider, model_id, description
conversations title, participant_names
audit_events actor_email, action, resource_type, ip_address
dlp_rules name, description, pattern
policy_rules name, description, condition_summary
api_keys name, prefix (last 4 characters only — full key values are never indexed)
webhooks name, url, event_types
organizations name, domain, plan_tier

The metadata object varies by entity type. Common fields:

Entity Type Metadata Fields
users status, role, last_active
groups member_count, policy_count
models provider, status, request_count_30d
conversations participant_count, message_count, created_at
audit_events severity, outcome, occurred_at
dlp_rules enabled, trigger_count_30d, action
policy_rules enabled, priority, condition_count
api_keys status, last_used, scopes
webhooks enabled, delivery_success_rate, last_triggered
organizations plan_tier, user_count, created_at
Status Code Description
400 query_too_short Query string is fewer than 2 characters
400 invalid_type One or more values in the types parameter are not recognized entity type names
401 unauthorized Missing or invalid authentication credential
403 forbidden Caller lacks permission to search the requested organization scope
429 rate_limited Search rate limit exceeded — 60 requests per minute per user

Rate limiting: 60 requests per minute per authenticated user. Search queries are logged in the audit trail with the query string redacted after 90 days. The q parameter is never logged in plaintext in long-term storage.


The analytics dashboard endpoint provides the full aggregated usage payload for an organization. This section documents the complete specification — including all query parameters, response fields, auto-granularity rules, and CSV export format. An earlier partial reference appears in the avatar and analytics API page; this section supersedes that coverage and adds the start_date/end_date custom range, the include filter, and the format=csv export option.

Method Path Auth Description
GET /v1/orgs/{org_id}/analytics/dashboard Bearer token with analytics:read, or Admin API key Retrieve aggregated analytics for an organization

Retrieve the analytics dashboard payload for an organization. Results cover the requested time period and are returned as a snapshot computed at request time. Responses are not cached server-side — callers should implement their own caching layer when polling this endpoint at high frequency.

Authentication: Bearer token (org-scoped JWT) with analytics:read permission, or Admin API key scoped to the target organization.

Parameter Type Description
org_id string (UUID) Organization identifier
Parameter Type Required Default Description
period string No 30d Predefined time window: 7d, 30d, 90d, or custom. When custom, both start_date and end_date are required.
start_date string (ISO 8601) Conditional Start of the custom date range (inclusive). Required when period=custom.
end_date string (ISO 8601) Conditional End of the custom date range (inclusive). Required when period=custom. Maximum range: 365 days.
granularity string No auto Data point interval for usage_over_time: hourly, daily, weekly, or monthly. When auto, the server selects an appropriate interval based on the period (see table below).
include string No all Comma-separated list of response sections to include: summary, usage_over_time, token_distribution, top_models, top_users, dlp_summary. Omitting a section reduces response payload size.
format string No json Response format: json or csv. When csv, the response is a flattened tabular export rather than JSON.

When granularity=auto (the default), the server selects an interval according to the period:

Period Default Granularity Approximate Data Points
7d hourly ~168
30d daily 30
90d daily 90
custom, range ≤ 7 days hourly varies
custom, range 8–90 days daily varies
custom, range 91–365 days weekly varies
Terminal window
curl -s "https://api.arbitex.ai/v1/orgs/org_01HZ_ACME/analytics/dashboard?period=30d&include=summary,top_models" \
-H "Authorization: Bearer $TOKEN"
{
"org_id": "org_01HZ_ACME",
"period": "30d",
"granularity": "daily",
"generated_at": "2026-03-14T12:00:00Z",
"summary": {
"total_requests": 284102,
"total_input_tokens": 31204819,
"total_output_tokens": 21636204,
"estimated_cost_usd": 1847.32,
"active_users": 142,
"period_start": "2026-02-12T00:00:00Z",
"period_end": "2026-03-13T23:59:59Z"
},
"usage_over_time": [
{
"date": "2026-02-12",
"requests": 9102,
"input_tokens": 1050341,
"output_tokens": 843506,
"cost_usd": 62.14
},
{
"date": "2026-02-13",
"requests": 8794,
"input_tokens": 1020183,
"output_tokens": 801247,
"cost_usd": 60.02
},
{
"date": "2026-03-13",
"requests": 9470,
"input_tokens": 1098324,
"output_tokens": 863043,
"cost_usd": 65.77
}
],
"token_distribution": [
{
"model": "gpt-4o",
"input_tokens": 10823401,
"output_tokens": 7491023,
"total_tokens": 18314424
},
{
"model": "claude-opus-4-6",
"input_tokens": 8934102,
"output_tokens": 6892341,
"total_tokens": 15826443
},
{
"model": "claude-sonnet-4-6",
"input_tokens": 6201047,
"output_tokens": 4730219,
"total_tokens": 10931266
}
],
"top_models": [
{
"model": "gpt-4o",
"provider": "openai",
"requests": 98432,
"tokens": 18314424,
"cost_usd": 641.50,
"percentage": 34.6
},
{
"model": "claude-opus-4-6",
"provider": "anthropic",
"requests": 61203,
"tokens": 15826443,
"cost_usd": 554.03,
"percentage": 21.5
},
{
"model": "claude-sonnet-4-6",
"provider": "anthropic",
"requests": 54901,
"tokens": 10931266,
"cost_usd": 382.59,
"percentage": 19.3
}
],
"top_users": [
{
"user_id": "usr_01HZ_JANE",
"display_name": "Jane Doe",
"email": "[email protected]",
"requests": 4521,
"tokens": 892341,
"cost_usd": 31.23
},
{
"user_id": "usr_01HZ_BOB",
"display_name": "Bob Smith",
"email": "[email protected]",
"requests": 3874,
"tokens": 741209,
"cost_usd": 25.94
},
{
"user_id": "usr_01HZ_ALICE",
"display_name": "Alice Chen",
"email": "[email protected]",
"requests": 3102,
"tokens": 618432,
"cost_usd": 21.65
}
],
"dlp_summary": {
"total_scanned": 284102,
"allowed": 282232,
"redacted": 412,
"blocked": 1458,
"by_rule": [
{
"rule_id": "dlp_01HZ_CC",
"rule_name": "Credit Card Numbers",
"triggers": 687
},
{
"rule_id": "dlp_01HZ_SSN",
"rule_name": "Social Security Numbers",
"triggers": 412
},
{
"rule_id": "dlp_01HZ_APIKEY",
"rule_name": "API Key Detection",
"triggers": 359
}
]
}
}

Top-level fields

Field Type Description
org_id string Organization UUID echoed from the path
period string Resolved period identifier (7d, 30d, 90d, or custom)
granularity string Resolved time-series interval used for usage_over_time
generated_at string (ISO 8601) Timestamp when the snapshot was computed, UTC
summary object Aggregate totals for the full period — present unless excluded via include
usage_over_time array Time-series data points at the resolved granularity
token_distribution array Token volume breakdown by model
top_models array Models ranked by request count, descending
top_users array Top 10 users by request count, descending
dlp_summary object DLP activity totals and per-rule trigger counts

summary object

Field Type Description
total_requests integer Total gateway requests in the period
total_input_tokens integer Total prompt tokens consumed across all models
total_output_tokens integer Total completion tokens generated across all models
estimated_cost_usd number Estimated spend in USD, computed using the per-model pricing table at generation time
active_users integer Count of distinct users who made at least one request in the period
period_start string (ISO 8601) Actual start timestamp of the report window, UTC
period_end string (ISO 8601) Actual end timestamp of the report window, UTC

usage_over_time array items

Field Type Description
date string ISO 8601 date or datetime representing the start of the bucket
requests integer Request count in this time bucket
input_tokens integer Prompt token count in this bucket
output_tokens integer Completion token count in this bucket
cost_usd number Estimated spend in USD for this bucket

token_distribution array items

Field Type Description
model string Model identifier
input_tokens integer Total prompt tokens for this model in the period
output_tokens integer Total completion tokens for this model in the period
total_tokens integer Sum of input and output tokens

top_models array items

Field Type Description
model string Model identifier as submitted in gateway requests
provider string Model provider (e.g., "openai", "anthropic", "google")
requests integer Request count for this model in the period
tokens integer Total tokens consumed by this model
cost_usd number Estimated spend attributable to this model
percentage number Share of total requests, expressed as a percentage

top_users array items (top 10, ordered by request count descending)

Field Type Description
user_id string User UUID
display_name string User display name at snapshot generation time
email string User email address
requests integer Request count for this user in the period
tokens integer Total tokens consumed by this user
cost_usd number Estimated spend attributable to this user

dlp_summary object

Field Type Description
total_scanned integer Total content segments evaluated by the DLP pipeline
allowed integer Segments that passed DLP inspection without modification
redacted integer Segments where one or more sensitive fields were redacted before forwarding
blocked integer Requests blocked entirely due to a DLP policy match
by_rule array Per-rule trigger counts, ordered by trigger count descending
by_rule[].rule_id string DLP rule identifier
by_rule[].rule_name string DLP rule display name
by_rule[].triggers integer Number of times this rule triggered in the period

When format=csv is specified, the response body is text/csv rather than JSON. The CSV export is a flattened representation of the requested include sections. Because the response contains multiple logical tables, the CSV uses a section-per-block structure with blank lines between sections and a #section header comment on each:

#section: summary
period_start,period_end,total_requests,total_input_tokens,total_output_tokens,estimated_cost_usd,active_users
2026-02-12T00:00:00Z,2026-03-13T23:59:59Z,284102,31204819,21636204,1847.32,142
#section: usage_over_time
date,requests,input_tokens,output_tokens,cost_usd
2026-02-12,9102,1050341,843506,62.14
2026-02-13,8794,1020183,801247,60.02
#section: top_models
model,provider,requests,tokens,cost_usd,percentage
gpt-4o,openai,98432,18314424,641.50,34.6
claude-opus-4-6,anthropic,61203,15826443,554.03,21.5
#section: top_users
user_id,display_name,email,requests,tokens,cost_usd
usr_01HZ_JANE,Jane Doe,[email protected],4521,892341,31.23
#section: dlp_summary
rule_id,rule_name,triggers,total_scanned,allowed,redacted,blocked
dlp_01HZ_CC,Credit Card Numbers,687,284102,282232,412,1458
dlp_01HZ_SSN,Social Security Numbers,412,284102,282232,412,1458

The summary section always emits a single data row. The usage_over_time, top_models, top_users, and dlp_summary sections emit one row per entity. DLP per-rule rows repeat the aggregate totals (total_scanned, allowed, redacted, blocked) for convenience when consuming the CSV in tools that do not support multi-table formats.

Status Description
400 Invalid query parameter value — unrecognized period, granularity, or format; missing start_date or end_date when period=custom; custom date range exceeds 365 days
403 Caller does not have analytics:read permission for this organization
404 Organization not found

The config changelog endpoint (GET /api/v1/admin/config/changelog) was first documented in the security and admin API reference. This section documents new resource types and response fields added in recent sprints. All query and pagination parameters from the base specification apply unchanged.

The following resource types are now indexed in the changelog as of sprint docs-0058:

Resource Type Added In Description
analytics_dashboard docs-0058 Dashboard configuration changes — period defaults, auto-refresh interval, visible sections
search_config docs-0058 Portal search configuration — enabled entity types, per-type index settings, minimum query length
theme_config docs-0058 Organization theme and branding changes — logo, color scheme, custom CSS
compliance_pack docs-0058 Compliance policy pack enable, disable, or modify operations

The following fields are present on all changelog entries returned by the updated endpoint. Older entries created before docs-0058 will return null for these fields.

Field Type Description
change.impact_level string Estimated blast radius of the change: low, medium, high, or critical. Computed heuristically based on resource type and the scope of fields modified.
change.requires_restart boolean Whether the configuration change requires a service restart to take effect. Most changes are applied live; this flag is true only for a small set of infrastructure-level settings.
change.rollback_available boolean Whether one-click rollback is supported for this change. Rollback is available for all resource types listed in this section, as well as for policy_rule, dlp_rule, and webhook changes.
change.related_changes array of strings IDs of other changelog entries that were submitted as part of the same batch operation. Empty array if the change was made individually.

Filter by resource type and impact level:

Terminal window
curl -s "https://api.arbitex.ai/api/v1/admin/config/changelog?resource_type=compliance_pack&impact_level=high&limit=20" \
-H "X-API-Key: arb_your_admin_api_key"
{
"entries": [
{
"id": "chg_01HZ_COMPPACK_001",
"resource_type": "compliance_pack",
"resource_id": "pack_01HZ_HIPAA",
"resource_name": "HIPAA Compliance Pack",
"action": "enabled",
"actor": {
"user_id": "usr_01HZ_ADMIN",
"display_name": "Platform Admin",
"email": "[email protected]"
},
"occurred_at": "2026-03-14T09:22:11Z",
"change": {
"before": {
"enabled": false
},
"after": {
"enabled": true
},
"impact_level": "high",
"requires_restart": false,
"rollback_available": true,
"related_changes": [
"chg_01HZ_COMPPACK_002",
"chg_01HZ_COMPPACK_003"
]
},
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 ArbitexPortal/2.4.1"
},
{
"id": "chg_01HZ_SRCHCFG_001",
"resource_type": "search_config",
"resource_id": "srch_01HZ_ACME",
"resource_name": "Portal Search Configuration",
"action": "updated",
"actor": {
"user_id": "usr_01HZ_ADMIN",
"display_name": "Platform Admin",
"email": "[email protected]"
},
"occurred_at": "2026-03-14T09:20:05Z",
"change": {
"before": {
"enabled_types": ["users", "groups", "models"],
"min_query_length": 2
},
"after": {
"enabled_types": ["users", "groups", "models", "audit_events", "dlp_rules"],
"min_query_length": 2
},
"impact_level": "low",
"requires_restart": false,
"rollback_available": true,
"related_changes": []
},
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 ArbitexPortal/2.4.1"
}
],
"total": 2,
"has_more": false
}

The changelog endpoint now accepts an additional filter parameter:

Parameter Type Required Default Description
impact_level string No Filter entries to a specific impact level: low, medium, high, or critical.

This parameter can be combined with all existing filters documented in the security and admin API reference (resource_type, actor_id, start_date, end_date, limit, offset).