Documentation Index
Fetch the complete documentation index at: https://docs.visiqlabs.com/llms.txt
Use this file to discover all available pages before exploring further.
All RECALL endpoints are mounted under /recall/*. The base URL is https://api.visiq.ai.
Authentication
RECALL uses two authentication schemes depending on the endpoint:
- SDK endpoints — API key authentication via
Authorization: Bearer <api_key>. The API key is the rk_live_... / recall_... key associated with your agent.
- Admin endpoints — Session authentication via a vendor session token. Used for managing rules, reviewing the audit log, and retrieving receipts.
All endpoints under /recall/* require authentication. Requests without a valid credential receive 401 Unauthorized.
SDK Endpoints
These endpoints are called directly by the RECALL SDK.
POST /recall/evaluate
Evaluate an agent’s access request against the vendor’s RECALL suppression rules and return a decision with a cryptographic receipt. This is the core suppression endpoint.
The SDK primarily evaluates rules locally from the cached WASM bundle — this endpoint is the fallback when no local bundle is available, and is also used to generate server-side cryptographic receipts.
Authentication: Bearer API key (Authorization: Bearer rk_live_...)
Request body:
{
"agent_id": "research-bot",
"operation": "retrieve",
"resource_type": "document",
"resource_metadata": {
"classification": "confidential",
"department": "finance"
},
"trust_tier": "tier2",
"surface": "INTERNAL_CHANNEL",
"query": "quarterly revenue figures"
}
| Field | Type | Required | Description |
|---|
agent_id | string | Yes | Identifier of the agent making the retrieval request (max 255 chars) |
operation | string | Yes | retrieve, tool_call, or prompt_render |
resource_type | string | No | Resource type being accessed. Default: document (max 255 chars) |
resource_metadata | object | No | Arbitrary metadata about the resource (classification, department, etc.). Default: {} |
trust_tier | string | No | Agent’s trust tier (e.g. tier1, tier2, tier3). Max 50 chars |
surface | string | No | Communication surface where the output will be delivered. Max 100 chars |
query | string | No | The retrieval query string. Max 2000 chars |
Response:
{
"decision_id": "550e8400-e29b-41d4-a716-446655440000",
"decision": "redact",
"reason_code": "POLICY_ALLOW",
"reason": "tier2 confidential redaction",
"receipt_id": "660e8400-e29b-41d4-a716-446655440001"
}
| Field | Type | Description |
|---|
decision_id | string (UUID) | Unique ID for this decision, used for audit and receipt lookup |
decision | string | allow, deny, redact, or escalate |
reason_code | string | Machine-readable reason: TIER_MISMATCH, PRINCIPAL_EXCLUDED, POLICY_DENY, AUDIENCE_EXPANSION, SURFACE_RESTRICTION, POLICY_ALLOW, DEFAULT_DENY, EMERGENCY_BYPASS |
reason | string | Human-readable explanation of the decision |
receipt_id | string (UUID) | ID of the cryptographic receipt for this decision |
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 500 Internal Server Error
Example curl:
curl -X POST https://api.visiq.ai/recall/evaluate \
-H "Authorization: Bearer rk_live_..." \
-H "Content-Type: application/json" \
-d '{
"agent_id": "research-bot",
"operation": "retrieve",
"resource_type": "document",
"resource_metadata": { "classification": "confidential" },
"trust_tier": "tier2"
}'
Admin Endpoints
These endpoints require session authentication and are used for managing your RECALL configuration, reviewing decisions, and retrieving receipts.
Rules
GET /recall/rules
List suppression rules for the authenticated vendor, paginated. Rules are ordered by priority descending.
Query parameters: page (default 1), limit (default 50, max 100)
Response:
{
"data": [
{
"id": "rule-uuid",
"name": "Deny tier3 from confidential",
"description": "Prevent tier3 agents from accessing sensitive data",
"natural_language": "Deny tier3 agents from internal, confidential, or restricted data",
"priority": 50,
"enabled": true,
"trust_tier": "tier3",
"surface": null,
"principal_exclusions": null,
"created_at": "2026-04-13T10:00:00Z",
"updated_at": "2026-04-13T10:00:00Z"
}
],
"total": 8,
"page": 1,
"pageSize": 50
}
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 500 Internal Server Error
Example curl:
curl -X GET 'https://api.visiq.ai/recall/rules?page=1&limit=20' \
-H "Authorization: Bearer <session_token>"
POST /recall/rules
Create a new suppression rule.
Request body:
{
"name": "Deny tier3 from confidential",
"description": "Prevent tier3 agents from accessing sensitive data",
"rego_source": "package recall.evaluate\n\nimport rego.v1\n\ndefault decision := {\"action\": \"deny\", \"reason_code\": \"DEFAULT_DENY\", \"reason\": \"no matching rule\"}\n\ndecision := result if {\n input.trust_tier == \"tier3\"\n input.resource_metadata.classification in {\"internal\", \"confidential\", \"restricted\"}\n result := {\"action\": \"deny\", \"reason_code\": \"TIER_MISMATCH\", \"reason\": \"tier3 restricted to public data\"}\n}",
"natural_language": "Deny tier3 agents from accessing internal, confidential, or restricted data",
"priority": 50,
"enabled": true,
"trust_tier": "tier3",
"surface": null,
"principal_exclusions": null
}
| Field | Type | Required | Description |
|---|
name | string | Yes | Rule name (max 255 chars) |
description | string | No | Description (max 1000 chars) |
rego_source | string | Yes | OPA/Rego policy source code |
natural_language | string | No | Natural language description (max 2000 chars) |
priority | number | No | Evaluation priority. Default 0 |
enabled | boolean | No | Whether the rule is active. Default true |
trust_tier | string | No | Trust tier this rule applies to (max 50 chars) |
surface | string | No | Communication surface restriction (max 100 chars) |
principal_exclusions | string[] | No | Agent IDs excluded from this rule |
Response: The created rule object including rego_source.
Status codes: 201 Created, 400 Bad Request, 401 Unauthorized, 500 Internal Server Error
Example curl:
curl -X POST https://api.visiq.ai/recall/rules \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Deny tier3 from confidential",
"rego_source": "package recall.evaluate\nimport rego.v1\ndefault decision := {\"action\": \"deny\"}",
"priority": 50
}'
GET /recall/rules/:id
Get a single rule by UUID, including rego_source.
Response: Rule object including rego_source.
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error
PUT /recall/rules/:id
Update a rule. Only provided fields are updated. At least one field must be provided.
Request body: Same shape as POST /recall/rules but all fields optional.
Response: Updated rule object.
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error
DELETE /recall/rules/:id
Delete a rule permanently.
Response:
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error
POST /recall/rules/compile
Compile a natural language description into an OPA/Rego suppression rule using AI. The agent reads your existing rules for context, drafts the Rego source, validates the syntax, and optionally saves the rule to the database.
Supports SSE streaming via ?stream=true or Accept: text/event-stream.
Request body:
{
"prompt": "Deny tier3 agents from accessing any document classified as internal, confidential, or restricted",
"nodeRef": "optional-graph-node-reference"
}
| Field | Type | Required | Description |
|---|
prompt | string | Yes | Plain-English rule description (max 4000 chars) |
nodeRef | string | No | Optional rule graph node reference for context (max 255 chars) |
Response (non-streaming):
{
"rego_source": "package recall.evaluate\n\nimport rego.v1\n\ndefault decision := ...",
"natural_language": "This rule denies tier3 agents from accessing...",
"name": "Compiled RECALL Rule",
"description": "AI-compiled suppression rule",
"suggested_priority": 50
}
Response (streaming, text/event-stream):
data: {"type": "text", "content": "Analyzing your existing rules..."}
data: {"type": "text", "content": "Compiling Rego policy..."}
data: {"type": "done", "result": {"rego_source": "...", "name": "...", "description": "...", "suggested_priority": 50}}
On error during streaming:
data: {"type": "error", "message": "The compiler could not produce a RECALL Rego policy. Please refine your prompt."}
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 422 Unprocessable Entity (AI could not produce a valid rule), 500 Internal Server Error
Example curl:
curl -X POST https://api.visiq.ai/recall/rules/compile \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Allow tier1 and tier2 to access all non-restricted documents, deny tier3 from anything beyond public"
}'
Receipts
GET /recall/receipts/:id
Retrieve a cryptographic receipt by its UUID. The response includes the receipt’s Ed25519 signature, public key, and SHA-256 payload hash, along with the linked decision object.
Path parameter: :id — UUID of the receipt
Response:
{
"id": "receipt-uuid",
"vendor_id": "vendor-uuid",
"decision_id": "decision-uuid",
"signature": "base64-encoded-ed25519-signature",
"public_key": "base64-encoded-ed25519-public-key",
"payload_hash": "hex-encoded-sha256-hash",
"merkle_root": null,
"merkle_proof": null,
"created_at": "2026-04-13T10:30:00Z",
"recall_decisions": {
"id": "decision-uuid",
"agent_id": "research-bot",
"operation": "retrieve",
"resource_type": "document",
"resource_metadata": {
"classification": "confidential",
"department": "finance"
},
"decision": "redact",
"reason_code": "POLICY_ALLOW",
"reason": "tier2 confidential redaction",
"rule_id": "rule-uuid",
"created_at": "2026-04-13T10:30:00Z"
}
}
Status codes: 200 OK, 400 Bad Request (invalid UUID), 401 Unauthorized, 404 Not Found, 500 Internal Server Error
Example curl:
curl -X GET https://api.visiq.ai/recall/receipts/receipt-uuid \
-H "Authorization: Bearer <session_token>"
Audit Log
GET /recall/audit-log
Query the immutable RECALL suppression audit log. All decisions — local and remote, allow and deny — are recorded here. The log is append-only; no writes are accepted via this API.
Query parameters:
| Parameter | Type | Description |
|---|
agent_id | string | Filter by agent logical ID |
operation | string | Filter by operation: retrieve, tool_call, prompt_render |
decision | string | Filter by decision: allow, deny, redact, escalate |
reason_code | string | Filter by reason code: TIER_MISMATCH, PRINCIPAL_EXCLUDED, POLICY_DENY, AUDIENCE_EXPANSION, SURFACE_RESTRICTION, POLICY_ALLOW, DEFAULT_DENY, EMERGENCY_BYPASS |
start_date | ISO 8601 datetime | Lower bound on created_at |
end_date | ISO 8601 datetime | Upper bound on created_at |
page | number | Page index (default 1) |
limit | number | Records per page (default 50, max 100) |
Response:
{
"data": [
{
"id": "audit-entry-uuid",
"agent_id": "research-bot",
"operation": "retrieve",
"resource_type": "document",
"decision": "deny",
"reason_code": "TIER_MISMATCH",
"reason": "tier3 restricted to public data",
"rule_id": "rule-uuid",
"receipt_id": "receipt-uuid",
"metadata": {
"surface": "PUBLIC_CHANNEL",
"trust_tier": "tier3",
"query": "quarterly revenue",
"resource_metadata": { "classification": "confidential" }
},
"created_at": "2026-04-13T10:30:00Z"
}
],
"total": 1247,
"page": 1,
"pageSize": 50
}
Status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 500 Internal Server Error
Example curl:
curl -X GET 'https://api.visiq.ai/recall/audit-log?decision=deny&start_date=2026-04-13T00:00:00Z&limit=20' \
-H "Authorization: Bearer <session_token>"