Xelurel AI Documentation
Xelurel AI is a governance layer for AI output. It sits between your AI model and your end users — assessing every output against your policy, enforcing human review where required, and logging every decision immutably for compliance and audit.
You send Xelurel AI your AI's output. Xelurel AI returns a decision: allow review block. Every decision is logged with a unique ID, risk score, triggered rules, and an immutable audit trail.
Quickstart
Get a governance decision on your first AI output in under 5 minutes.
test for development. Keys are prefixed xel_test_ for sandbox and xel_live_ for production.npm install @xelurelai/sdk) or send a raw HTTP POST to /api/v1/assess with your API key in the x-api-key header. See examples below.decision field: allow, review, or block. Route your output accordingly — show it, hold it for human review, or suppress it entirely.decision_id alongside your record. This is your audit receipt — it permanently links your output to the governance decision that governed it.SDK (recommended)
cURL
Response
Authentication
All API requests require an API key in the x-api-key request header. Keys are tenant-scoped — all activity is isolated to your workspace.
Key environments
| Prefix | Environment | Behaviour |
|---|---|---|
xel_test_ | sandbox | Full functionality. Decisions logged. Safe for development, staging, and integration testing. |
xel_live_ | production | Full functionality. Use for any production or patient-facing workflows. |
/api/v1/assess must originate from your backend server — never directly from a browser, mobile app, or public script.API Key Management
API keys are managed through the Xelurel AI dashboard. Each key is scoped to your tenant and can be independently labelled, rotated, and revoked.
Creating a key
Key security practices
| Practice | Detail |
|---|---|
| Use separate keys per environment | Never use a live key in development. Keep test and production keys strictly separated. |
| Store in environment variables | Never hardcode keys in source code. Use process.env.XELURELAI_API_KEY or your secrets manager. |
| Rotate on suspected compromise | Revoke the key immediately from the dashboard and create a replacement. Revocation is instant. |
| Label keys meaningfully | Use labels like prod-backend-v2 so you can identify and revoke specific keys without disruption. |
POST /api/v1/assess
The core endpoint. Send your AI's generated output and receive a governance decision.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | required | The input sent to your AI model. Max 50,000 characters. Used for semantic overlap checks and logged as a hash. |
| output | string | required | The AI-generated output to assess. Max 50,000 characters. This is the content that will reach your user if allowed. |
| use_case | string | optional | Content type for policy and threshold selection. Defaults to general. See . |
| model | string | optional | The model name that generated the output (e.g. "gpt-4o", "claude-3-5-sonnet"). Logged for audit purposes only. |
| context | object | optional | Additional metadata. Can include session_id, patient_id, or any key-value pairs. Not stored in raw form. |
| policy_id | string | optional | Override the auto-selected policy for this assessment. Useful for multi-policy tenants. |
Response
| Field | Type | Description |
|---|---|---|
| decision_id | string (uuid) | Unique identifier for this governance decision. Store this — it is your audit receipt. |
| tenant_id | string | Your tenant identifier. |
| decision | string | The governance decision: allow, review, or block. |
| risk_score | integer (0–100) | Aggregate risk score normalised to 0–100. Suitable for display. |
| risk_score_normalized | float (0.0–1.0) | Raw risk score. Used for threshold comparisons. Matches policy threshold values directly. |
| reasons | string[] | Human-readable list of rules that triggered. Show these to reviewers — they explain why the decision was made. |
| policy_id | string | The policy that governed this assessment. |
| policy_version | string | The exact policy version applied. Immutably linked to this decision record. |
| api_key_env | string | test or live, matching the key used. |
Decision States
Every assessment returns one of three decisions. Your integration must handle all three — never assume only allow will be returned.
| Decision | risk_score_normalized | Meaning | Required action |
|---|---|---|---|
| allow | 0.00 – 0.30 | Output passed all policy rules within acceptable thresholds. | Safe to deliver to end user. Store the decision_id on your record. |
| review | 0.31 – 0.69 | Output triggered one or more risk rules. Requires a human decision before delivery. | Do not auto-publish. Hold the output and route to your human review queue. Record reviewer action. |
| block | 0.70 – 1.00 | Output triggered high-weight rules. Risk exceeds automatic review threshold. | Suppress the output entirely. Inform the user that manual input is required. Log the decision_id regardless. |
review decision. The entire compliance value of Xelurel AI is that review decisions require a human to approve, edit, or reject them. Auto-publishing defeats the audit trail and removes the human accountability the system is designed to prove.Risk Scoring
The risk score is an aggregate of all rules that triggered during assessment. Each rule in your active policy carries a weight between 0 and 1. When a rule triggers, its weight is added to the running score. The final score is capped at 1.0 before thresholds are applied.
The response returns two representations: risk_score (0–100, integer, for display) and risk_score_normalized (0.0–1.0, float, matches policy threshold values directly).
Rate Limits
Xelurel AI enforces three independent rate limits on /api/v1/assess. All three must pass for the request to proceed. When a limit is exceeded, the API returns 429 with a Retry-After header.
Handling 429 responses
JavaScript SDK
The official SDK wraps the assess API with typed responses, automatic error handling, and retry-after support. Zero dependencies — works in Node.js 18+ and modern bundlers.
Installation
Initialisation
client.assess(params)
| Param | Type | Required | Description |
|---|---|---|---|
| prompt | string | required | The input sent to your AI model. |
| output | string | required | The AI-generated text to evaluate. |
| use_case | string | optional | Use-case hint for policy routing. e.g. medical_note, legal_draft. |
| policy_id | string | optional | Override the policy to evaluate against. |
| model | string | optional | Model name — logged for audit, not used in scoring. |
Full usage example
Static helpers
| Method | Returns | Description |
|---|---|---|
XelurelAI.isAllowed(result) | boolean | True when decision === "allow". Safe to deliver output. |
XelurelAI.needsReview(result) | boolean | True when decision === "review". Route to human review queue. |
XelurelAI.isBlocked(result) | boolean | True when decision === "block". Suppress output entirely. |
XelurelAIError
All API errors throw a XelurelAIError with the following properties:
| Property | Type | Description |
|---|---|---|
message | string | Human-readable error description. |
status | number | null | HTTP status code, if the request reached the server. |
code | string | null | Machine-readable code: rate_limited, timeout, network_error. |
retryAfterMs | number | null | Set on rate_limited — milliseconds to wait before retrying. |
import) with a CommonJS wrapper (require) for legacy Node.js projects. TypeScript types are bundled — no @types/ package needed.Node.js / TypeScript
Standard integration pattern for any AI pipeline that produces text output before delivery to a user.
Using the SDK
Raw fetch (no SDK)
Python
Handling Decisions in Your UI
What your user-facing interface should do for each decision state.
allow — deliver the output
review — hold and route to reviewer
block — suppress and prompt manual input
decision_id on your underlying record — even for allow decisions. This links every output to the governance decision that permitted it. Your audit trail requires this.Use Case Types
The use_case field tells Xelurel AI what kind of content it is assessing. Different use cases apply different policy thresholds — clinical content uses stricter thresholds than general content.
| use_case value | Policy applied | Notes |
|---|---|---|
| medical_note | healthcare_default | SOAP notes, visit summaries, clinical documentation. Strictest thresholds — dosage, diagnosis language, allergy flags all apply. |
| discharge_summary | healthcare_default | Discharge documentation. Same policy as medical_note. |
| patient_instructions | healthcare_default | Patient-facing instructions. Dosage and allergy rules apply. |
| legal_draft | law_default | Legal documents and contract analysis. Flags definitive advice language and privileged terms. |
| general | general_default | Default fallback. Standard thresholds. Appropriate when no specific use case applies. |
How Policies Work
A policy is a versioned set of rules and thresholds that governs how AI outputs are assessed. Every tenant has their own isolated policies. Every assessment records the exact policy version that was active — the audit trail is immutable even when policies change.
Policies use semantic versioning (1.0.0, 1.0.1, etc.). You work in a draft version that you can edit freely, then publish it as a new immutable version. Past decisions remain permanently linked to the version that governed them.
Policy lifecycle
draft version — changes do not affect live assessments until you publish.Rule Types
Each policy contains an array of rules. When a rule triggers, its weight is added to the risk score. Rules are evaluated in order with an early exit once the block threshold is exceeded.
min characters. Catches suspiciously short or empty outputs that may indicate a model failure.minOverlap. Catches outputs that do not appear to address their prompt.Rule targets
| target | Description |
|---|---|
| output | Evaluate the rule against the AI-generated output only. Most rules should target output. |
| prompt | Evaluate against the input prompt only. Useful for detecting sensitive query patterns. |
| prompt_output | Evaluate against the concatenation of prompt and output. Used for overlap and relevance checks. |
Example rule — regex
Example rule — contains_any
(a+)+) to prevent ReDoS attacks. Patterns over 300 characters are rejected. Both checks are enforced at policy save time.Thresholds
Thresholds define the risk_score_normalized (0.0–1.0) boundaries for each decision. You can set policy-wide thresholds and override them for specific use cases.
Dashboard Overview
The Xelurel AI dashboard is your operational interface for governance. It provides real-time visibility into all AI decisions made through your tenant, a policy editor, analytics, and audit export.
Access the dashboard at /dashboard after signing in with your Xelurel AI account.
Decision Log
The decision log is the real-time record of every assessment made through your tenant. Each row represents one call to /api/v1/assess.
What you can see per decision
| Field | Description |
|---|---|
| Decision ID | UUID. The audit receipt stored on your system records. |
| Timestamp | Server-side ISO timestamp. Tamper-evident. |
| Decision | allow review block — the governance outcome. |
| Risk score | Aggregate score at time of assessment (0–100). |
| Reasons | Human-readable list of rules that triggered and why. |
| Rules triggered | Exact rule IDs from your active policy that fired. |
| Policy / version | The exact policy version that governed this decision. |
| API key | Last 4 of the key used — environment (test / live) and label. |
| Use case | The use_case value sent in the request. |
| Model | The client model reported in the request, if provided. |
| Review status | Whether a human reviewer has acted on this decision. |
| Audit events | Full chronological log of every action taken on this decision. |
Review Actions
Decisions with status review can receive human review actions from your team directly in the dashboard. All review actions are appended to the immutable audit log with the reviewer's identity and timestamp.
| Action | Resulting status | When to use |
|---|---|---|
| Approve | allow | Reviewer has examined the output and determined it is safe to deliver. Output can now be sent to the end user. |
| Reject | block | Reviewer has determined the output should not be delivered. Adds reviewer identity and reason to the audit trail. |
| Send for review | review | Escalate to another team member. Decision remains in review status with an audit note. |
Policies in the Dashboard
The Policies tab lets you view and edit your governance configuration without writing code.
Policy list
Your tenant starts with pre-seeded policies based on the industry you selected at registration:
| Policy ID | Industry | Default rules included |
|---|---|---|
| general_default | All | OUTPUT_TOO_SHORT, LOW_SEMANTIC_OVERLAP |
| healthcare_default | Healthcare | DOSAGE_DETECTED, OUTPUT_TOO_SHORT, LOW_SEMANTIC_OVERLAP, ALLERGY_MENTION |
| law_default | Legal | DEFINITIVE_LEGAL_ADVICE, PRIVILEGED_TERMS, OUTPUT_TOO_SHORT, LOW_SEMANTIC_OVERLAP |
Editing a policy
Select a policy and click Edit draft. You can add, remove, and reorder rules, adjust weights and thresholds, and add use-case overrides. All changes are saved to the draft version only — live assessments continue using the published version until you explicitly publish.
Analytics
The Analytics tab provides aggregated governance metrics over a configurable time window (default: 7 days).
| Metric | Description |
|---|---|
| Total decisions | All assessments in the selected window. |
| Decision split | Count and percentage of allow / review / block decisions. |
| Flagged rate | Percentage of decisions that were review or block — a proxy for output risk rate. |
| Top rules | The rules that triggered most frequently — useful for tuning policy weights. |
| Top reasons | Most common human-readable violation reasons, sorted by frequency. |
| Risk trend | Daily risk score trend over the selected window. Useful for detecting model drift or prompt changes. |
Audit Export
Export your complete decision log as CSV or JSON for compliance reporting, external audit, or integration with your SIEM or data warehouse. Export is available from the dashboard and via the API.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tenantId | string | required | Your tenant ID. |
| format | string | optional | csv (default) or json. |
| limit | integer | optional | Max records to return. Default: 2000. Max: 10,000. |
| fromIso | string | optional | ISO 8601 start date filter (inclusive). |
| toIso | string | optional | ISO 8601 end date filter (inclusive). |
| decisionId | string | optional | Export a single decision by ID. Ignores limit/date filters. |
CSV fields exported
Every exported row includes: decision_id, timestamp, use_case, model_used, api_key_env, policy_id, policy_version, decision, reviewed_decision, review_status, reviewed_by, reviewed_at_iso, review_note, risk_score, risk_score_normalized, rules_triggered, reasons, prompt_hash, output_hash, audit_events_count, audit_log.
Request Schema
Response Schema
Errors
All error responses return JSON with an error field describing the problem.
| Status | Error | Cause |
|---|---|---|
| 400 | prompt and output are required | Request body missing prompt or output. |
| 400 | prompt and output must be strings | Non-string value passed for prompt or output. |
| 400 | prompt and output must each be under 50000 characters | Input exceeds the maximum length limit. |
| 401 | missing api key | x-api-key header absent. |
| 401 | invalid api key | Key not found, revoked, or inactive. |
| 429 | rate_limited | Limit exceeded. Respect the Retry-After response header (seconds). |
| 500 | internal server error | Unexpected server error. Retry with exponential backoff. |
Error response shape
Rate limit response shape
Audit Trail
Every call to /api/v1/assess creates an immutable record in Xelurel AI's decision log. Records cannot be modified or deleted. The prompt and output are never stored in raw form — they are stored as HMAC-SHA256 hashes, scoped to your tenant, allowing cryptographic verification without retaining potentially sensitive content.
What is logged per decision
| Field | Description |
|---|---|
| id | UUID. Your audit receipt — store this on every record your system produces. |
| tenantId | Your tenant. All decisions are fully isolated per tenant. |
| promptHash | Tenant-scoped HMAC-SHA256 of the prompt. Proves what context was provided without storing PHI. |
| outputHash | Tenant-scoped HMAC-SHA256 of the output. Proves exactly what was assessed. |
| hashVersion | Hash scheme version, for forward compatibility. |
| decision | allow / review / block — the governance outcome. |
| riskScore | The aggregate score (0–100) at time of assessment. |
| riskScoreNormalized | The raw score (0.0–1.0) used for threshold comparison. |
| reasons | Human-readable rule triggers at time of assessment. |
| rulesTriggered | Rule IDs from your policy that fired. |
| policyId + policyVersion | Exact policy snapshot that governed this decision. Permanently linked. |
| engineVersion | Assessment engine used (policy_v1 or assess_v1 fallback). |
| apiKeyId / apiKeyLast4 | Which key was used. Last 4 characters only — the full key is never stored. |
| clientModel | Model name reported by the caller, if provided. |
| createdAt | Server-side timestamp. Set by Firestore — cannot be spoofed by the caller. |
| reviewStatus | Current review state: null, approved, rejected, or sent_for_review. |
| reviewedBy / reviewedByEmail | Identity of the reviewer who acted on this decision. |
| reviewedAtIso | ISO timestamp of the review action. |
| reviewNote | Optional note the reviewer attached to their action. |
| auditLog | Append-only array of every event on this decision — assessment, review actions, escalations. Capped at 200 entries. |