FactQLDocs
Get an API key
API · Chat history

Chat history

GET/clients/{client_id}/sessions/{session_id}

Reopen an earlier chat: load its messages newest first, page back through older ones, and redraw any answer's table or chart.

Use the same headers as Conversations: X-API-Key, and X-End-User-Id for the person whose chat it is. A chat belongs to the end user who started it. Anyone else gets a 404. Ask-only keys can use every call on this page.

List someone's chats

GET /clients/{client_id}/sessions?limit=50&offset=0 returns {items, total, limit, offset}, newest first. Each item has id, title, created_at, updated_at and message_count. The id is the session_id below.

Open a chat, newest first

Ask for the last 30 messages. They come back oldest first, with has_more when the chat goes back further. To load older messages, send the id of the oldest message you have as before_message_id. Repeat until has_more is false.

Newest 30, then the 30 before them
curl "https://api.factql.ai/clients/$CLIENT_ID/sessions/$SESSION_ID?message_limit=30" \
  -H "X-API-Key: $FACTQL_API_KEY" -H "X-End-User-Id: user-42"

curl "https://api.factql.ai/clients/$CLIENT_ID/sessions/$SESSION_ID?message_limit=30&before_message_id=1071" \
  -H "X-API-Key: $FACTQL_API_KEY" -H "X-End-User-Id: user-42"
Response
{
  "id": "3f7b1c40-2a55-4f9e-8d21-0a6f4b9c1d33",
  "title": "Revenue by month",
  "has_more": true,
  "messages": [
    { "id": 1071, "role": "user", "content": "Revenue by month this year", "timestamp": "2026-11-10T09:12:03Z", "metadata": {} },
    {
      "id": 1072,
      "role": "assistant",
      "content": "Revenue rose every month from January to July.",
      "timestamp": "2026-11-10T09:12:09Z",
      "metadata": {
        "payload": {
          "sql": "SELECT month, SUM(revenue) AS revenue FROM orders GROUP BY month ORDER BY month",
          "data": { "columns": ["month", "revenue"] },
          "total_rows": 7,
          "type": "text2sql"
        }
      }
    }
  ]
}
Query
message_limitinteger
Only the last N messages. With before_message_id, the N before it: 1 to 100, default 30. Leave out both parameters to get the whole chat.
before_message_idinteger
The id of the oldest message you already have. It must be a message of this chat.
workspace_idstring
The workspace the chat was in. Keys bound to a workspace don't need it.

An assistant message's metadata.payload has everything its answer card needs except the rows: the sql, the column names under data.columns, total_rows and, when the answer drew one, chart_config. Fetch the rows with the call below.

Redraw an answer's table or chart

POST /clients/{client_id}/sessions/{session_id}/messages/{message_id}/results

message_id is the assistant message's idfrom the chat above. FactQL runs that answer's saved query again, read-only, and returns one page of rows. Opening the same answer again within five minutes is served without another database query.

Request
curl -X POST "https://api.factql.ai/clients/$CLIENT_ID/sessions/$SESSION_ID/messages/1072/results" \
  -H "X-API-Key: $FACTQL_API_KEY" -H "X-End-User-Id: user-42" \
  -H "Content-Type: application/json" \
  -d '{"page": 1, "page_size": 50}'
Body
pageinteger
1-based page. Default 1.
page_sizeinteger
1 to 500. Default 50.
known_totalinteger
The total_rows you already have, to skip counting again.
step_idstring
For an answer built from several queries: which one to run, from steps in a previous response. Leave it out to get the last one.
workspace_idstring
The workspace the chat was in.
Response
columns, rowsOne page of the answer's result, re-run now. Rows are never stored.
page, page_size, total_rows, total_pagesWhere this page sits in the whole result.
column_labelsDisplay names for the columns, when your admin has set any.
step_id, label, stepsAnswers built from several queries only: the query this page is from, its label, and every query you can switch to.
chart_configThe chart the live answer drew, when it drew one.
Response for an answer built from two queries
{
  "columns": ["product", "revenue"],
  "rows": [["Kit", 48210.0], ["Scarf", 12034.5]],
  "page": 1,
  "page_size": 50,
  "total_rows": 2,
  "total_pages": 1,
  "step_id": "s2",
  "label": "Top products",
  "steps": [
    { "step_id": "s1", "label": "Revenue by month" },
    { "step_id": "s2", "label": "Top products" }
  ],
  "chart_config": { "type": "bar", "x": "product", "y": "revenue" }
}
Errors
400before_message_id isn't a message of this chat.
401The key is missing, invalid or revoked.
403The key belongs to a different tenant, or the answer's data is outside the active workspace.
404The chat doesn't exist or belongs to a different end user, the message has no query to run (a text answer), or step_idisn't one of the answer's steps.
422message_limit is outside 1 to 100 while paging back.
429Too many requests. Wait Retry-After seconds.