Minto is fileAI’s AI assistant: it answers questions about the documents in your workspace. The agent sessions API is how you use Minto from your own code. You open a session, ask a question, and get back a job that you poll (or receive by callback) for the answer. Later questions in the same session build on earlier ones.

How it works

A session holds the conversation. Each question you ask is a turn, and each turn runs as an asynchronous agent job with an id that starts sajob_. Agent jobs are polled on the same route as document jobs; see Async jobs. A session runs one turn at a time. Asking while a turn is still QUEUED or RUNNING returns 409 AGENT_RUN_IN_PROGRESS; wait for it to settle, or stop it.

Requirements

  • Every route uses the usual x-api-key header. See Authentication.
  • The key must be associated with a user. A key with no user gets 403 FORBIDDEN on session creation and on every ask. Re-issue the key with a user rather than retrying.
  • POST /v1/agent/sessions, POST …/ask and POST …/stop require an Idempotency-Key header. Without it you get 400. DELETE /v1/agent/sessions/{session_id} accepts one optionally. See Idempotent requests.

Endpoints

Example

The cURL commands assume FILEAI_BASE_URL="https://api.orion.file.ai/prod/v1", or your regional host.
1

Create a session

Response (201)
title is optional (up to 200 characters). Without it the session is called New Chat until the agent names it from the first turn.
2

Ask a question

Response (202)
3

Poll the job

Response
If your API key has a default callback URL, the settled job is also POSTed there. Keep polling as a fallback; see Async jobs.

Reference

Ask fields

Omit document_ids, file_ids and use_all_files to keep the session’s own scope.
use_all_files only considers the 100 most recently created processed documents. In a larger workspace the agent does not see the rest. When coverage matters, name the documents with document_ids or file_ids.

Job result

GET /v1/jobs/{job_id} returns kind: "agent" for a sajob_ id. For what each status means (QUEUED, RUNNING, COMPLETED, STOPPED, FAILED), see Agent jobs. Two things matter for Minto in particular:
  • result.answer holds the answer on COMPLETED, and the partial answer on STOPPED. On FAILED, error.code and error.detail describe the failure, and error.retryable says whether asking again is worthwhile.
  • FAILED with error.code SUPERAGENT_RUN_STALE is provisional. The run went quiet for too long and was given up on, but a run that was only slow can still finish and move to COMPLETED or STOPPED, with a second callback. Treat it as safe to retry, but don’t close out your own record for that job_id on it.
result.files lists any files the agent generated (PDF, HTML or Excel), each with name, content_type, a presigned url and its expires_at. Use the URL as given; ask again for a fresh link once it expires.

Session run status

GET /v1/agent/sessions/{session_id} includes run_status and the latest job_id. The list endpoint leaves run_status out, so read the single session when you need to know whether it can take a turn. A turn that stops reporting sends no final event. It is only marked STALE when you read the session or its messages, or ask a new question; that is what frees the session.

Reading the conversation

GET /v1/agent/sessions/{session_id}/messages returns one row per message, oldest first: a user row for each question and an assistant row for each answer, so a turn appears as two rows. To read a truncated answer in full, fetch its job_id from GET /v1/jobs/{job_id}. A turn asked in the app has no job, so its truncated answer can’t be retrieved in full through the API.

Pagination

Both list routes use cursor pagination only; there is no page parameter. Omit cursor for the first page, then pass pagination.nextCursor until hasMore is false. A larger limit is reduced to the maximum.

Stopping a turn

POST /v1/agent/sessions/{session_id}/stop is a request, not a completion. It returns 202 straight away with stop_requested, the run_status at that moment, job_id and poll_url.
  • The agent keeps working for about a second while it saves its partial work, then ends the turn. The partial answer is kept, and the time and cost already spent are still billed.
  • If the turn had already finished, stop_requested is false. That is a normal outcome, not an error.
  • The session stays open, and the next turn continues from where the agent stopped.
Poll the job_id until it reaches STOPPED, or whatever status the turn reached on its own.

Deleting a session

DELETE /v1/agent/sessions/{session_id} stops a live turn first instead of refusing. The response has deleted: true, stopped_run (whether a turn was stopped) and that turn’s job_id. The job outlives the session: its partial answer, cost and callback still arrive through GET /v1/jobs/{job_id}. Every route on a deleted session, including another DELETE, returns 404.

Async jobs

How agent jobs, document jobs and uploads report progress.

Idempotent requests

Why create, ask and stop require an Idempotency-Key.

Pagination

Cursor rules for the session and message lists.

Errors

AGENT_RUN_IN_PROGRESS, FORBIDDEN and the rest.