Skip to content

Murshid — the AI assistant (/v1/ai)

Murshid is Caravan's information-only assistant. Its value is legibility, not advice: it explains facts about the caller's own account and general market concepts, and it never ranks, evaluates, compares, recommends, times, or expresses sentiment about a security. That posture is the regulatory perimeter of FRA Decision 332 (R1) — and here it is a build property, not a prompt instruction.

Non-advice by construction. Every turn runs a fail-closed pipeline — policy → intent → grounding → render → firewall — and a failure at any stage falls back to a neutral, templated refusal. The order-explainer answers only from a fixed reject-code registry, so it is structurally incapable of advice. For anything about what to do with money, Murshid redirects to the broker.

Availability — 501 NOT_AVAILABLE

Murshid mounts behind the same read auth as every other /v1 read endpoint (Bearer key; no signature). When no inference provider is configured — the default — the AI routes return:

HTTP/1.1 501 Not Implemented
{ "error": { "code": "NOT_AVAILABLE", "message": "…" }, "request_id": "…" }

The registry-grounded surfaces (glossary, disclosure, the error explainer, and the order-explainer's reject-code path) need no model, so where a backend is configured they answer from the closed, vetted corpus rather than free generation. Responses are bilingual — send Accept-Language: ar for Arabic.

POST /v1/ai/explain/order/{id}

A plain-language explanation of one of the caller's own orders — a status explainer, not a judgement. A rejected order with a known reason code gets a neutral cause + remedy from the registry; any other state is narrated factually. A cross-tenant order id is treated as not-found (404-style refusal), never a 403.

json
{
  "outcome": "answered",
  "order_id": "ord_…",
  "state": "rejected",
  "symbol": "COMI",
  "reason_code": "INSUFFICIENT_BUYING_POWER",
  "cause": "The order needed more settled cash than the account had available.",
  "remedy": "Fund the account or reduce the order size, then try again."
}
FieldNotes
outcomeanswered, or refused with a neutral message
statethe order's verbatim state span (filled, rejected, working, …)
reason_codepresent only for a rejected order; resolved against the reject registry
cause / remedyneutral explanation; never a recommendation. A code with no registry entry yields a "contact your broker" refusal

GET /v1/ai/glossary and /v1/ai/glossary/{term}

Neutral, educational definitions from the closed glossary (the same corpus as Learn). Never instrument-specific, never an action frame. With no {term}, returns the glossary article / article list; with a term, an exact-slug lookup (never a relevance ranking). An unmatched term yields a neutral abstain.

json
{ "outcome": "answered", "article": { "slug": "clean-and-dirty-price", "title": "…", "body": "…" } }

GET /v1/ai/disclosure

The canonical standing disclosure — what Murshid is and is not — rendered as the first message of any session and on every advice-deflection. Co-renders the investment-risk note. Verbatim canonical text (no model).

json
{
  "outcome": "answered",
  "disclosures": [
    { "key": "ai_interaction", "text": "You are using an information-only assistant. … For anything about what to do with your money, contact your broker." },
    { "key": "investment_risk", "text": "…" }
  ]
}

GET /v1/ai/dev/explain-error/{code}

A developer aid (also accepts ?code=): explains an API error code in plain terms — HTTP/transport semantics, not securities — from the error registry. It carries none of the investor guardrails because it never speaks about instruments; the egress firewall still runs.

json
{ "outcome": "answered", "code": "SIGNATURE_INVALID", "cause": "…", "remedy": "…" }

What Murshid will not do. It books nothing, calls no broker, and holds no signing credentials. It does not recommend, compare, rank, or time securities, and it does not interpret news sentiment. Advice-seeking prompts are deflected to the broker before any generation. See Neutrality by construction.

Embedded investing infrastructure for the Egyptian Exchange. Sandbox runs on simulated money.