curl --request POST \
--url https://openrouter.ai/api/v1/interns \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "research-assistant",
"provision": true,
"workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}
'import requests
url = "https://openrouter.ai/api/v1/interns"
payload = {
"name": "research-assistant",
"provision": True,
"workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}
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({
name: 'research-assistant',
provision: true,
workspace_id: '89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb'
})
};
fetch('https://openrouter.ai/api/v1/interns', 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",
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([
'name' => 'research-assistant',
'provision' => true,
'workspace_id' => '89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb'
]),
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"
payload := strings.NewReader("{\n \"name\": \"research-assistant\",\n \"provision\": true,\n \"workspace_id\": \"89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb\"\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")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"research-assistant\",\n \"provision\": true,\n \"workspace_id\": \"89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns")
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 \"name\": \"research-assistant\",\n \"provision\": true,\n \"workspace_id\": \"89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb\"\n}"
response = http.request(request)
puts response.read_body{
"attached_vault_id": null,
"created_at": "2026-09-16T08:30:00.000Z",
"description": "Researches customer questions",
"hostname": "research-assistant.openrouter.ai",
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"instructions": null,
"last_failure_message": null,
"model": "openai/gpt-5.4",
"name": "research-assistant",
"progress": null,
"status": "running",
"updated_at": "2026-09-16T08:45:00.000Z",
"vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121",
"workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}Create an intern
Creates an intern in an explicit workspace. The operation also creates its private vault. It can start provisioning immediately or wait for a later provision call. A retry with the same idempotency key and body resumes unfinished work. The request body is capped at 1048576 bytes and a larger body is refused with 413. The API key selects the caller, workspace and visible interns. There is no default workspace fallback. Requests on regional hostnames such as eu.openrouter.ai are refused. API key required.
curl --request POST \
--url https://openrouter.ai/api/v1/interns \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "research-assistant",
"provision": true,
"workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}
'import requests
url = "https://openrouter.ai/api/v1/interns"
payload = {
"name": "research-assistant",
"provision": True,
"workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}
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({
name: 'research-assistant',
provision: true,
workspace_id: '89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb'
})
};
fetch('https://openrouter.ai/api/v1/interns', 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",
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([
'name' => 'research-assistant',
'provision' => true,
'workspace_id' => '89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb'
]),
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"
payload := strings.NewReader("{\n \"name\": \"research-assistant\",\n \"provision\": true,\n \"workspace_id\": \"89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb\"\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")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"research-assistant\",\n \"provision\": true,\n \"workspace_id\": \"89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns")
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 \"name\": \"research-assistant\",\n \"provision\": true,\n \"workspace_id\": \"89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb\"\n}"
response = http.request(request)
puts response.read_body{
"attached_vault_id": null,
"created_at": "2026-09-16T08:30:00.000Z",
"description": "Researches customer questions",
"hostname": "research-assistant.openrouter.ai",
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"instructions": null,
"last_failure_message": null,
"model": "openai/gpt-5.4",
"name": "research-assistant",
"progress": null,
"status": "running",
"updated_at": "2026-09-16T08:45:00.000Z",
"vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121",
"workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}Authorizations
API key as bearer token in Authorization header
Headers
Key that makes retries resume the same create operation. Without one, the server derives a stable key from the request body.
1"create-research-assistant-2026-09-16"
Body
Settings for a new intern.
Intern name, unique per creator within the workspace.
2 - 17^[a-z][a-z0-9]*(-[a-z0-9]+)*$Free-form description, or null.
2000Standing instructions the intern boots with, or null.
100000Start provisioning during this create operation. Defaults to false.
Vault owned by another intern in this workspace to attach as a borrowed vault.
Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace.
Response
A completed create operation was replayed.
Public lifecycle state and settings for one intern.
Vault the intern borrows from another intern, or null when it borrows none.
ISO 8601 creation time.
Free-form description.
Public hostname the intern is reachable at, or null until provisioning has assigned one.
Intern id.
Standing instructions the intern boots with.
Why the last provisioning attempt failed, when status is failed.
OpenRouter model slug the intern runs, or null for the workspace default.
Intern name, unique per creator within a workspace.
Active provisioning step, or null once provisioning has settled.
Show child attributes
Show child attributes
Lifecycle status.
awaiting_slack_install, queued, provisioning, running, failed, stopped, destroying, destroy_failed ISO 8601 last update time.
Vault the intern owns, or null before it has been created.
Workspace that owns the intern and scopes its secrets.