curl --request POST \
--url https://openrouter.ai/api/v1/interns/{internId}/invoke \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"input": "New support ticket 48213. Case token: ct_9f2c. Investigate and reply."
}
'import requests
url = "https://openrouter.ai/api/v1/interns/{internId}/invoke"
payload = { "input": "New support ticket 48213. Case token: ct_9f2c. Investigate and reply." }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({input: 'New support ticket 48213. Case token: ct_9f2c. Investigate and reply.'})
};
fetch('https://openrouter.ai/api/v1/interns/{internId}/invoke', 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://openrouter.ai/api/v1/interns/{internId}/invoke",
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([
'input' => 'New support ticket 48213. Case token: ct_9f2c. Investigate and reply.'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://openrouter.ai/api/v1/interns/{internId}/invoke"
payload := strings.NewReader("{\n \"input\": \"New support ticket 48213. Case token: ct_9f2c. Investigate and reply.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://openrouter.ai/api/v1/interns/{internId}/invoke")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"input\": \"New support ticket 48213. Case token: ct_9f2c. Investigate and reply.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns/{internId}/invoke")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": \"New support ticket 48213. Case token: ct_9f2c. Investigate and reply.\"\n}"
response = http.request(request)
puts response.read_body{
"session_id": "b51a0e21-368b-4780-a220-14655bf28c55",
"status": "started"
}{
"error": {
"code": 400,
"message": "Invalid invoke request (input: Too small: expected string to have >=1 characters).",
"metadata": {
"reason": "bad_request",
"retryable": false
}
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": 403,
"message": "This API key's creator is no longer a member of the organization. Ask an organization admin to reassign the key to an active member."
}
}{
"error": {
"code": 404,
"message": "Intern not found",
"metadata": {
"reason": "not_found",
"retryable": false
}
}
}{
"error": {
"code": 408,
"message": "Operation timed out after 60s. Please try again later.",
"metadata": {
"reason": "timeout",
"retryable": true
}
}
}{
"error": {
"code": 409,
"message": "This intern is not running.",
"metadata": {
"reason": "intern_not_ready",
"retryable": true
}
}
}{
"error": {
"code": 413,
"message": "Request body exceeds 1048576 bytes",
"metadata": {
"reason": "payload_too_large",
"retryable": false
}
}
}{
"error": {
"code": 429,
"message": "Too many intern turns. Please wait a moment.",
"metadata": {
"reason": "rate_limited",
"retryable": true
}
}
}{
"error": {
"code": 500,
"message": "Could not look up the intern",
"metadata": {
"reason": "intern_unreachable",
"retryable": true
}
}
}{
"error": {
"code": 502,
"message": "The intern could not be reached.",
"metadata": {
"reason": "intern_unreachable",
"retryable": true
}
}
}{
"error": {
"code": 503,
"message": "The intern cannot hold another run open across a question right now. Retry later.",
"metadata": {
"reason": "busy",
"retryable": true
}
}
}{
"error": {
"code": 504,
"message": "The intern did not answer in time.",
"metadata": {
"reason": "timeout",
"retryable": true
}
}
}Start an intern run without waiting for it
Starts a run on one of your interns and answers 202 with the session_id as soon as the intern accepts it. The run keeps going on the intern after the response. Nothing about its progress comes back on this request; the intern reports through its own tools, such as Slack.
Send the same session_id later to continue the conversation, for example to hand the intern a decision on work it started. If that session already has a run going, the prompt is delivered into it and the status is steered. A session_id is accepted only from the caller it was issued to, on the same intern; any other, including sessions started from Slack or the chat endpoint, is refused with 404.
Runs started here self-drive: the intern consents to its own tool approvals, and a question it asks is answered by its own fallback. A run ends when the intern finishes it or after its execution deadline (1 hour by default).
Available to interns programme members. Callers outside the programme receive 404 for every path under /api/v1/interns.
curl --request POST \
--url https://openrouter.ai/api/v1/interns/{internId}/invoke \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"input": "New support ticket 48213. Case token: ct_9f2c. Investigate and reply."
}
'import requests
url = "https://openrouter.ai/api/v1/interns/{internId}/invoke"
payload = { "input": "New support ticket 48213. Case token: ct_9f2c. Investigate and reply." }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({input: 'New support ticket 48213. Case token: ct_9f2c. Investigate and reply.'})
};
fetch('https://openrouter.ai/api/v1/interns/{internId}/invoke', 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://openrouter.ai/api/v1/interns/{internId}/invoke",
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([
'input' => 'New support ticket 48213. Case token: ct_9f2c. Investigate and reply.'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://openrouter.ai/api/v1/interns/{internId}/invoke"
payload := strings.NewReader("{\n \"input\": \"New support ticket 48213. Case token: ct_9f2c. Investigate and reply.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://openrouter.ai/api/v1/interns/{internId}/invoke")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"input\": \"New support ticket 48213. Case token: ct_9f2c. Investigate and reply.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns/{internId}/invoke")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": \"New support ticket 48213. Case token: ct_9f2c. Investigate and reply.\"\n}"
response = http.request(request)
puts response.read_body{
"session_id": "b51a0e21-368b-4780-a220-14655bf28c55",
"status": "started"
}{
"error": {
"code": 400,
"message": "Invalid invoke request (input: Too small: expected string to have >=1 characters).",
"metadata": {
"reason": "bad_request",
"retryable": false
}
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": 403,
"message": "This API key's creator is no longer a member of the organization. Ask an organization admin to reassign the key to an active member."
}
}{
"error": {
"code": 404,
"message": "Intern not found",
"metadata": {
"reason": "not_found",
"retryable": false
}
}
}{
"error": {
"code": 408,
"message": "Operation timed out after 60s. Please try again later.",
"metadata": {
"reason": "timeout",
"retryable": true
}
}
}{
"error": {
"code": 409,
"message": "This intern is not running.",
"metadata": {
"reason": "intern_not_ready",
"retryable": true
}
}
}{
"error": {
"code": 413,
"message": "Request body exceeds 1048576 bytes",
"metadata": {
"reason": "payload_too_large",
"retryable": false
}
}
}{
"error": {
"code": 429,
"message": "Too many intern turns. Please wait a moment.",
"metadata": {
"reason": "rate_limited",
"retryable": true
}
}
}{
"error": {
"code": 500,
"message": "Could not look up the intern",
"metadata": {
"reason": "intern_unreachable",
"retryable": true
}
}
}{
"error": {
"code": 502,
"message": "The intern could not be reached.",
"metadata": {
"reason": "intern_unreachable",
"retryable": true
}
}
}{
"error": {
"code": 503,
"message": "The intern cannot hold another run open across a question right now. Retry later.",
"metadata": {
"reason": "busy",
"retryable": true
}
}
}{
"error": {
"code": 504,
"message": "The intern did not answer in time.",
"metadata": {
"reason": "timeout",
"retryable": true
}
}
}Authorizations
API key as bearer token in Authorization header
Path Parameters
The intern to run.
"a11e0000-0000-4000-8000-000000000005"
Body
A prompt to run on the intern without holding a connection open.
The prompt for the run, at most 32000 characters.
1 - 32000"New support ticket 48213. Case token: ct_9f2c. Investigate and reply."
The session to run in. Send the session_id from an earlier 202 to continue that conversation, for example to hand the intern a decision on a case it is working. Omit it to start a new session. Only a session_id this endpoint issued to the same caller on the same intern is accepted; any other is refused with 404.
1 - 256"b51a0e21-368b-4780-a220-14655bf28c55"
Response
The intern accepted the prompt. The run continues on the intern.
The intern admitted the prompt. The run continues on the intern.
The session the run belongs to. Send it back to continue the conversation.
"b51a0e21-368b-4780-a220-14655bf28c55"
started when a new run began. steered when the session already had a run going and the prompt was delivered into it instead.
started, steered "started"