iblai/api

iblai-api-agent-session

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.

First seen Jul 27, 2026

Installation

$ npx skills add iblai/api --skill iblai-api-agent-session

Summary

  • 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.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from iblai/api · top by installs.

npx skills add iblai/api

Browse all from iblai/api

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 15
License LICENSE
Default branch main
Open issues 1
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 11,356 B
  • docs SUMMARY.md 442 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 3 installs

SKILL.md

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 clientcontext, and list/inspect the resulting session records. Get IBLAIORG/IBLAIUSERNAME/IBLAIAPI_KEY from /iblai-api-login.

Auth & conventions

  • Header: Authorization: Api-Token $IBLAIAPIKEY on every request.
  • Path vars: {org} = $IBLAIORG, {user} = $IBLAIUSERNAME.
  • 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 → clientcontext 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["clientcontext"]. It is session-level: each turn's metadata overwrites the session's clientcontext, 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 pagecontent is also appended to the prompt, but — unlike metadata — is stripped before the message is saved.

documentfilter → retrieval scoping (hard). An optional BaseConsumerPayload.documentfilter object ({key: scalar}) restricts RAG retrieval to documents whose ingested custommetadata 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, documentfilter 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 clientcontext, read from the session's metadata["clientcontext"].

  • GET …/orgs/{org}/users/{user}/sessions/{sessionid}/tasks/{taskid}/ — the

chat-history export (DownloadableChatHistory); every item carries a clientcontext field. Add ?tocsv=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/?platformkey={org}&sessionid={session_id} — documented under /iblai-api-analytics.

Writes

  • POST https://asgi.data.iblai.app/api/agent/chat/?platformkey={org}&sessionid={session_id}

— send a chat turn; response is Server-Sent Events. Body (BaseConsumerPayload): ``json { "sessionid": "…", "prompt": "Hello", "flow": { "name": "<agent uniqueid>", "tenant": "<org key>" }, "pagecontent": "optional text appended to the prompt, stripped before saving", "metadata": { "any": "soft client context keys" }, "documentfilter": { "stateCode": "CA" } } ` sessionid (a UUID4) and flow are required; flow.name selects the agent (its uniqueid, or a slug/name) and flow.tenant is the org key. prompt and pagecontent default to empty, metadata and documentfilter to null. metadata is soft passthrough — stored on the session as clientcontext (see Concepts) and echoed in the reads above. documentfilter 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

# 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. sessionid and flow are required on every turn, and flow.name must resolve to a deployed agent (its uniqueid, 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 / clientcontext (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["clientcontext"] and read back as clientcontext in the session-messages response, the history export (a clientcontext field per item, or CSV column via ?tocsv=true), and analytics summary.clientcontext. It is appended to the prompt but never restricts retrieval.

documentfilter (hard) — an optional JSON object (dict[str, str|int|float|bool] | null, BaseConsumerPayload.documentfilter) that scopes RAG retrieval to documents whose ingested custommetadata 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 custommetadata 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 clientcontext vs. the per-message snapshot), and the soft metadata vs. hard documentfilter comparison with the state-specific + generic retrieval pattern.