Skip to content
Back to skills

Iblai Api Agent Session

ASecurity

Talk to a deployed ibl.ai agent directly over REST/SSE (or WebSocket) and manage its chat sessions — POST a prompt to the agent chat endpoint, attach arbitrary metadata (surfaced later as client_context), and list/read sessions and per-task history exports. The direct-transport counterpart to iblai-api-agent-chat's MCP wiring; use when you want raw streamed chat + session records rather than an MCP server.

  • 15 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 20, 2026
ai-agentsbashapi

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 20, 2026

npx -y skills add iblai/vibe --skill iblai-api-agent-session --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Iblai Api Agent Session?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Iblai Api Agent Session
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iblai-iblai-api-agent-session/badge)](https://www.skillsdirectory.com/skills/iblai-iblai-api-agent-session)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: iblai-api-agent-session
description: Talk to a deployed ibl.ai agent directly over REST/SSE (or WebSocket) and manage its chat sessions — POST a prompt to the agent chat endpoint, attach arbitrary metadata (surfaced later as client_context), and list/read sessions and per-task history exports. The direct-transport counterpart to iblai-api-agent-chat's MCP wiring; use when you want raw streamed chat + session records rather than an MCP server.
metadata:
  kind: api
---

# iblai-api-agent-session

Drive a deployed agent's **chat transport directly** and read its **sessions**.
Where `/iblai-api-agent-chat` wires a hosted MCP server for conversation, this
skill is the raw REST/SSE (and WebSocket) surface: POST a prompt, stream the
reply, attach `metadata` that resurfaces as `client_context`, and list/inspect
the resulting session records. Get `IBLAI_ORG`/`IBLAI_USERNAME`/`IBLAI_API_KEY`
from `/iblai-api-login`.

## Auth & conventions

- **Header:** `Authorization: Api-Token $IBLAI_API_KEY` on every request.
- **Path vars:** `{org}` = `$IBLAI_ORG`, `{user}` = `$IBLAI_USERNAME`.
- **Two hosts — chat is streaming/ASGI:**
  - Chat turn (SSE / WebSocket) → `https://asgi.data.iblai.app`
  - Session reads/writes → `https://api.iblai.app/dm/api/ai-mentor/orgs/{org}/users/{user}/v1` … i.e. `…/orgs/{org}/users/{user}/sessions/…`
- Not connected yet? Run **`/iblai-api-login`** first.

## Concepts

**Two independent context fields — one soft, one hard.** A chat turn can carry both
`metadata` (soft) and `document_filter` (hard); they do different jobs and don't
substitute for each other:

- **`metadata` (soft)** — steers *how the agent reasons*. It's appended to the prompt and
  persisted; it never restricts which documents RAG can retrieve.
- **`document_filter` (hard)** — steers *which documents RAG may retrieve*. It's a
  document-level allow-list applied in the vector store; it does not touch the prompt.

Passing `metadata` alone narrows nothing in retrieval; passing `document_filter` alone
scopes retrieval without giving the agent any extra prose context. Use both when you want
both effects.

**`metadata` → `client_context` passthrough (soft).** Every chat turn (WS or SSE) may
carry a `metadata` object of arbitrary key/values (`BaseConsumerPayload.metadata`). The
runner folds it into the prompt the agent sees, so the agent can tailor its reply, and the
consumer persists it on the session as `Session.metadata["client_context"]`. It is
**session-level**: each turn's `metadata` overwrites the session's `client_context`, so
it sticks across turns until you send new keys. Use it to tell one deployed agent
*where/why* a message arrives (product, plan tier, page, region) without editing its
prompt. It then echoes back on every read below. The sibling field `page_content` is
also appended to the prompt, but — unlike `metadata` — is stripped before the message is
saved.

**`document_filter` → retrieval scoping (hard).** An optional
`BaseConsumerPayload.document_filter` object (`{key: scalar}`) restricts RAG retrieval to
documents whose ingested `custom_metadata` is compatible with the filter. It is matched
**inclusively per key**: a document is kept if, for **every** filter key, it either
*matches that key's value* **or** *does not carry that key at all*; it is excluded only
when it carries the key with a **different** value. Multiple keys are AND'd. Because a
document that lacks a key is never excluded by it, generic/untagged material always
survives — e.g. `{"stateCode":"CA"}` keeps California docs **and** generic docs that carry
no `stateCode`, while dropping docs tagged for other states. Unlike `metadata`,
`document_filter` is **not** session-sticky — it applies only to the turn that sends it —
and it never appears in the prompt or saved history. It only shrinks the retrieval
candidate set; top-k similarity ranking still runs afterward, so an eligible document is
not guaranteed to be retrieved if higher-scoring eligible documents fill the top-k.

## Reads

- **GET** `…/dm/api/ai-mentor/orgs/{org}/users/{user}/sessions/` — list the user's
  chat sessions.
- **GET** `…/orgs/{org}/users/{user}/sessions/{session_id}/` — the session's paginated
  chat messages (`MessageView`); the response also carries `client_context`, read from
  the session's `metadata["client_context"]`.
- **GET** `…/orgs/{org}/users/{user}/sessions/{session_id}/tasks/{task_id}/` — the
  chat-history export (`DownloadableChatHistory`); every item carries a `client_context`
  field. Add `?to_csv=true` for a CSV whose columns are exactly
  `type,content,timestamp,client_context`. Kicking off (POST) and polling that export
  task is owned by **`/iblai-api-agent-history`**.
- **Analytics echo:** the same value comes back at `summary.client_context` from
  **GET** `…/dm/api/analytics/messages/details/?platform_key={org}&session_id={session_id}`
  — documented under **`/iblai-api-analytics`**.

## Writes

- **POST** `https://asgi.data.iblai.app/api/agent/chat/?platform_key={org}&session_id={session_id}`
  — send a chat turn; response is Server-Sent Events. Body (`BaseConsumerPayload`):
  ```json
  {
    "session_id": "…",
    "prompt": "Hello",
    "flow": { "name": "<agent unique_id>", "tenant": "<org key>" },
    "page_content": "optional text appended to the prompt, stripped before saving",
    "metadata": { "any": "soft client context keys" },
    "document_filter": { "stateCode": "CA" }
  }
  ```
  `session_id` (a UUID4) and `flow` are **required**; `flow.name` selects the agent (its
  `unique_id`, or a slug/name) and `flow.tenant` is the org key. `prompt` and
  `page_content` default to empty, `metadata` and `document_filter` to null. `metadata` is
  soft passthrough — stored on the session as `client_context` (see Concepts) and echoed in
  the reads above. `document_filter` is the hard retrieval scope — an inclusive per-key
  allow-list over documents' ingested `custom_metadata`, applied only to this turn and never
  persisted (see Concepts and Schema). The **same payload** works over WebSocket at
  `wss://asgi.data.iblai.app/ws/chat/`.
- **POST** `…/dm/api/ai-mentor/orgs/{org}/users/{user}/sessions/` — create/retrieve a
  session (`ChatSessionView`; the body's `mentor` field picks the agent). Or let the
  first chat turn create one by passing a new `session_id`.

## Example

```bash
# Stream a chat turn with attached client context (SSE). MENTOR = the agent's unique_id.
curl -N -X POST \
  "https://asgi.data.iblai.app/api/agent/chat/?platform_key=$IBLAI_ORG&session_id=$SESSION" \
  -H "Authorization: Api-Token $IBLAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"session_id":"'"$SESSION"'","prompt":"Summarize my notes","flow":{"name":"'"$MENTOR"'","tenant":"'"$IBLAI_ORG"'"},"metadata":{"source":"docs","tab":"notes"}}'

# Read the session's messages back (client_context is the metadata you sent)
curl "https://api.iblai.app/dm/api/ai-mentor/orgs/$IBLAI_ORG/users/$IBLAI_USERNAME/sessions/$SESSION/" \
  -H "Authorization: Api-Token $IBLAI_API_KEY"

# Download the history export as CSV (client_context is a column)
curl "https://api.iblai.app/dm/api/ai-mentor/orgs/$IBLAI_ORG/users/$IBLAI_USERNAME/sessions/$SESSION/tasks/$TASK/?to_csv=true" \
  -H "Authorization: Api-Token $IBLAI_API_KEY"
```

## Notes

- **Streaming runs on ASGI** — the chat turn (`/api/agent/chat/`, `/ws/chat/`) is on
  `asgi.data.iblai.app`; session reads are ordinary REST on the `api.iblai.app/dm`
  gateway. `session_id` and `flow` are required on every turn, and `flow.name` must
  resolve to a deployed agent (its `unique_id`, slug, or name).
- For **OpenAI-format** inference against a provider/model (no agent RAG/memory), use
  `/iblai-api-inference`; to chat via an **MCP server** instead of raw SSE, use
  `/iblai-api-agent-chat`; the history-export task (kick off + poll) is
  `/iblai-api-agent-history`; the `summary.client_context` analytics read is
  `/iblai-api-analytics`.

## Schema

**`metadata` / `client_context`** (soft) — an arbitrary JSON object (`dict[str, Any] |
null`, `BaseConsumerPayload.metadata`). No fixed keys; use whatever your app needs, e.g.
`product`, `planTier`, `userRole`, `region`. Sent as `metadata` on a chat turn, it is
persisted at `Session.metadata["client_context"]` and read back as `client_context` in
the session-messages response, the history export (a `client_context` field per item, or
CSV column via `?to_csv=true`), and analytics `summary.client_context`. It is appended to
the prompt but never restricts retrieval.

**`document_filter`** (hard) — an optional JSON object (`dict[str, str|int|float|bool] |
null`, `BaseConsumerPayload.document_filter`) that scopes RAG retrieval to documents whose
ingested `custom_metadata` is compatible with the filter. It never touches the prompt and
is **not** persisted on the session (per-turn only). The keys/values here match the
`custom_metadata` you attach when adding documents — see `/iblai-api-agent-dataset` for
tagging documents at ingestion (the `custom_metadata` field on `documents/train/`).

- **Keys** must be flat and alphanumeric/underscore (`^\w+$`) — no `__`, no ORM-style
  lookup suffixes (`__icontains`, etc.). **Values** must be scalars (string, number, or
  boolean); lists/objects/null are rejected. A malformed filter fails the turn with a
  validation error rather than being silently ignored.
- **Inclusive per key:** a document is kept if, for **every** filter key, it *matches the
  value* **or** *does not carry that key*; it is excluded only when it carries the key with
  a **different** value. Multiple keys are AND'd.
- **Matching is exact** — value comparison is case- and type-sensitive (`"CA"` ≠ `"ca"`;
  the integer `2026` ≠ the string `"2026"`), and keys are matched exactly (`"stateCode"` ≠
  `"statecode"`); a key no document carries acts as a no-op for that key.
- **State + generic pattern:** ingest generic/shared documents with **no** state key and
  state-specific documents with `stateCode = <state>`; then `{"stateCode":"CA"}` retrieves
  California **and** generic documents while excluding other states — no per-state agent or
  two-stage retrieval needed. To search everything, send **no** `document_filter` (an empty
  or fully non-matching filter can yield an empty candidate set, and the agent may then
  answer without any retrieved context).
- **Eligibility ≠ retrieval:** the filter only shrinks the candidate set; top-k similarity
  ranking still runs, so an eligible document is not guaranteed to surface if higher-scoring
  eligible documents fill the top-k. Raise the agent's retrieval `k` if broad generic
  material is being crowded out.

## Reference material

- [`references/metadata-passthrough.md`](references/metadata-passthrough.md) — the
  `metadata` pass-through companion: the `<CONTEXT METADATA>` prompt-injection format,
  per-transport wire notes (SSE/WebSocket + the embedded-iframe `postMessage` channel),
  session caching (send-once, replace-not-merge, ~2h TTL), the
  one-agent-many-contexts pattern, the storage/pipeline map (session
  `client_context` vs. the per-message snapshot), and the **soft `metadata` vs. hard
  `document_filter`** comparison with the state-specific + generic retrieval pattern.

Files in this skill

  • SKILL.md11.1 KB
  • references/metadata-passthrough.md8.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.