Skip to main content
Hooks let you plug custom logic into an agent’s runtime pipeline. At defined lifecycle events — when a message arrives, before/after the LLM call, when a file is ingested or about to be uploaded — a hook can inspect, modify, allow or block the payload by calling an external endpoint, a workspace automation, or by evaluating a declarative policy in the browser. Typical uses: PII redaction, toxicity / classification blocking, citation enforcement, file MIME or watermark checks, antivirus scanning, and the client-side file-classification gate (block a document before it ever leaves the browser).
Hooks exist at three levels — agent, org, and platform. They are merged (agent ∪ org ∪ platform). The agent UI manages the agent’s own hooks and shows org/platform hooks as read-only. An org/platform hook can be marked immutable so it always applies and cannot be disabled below.

Lifecycle events

A hook subscribes to one or more events:
EventWhen it firesTypical use
before_uploadIn the browser, before a file is uploadedClient-side file-classification gate (see below)
before_file_ingestServer-side, before a file is ingestedMIME/type allow-list, antivirus, virus scanning
after_file_parseAfter a file has been parsed to textWatermark / sensitivity-marking detection
before_messageBefore a user message enters the pipelinePII redaction, input filtering
before_llmJust before the LLM callPrompt inspection, proxying
after_llmAfter the LLM responseToxicity blocking, citation enforcement, output rewriting

Targets

The target.type decides where the hook runs.

http — call an external endpoint

The hook posts the event payload to a URL and uses the response to allow / modify / block. The endpoint is most often a Builder automation exposed as a webhook, so you stay inside Prisme.ai (RBAC, secrets, audit).
{
  "id": "pii-redact",
  "events": ["before_message"],
  "mode": "sync",
  "target": {
    "type": "http",
    "url": "https://<api>/v2/workspaces/slug:my-ws/webhooks/hook-pii-redact"
  },
  "on_error": "allow",
  "enabled": true
}
You can add custom headers to the request.

workspace — call a workspace automation directly

Reference a Builder automation by slug instead of a full URL.
{
  "target": {
    "type": "workspace",
    "automation_slug": "scan-document",
    "workspace_slug": "my-ws"
  }
}

client — declarative browser policy (file gate)

A client hook is evaluated in the browser against a file’s extracted metadata, before any upload. No external call, no third-party JavaScript — see The client-side file gate. For client targets mode is ignored (it is always a synchronous, in-browser check).

Execution modes

mode controls the server-side timing of http / workspace hooks:
ModeBehavior
syncThe pipeline waits for the hook and uses its decision (allow / deny / modified payload). Use for anything that must block or rewrite.
asyncFire-and-forget — the pipeline does not wait. Use for logging, scanning, analytics. Combine with sample_rate to run it on a fraction of events.
streamThe hook can stream a transformed response (e.g. an LLM proxy).

Behavior controls

FieldDescriptionDefault
enabledTurn the hook on/offtrue
on_errorWhat happens if the hook call fails or times out: allow (fail-open) or deny (fail-closed)allow
expose_reasonSurface the hook’s block reason to the end user (otherwise a generic message)false
rate_limit_per_minMax hook invocations per minute1000
apply_output_guardrailsRe-run the agent’s output guardrails after the hook modified an after_llm responsefalse
payload_modeSend the payload inline or as a reference the endpoint fetchesinline
sample_rateFraction (0–1) of events to run an async hook on1
display_nameHuman-readable label in the UI (falls back to id)
Choose on_error deliberately. For a security control (block forbidden files/content) use on_error: "deny" so a failing or unreachable hook never silently lets the payload through. For a best-effort enrichment use allow.

The client-side file gate

The most common client hook is a file-classification gate: read a document’s metadata locally and reject non-conformant files before they ever leave the browser (e.g. a document classified above the level your SaaS is allowed to process).
{
  "id": "titus-classification-gate",
  "events": ["before_upload"],
  "target": {
    "type": "client",
    "policy": [
      {
        "property": "custom.Classification",
        "operator": "in",
        "allowed": ["C0", "C1"],
        "on_fail": "deny",
        "message": "This document is classified above the allowed level. Upload blocked."
      }
    ]
  },
  "enabled": true
}

Policy rules

Rules are evaluated with AND semantics — the first rule the file does not satisfy whose on_fail is deny blocks the upload.
operatorConforms when…
inthe value is in allowed
not_inthe value is not in allowed (a missing value conforms — fail-open)
equalsthe value equals allowed[0]
existsthe property is present and non-empty
matchesthe value matches one of the allowed regular expressions
in / equals / matches / exists are fail-closed: a missing property fails the rule, so an unmarked document is blocked by a deny rule. not_in is fail-open (nothing to forbid when the property is absent) — pair it with an exists rule to also block unmarked files.

Metadata namespaces

The extractor flattens each file’s metadata into namespaced keys you target with property:
PrefixSourceExamples
file.*Always present (the File object)file.name, file.type, file.size
custom.*Office docProps/custom.xml (where classification tools like TITUS write markings)custom.Classification, custom.TitusGUID
core.* / app.*Office core / app propertiescore.title, app.Company
info.* / xmp.*PDF info dictionary / XMPinfo.Subject, info.Keywords
email.*.eml RFC 5322 headersemail.X-TITUS-Classification
The client gate is a fast-fail UX convenience, not an authoritative barrier — it runs in the user’s browser. Always pair a classification policy with a server-side before_file_ingest hook (e.g. target: http / workspace) that re-checks the file, so the rule is enforced even if the browser is bypassed.

Org & platform hooks

Hooks defined at the org or platform level apply to every agent in scope. Set immutable: true to make a policy mandatory: it always applies and cannot be disabled or overridden by an agent. In the agent UI these appear as read-only / locked, with locked_by indicating org or platform.

Limits

  • Up to 10 hooks per agent.
  • Default rate limit: 1000 invocations/minute per hook.

Configuring hooks

Hooks are managed from the agent’s Capabilities page (see Capabilities). Add a hook, pick its event(s), choose the target (HTTP / workspace / client) and mode, then set the behavior controls. For HTTP/workspace targets, point it at a Builder automation exposed as a webhook.