curl --request POST \
--url https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'x-api-key: <api-key>' \
--data '
{
"user_prompt": "Which invoices from Acme are still unpaid?",
"file_ids": [
"<string>"
],
"document_ids": [
"<string>"
],
"directory_id": "665f1c2e8a1b4c0012ab34cd",
"use_all_files": false,
"llm_model": "auto",
"allow_internet_search": true,
"allow_ai_query_subagent": true,
"client_ref": "order-4417",
"language_code": "en"
}
'import requests
url = "https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask"
payload = {
"user_prompt": "Which invoices from Acme are still unpaid?",
"file_ids": ["<string>"],
"document_ids": ["<string>"],
"directory_id": "665f1c2e8a1b4c0012ab34cd",
"use_all_files": False,
"llm_model": "auto",
"allow_internet_search": True,
"allow_ai_query_subagent": True,
"client_ref": "order-4417",
"language_code": "en"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
'x-api-key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_prompt: 'Which invoices from Acme are still unpaid?',
file_ids: ['<string>'],
document_ids: ['<string>'],
directory_id: '665f1c2e8a1b4c0012ab34cd',
use_all_files: false,
llm_model: 'auto',
allow_internet_search: true,
allow_ai_query_subagent: true,
client_ref: 'order-4417',
language_code: 'en'
})
};
fetch('https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user_prompt' => 'Which invoices from Acme are still unpaid?',
'file_ids' => [
'<string>'
],
'document_ids' => [
'<string>'
],
'directory_id' => '665f1c2e8a1b4c0012ab34cd',
'use_all_files' => false,
'llm_model' => 'auto',
'allow_internet_search' => true,
'allow_ai_query_subagent' => true,
'client_ref' => 'order-4417',
'language_code' => 'en'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask"
payload := strings.NewReader("{\n \"user_prompt\": \"Which invoices from Acme are still unpaid?\",\n \"file_ids\": [\n \"<string>\"\n ],\n \"document_ids\": [\n \"<string>\"\n ],\n \"directory_id\": \"665f1c2e8a1b4c0012ab34cd\",\n \"use_all_files\": false,\n \"llm_model\": \"auto\",\n \"allow_internet_search\": true,\n \"allow_ai_query_subagent\": true,\n \"client_ref\": \"order-4417\",\n \"language_code\": \"en\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask")
.header("Idempotency-Key", "<idempotency-key>")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"user_prompt\": \"Which invoices from Acme are still unpaid?\",\n \"file_ids\": [\n \"<string>\"\n ],\n \"document_ids\": [\n \"<string>\"\n ],\n \"directory_id\": \"665f1c2e8a1b4c0012ab34cd\",\n \"use_all_files\": false,\n \"llm_model\": \"auto\",\n \"allow_internet_search\": true,\n \"allow_ai_query_subagent\": true,\n \"client_ref\": \"order-4417\",\n \"language_code\": \"en\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_prompt\": \"Which invoices from Acme are still unpaid?\",\n \"file_ids\": [\n \"<string>\"\n ],\n \"document_ids\": [\n \"<string>\"\n ],\n \"directory_id\": \"665f1c2e8a1b4c0012ab34cd\",\n \"use_all_files\": false,\n \"llm_model\": \"auto\",\n \"allow_internet_search\": true,\n \"allow_ai_query_subagent\": true,\n \"client_ref\": \"order-4417\",\n \"language_code\": \"en\"\n}"
response = http.request(request)
puts response.read_body{
"job_id": "sajob_9f2c1a4b7e8d4c1fa0b3",
"status": "QUEUED",
"session_id": "665f1c2e8a1b4c0012ab34cd",
"created_at": "2023-11-07T05:31:56Z",
"poll_url": "<string>"
}Ask the agent a question
Adds a turn to the session and queues the agent run.
Returns 202 with a job_id and never an answer: a run routinely outlives any HTTP request. Poll poll_url for the result, or let it arrive at the API key’s callback URL when the job settles.
A session runs one turn at a time — asking again while a run is live is a 409. Wait for the job to reach a terminal status, or stop the run first.
Scope the turn with file_ids, document_ids or directory_id; omit them to inherit the session’s scope, or set use_all_files to search the whole workspace.
curl --request POST \
--url https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'x-api-key: <api-key>' \
--data '
{
"user_prompt": "Which invoices from Acme are still unpaid?",
"file_ids": [
"<string>"
],
"document_ids": [
"<string>"
],
"directory_id": "665f1c2e8a1b4c0012ab34cd",
"use_all_files": false,
"llm_model": "auto",
"allow_internet_search": true,
"allow_ai_query_subagent": true,
"client_ref": "order-4417",
"language_code": "en"
}
'import requests
url = "https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask"
payload = {
"user_prompt": "Which invoices from Acme are still unpaid?",
"file_ids": ["<string>"],
"document_ids": ["<string>"],
"directory_id": "665f1c2e8a1b4c0012ab34cd",
"use_all_files": False,
"llm_model": "auto",
"allow_internet_search": True,
"allow_ai_query_subagent": True,
"client_ref": "order-4417",
"language_code": "en"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
'x-api-key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_prompt: 'Which invoices from Acme are still unpaid?',
file_ids: ['<string>'],
document_ids: ['<string>'],
directory_id: '665f1c2e8a1b4c0012ab34cd',
use_all_files: false,
llm_model: 'auto',
allow_internet_search: true,
allow_ai_query_subagent: true,
client_ref: 'order-4417',
language_code: 'en'
})
};
fetch('https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user_prompt' => 'Which invoices from Acme are still unpaid?',
'file_ids' => [
'<string>'
],
'document_ids' => [
'<string>'
],
'directory_id' => '665f1c2e8a1b4c0012ab34cd',
'use_all_files' => false,
'llm_model' => 'auto',
'allow_internet_search' => true,
'allow_ai_query_subagent' => true,
'client_ref' => 'order-4417',
'language_code' => 'en'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask"
payload := strings.NewReader("{\n \"user_prompt\": \"Which invoices from Acme are still unpaid?\",\n \"file_ids\": [\n \"<string>\"\n ],\n \"document_ids\": [\n \"<string>\"\n ],\n \"directory_id\": \"665f1c2e8a1b4c0012ab34cd\",\n \"use_all_files\": false,\n \"llm_model\": \"auto\",\n \"allow_internet_search\": true,\n \"allow_ai_query_subagent\": true,\n \"client_ref\": \"order-4417\",\n \"language_code\": \"en\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask")
.header("Idempotency-Key", "<idempotency-key>")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"user_prompt\": \"Which invoices from Acme are still unpaid?\",\n \"file_ids\": [\n \"<string>\"\n ],\n \"document_ids\": [\n \"<string>\"\n ],\n \"directory_id\": \"665f1c2e8a1b4c0012ab34cd\",\n \"use_all_files\": false,\n \"llm_model\": \"auto\",\n \"allow_internet_search\": true,\n \"allow_ai_query_subagent\": true,\n \"client_ref\": \"order-4417\",\n \"language_code\": \"en\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orion.file.ai/prod/v2/agent/sessions/{session_id}/ask")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_prompt\": \"Which invoices from Acme are still unpaid?\",\n \"file_ids\": [\n \"<string>\"\n ],\n \"document_ids\": [\n \"<string>\"\n ],\n \"directory_id\": \"665f1c2e8a1b4c0012ab34cd\",\n \"use_all_files\": false,\n \"llm_model\": \"auto\",\n \"allow_internet_search\": true,\n \"allow_ai_query_subagent\": true,\n \"client_ref\": \"order-4417\",\n \"language_code\": \"en\"\n}"
response = http.request(request)
puts response.read_body{
"job_id": "sajob_9f2c1a4b7e8d4c1fa0b3",
"status": "QUEUED",
"session_id": "665f1c2e8a1b4c0012ab34cd",
"created_at": "2023-11-07T05:31:56Z",
"poll_url": "<string>"
}Idempotency-Key request header — omitting it
is a 400. See Idempotent requests.202 with a job_id. See The async job
lifecycle for how to
poll poll_url (GET /v2/jobs/{job_id}) through to a result, and for the one
run per session rule that makes a second ask a 409 while a turn is live.Authorizations
API key for authentication
Headers
Required opaque key (max 255 chars, UUIDv4 recommended) making this request idempotent for 24h: a retry with the same key and body replays the original response with Idempotent-Replayed: true. Omitting it is a 400; reusing a key with a different body is a 422; retrying while the first request is still in flight is a 409.
Path Parameters
Session to add the turn to.
Body
The question to ask.
30000"Which invoices from Acme are still unpaid?"
Restrict this turn to these files. Their documents are resolved for you. Omit to inherit the session's own scope.
100Restrict this turn to these documents. Takes precedence over file_ids.
100Restrict this turn to a directory.
"665f1c2e8a1b4c0012ab34cd"
Search the workspace's processed documents instead of a fixed list. Overrides file_ids and document_ids.
Bounded: the 100 most recently created processed documents are considered, newest first. A workspace larger than that is NOT searched in full — name the documents you care about with document_ids or file_ids when coverage matters.
Model hint for this turn. Defaults to the workspace-configured model.
"auto"
Allow the agent to search the public internet.
Allow the agent to run structured queries over your data as a sub-agent.
Opaque reference of your own, echoed back on the job and on the settlement webhook so you can correlate them with your own records.
255"order-4417"
BCP-47 language tag the agent should answer in.
"en"
Response
Turn accepted and queued.
Job handle for this turn. Poll it for the answer.
"sajob_9f2c1a4b7e8d4c1fa0b3"
Always QUEUED here. The job moves to RUNNING, then to COMPLETED, FAILED or STOPPED.
QUEUED "QUEUED"
The session this turn belongs to.
"665f1c2e8a1b4c0012ab34cd"
URL of GET /v2/jobs/{job_id}.