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,
"createdAt": "2026-09-16T08:30:00.000Z",
"description": "Researches customer questions",
"hostname": "research-assistant.openrouter.ai",
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"instructions": null,
"lastFailureMessage": null,
"model": "openai/gpt-5.4",
"name": "research-assistant",
"progress": null,
"status": "running",
"updatedAt": "2026-09-16T08:45:00.000Z",
"vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121",
"workspaceId": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}{
"attached_vault_id": null,
"createdAt": "2026-09-16T08:30:00.000Z",
"description": "Researches customer questions",
"hostname": "research-assistant.openrouter.ai",
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"instructions": null,
"lastFailureMessage": null,
"model": "openai/gpt-5.4",
"name": "research-assistant",
"progress": null,
"status": "running",
"updatedAt": "2026-09-16T08:45:00.000Z",
"vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121",
"workspaceId": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}{
"error": {
"code": "invalid_body",
"message": "Invalid request body"
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": "no_acting_user",
"message": "This key acts as the organization and has no member to own a new intern"
}
}{
"error": {
"code": "not_found",
"message": "Intern not found"
}
}{
"error": {
"code": 408,
"message": "Request timed out"
}
}{
"error": {
"code": "idempotency_key_reused",
"message": "This Idempotency-Key was already used with a different request"
}
}{
"error": {
"code": "payload_too_large",
"message": "Request body exceeds 1048576 bytes"
}
}{
"error": {
"code": "internal_error",
"message": "The request could not be completed"
}
}{
"error": {
"code": "upstream_unavailable",
"message": "The intern was created but setup is not ready yet, retry the request"
}
}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,
"createdAt": "2026-09-16T08:30:00.000Z",
"description": "Researches customer questions",
"hostname": "research-assistant.openrouter.ai",
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"instructions": null,
"lastFailureMessage": null,
"model": "openai/gpt-5.4",
"name": "research-assistant",
"progress": null,
"status": "running",
"updatedAt": "2026-09-16T08:45:00.000Z",
"vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121",
"workspaceId": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}{
"attached_vault_id": null,
"createdAt": "2026-09-16T08:30:00.000Z",
"description": "Researches customer questions",
"hostname": "research-assistant.openrouter.ai",
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"instructions": null,
"lastFailureMessage": null,
"model": "openai/gpt-5.4",
"name": "research-assistant",
"progress": null,
"status": "running",
"updatedAt": "2026-09-16T08:45:00.000Z",
"vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121",
"workspaceId": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"
}{
"error": {
"code": "invalid_body",
"message": "Invalid request body"
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": "no_acting_user",
"message": "This key acts as the organization and has no member to own a new intern"
}
}{
"error": {
"code": "not_found",
"message": "Intern not found"
}
}{
"error": {
"code": 408,
"message": "Request timed out"
}
}{
"error": {
"code": "idempotency_key_reused",
"message": "This Idempotency-Key was already used with a different request"
}
}{
"error": {
"code": "payload_too_large",
"message": "Request body exceeds 1048576 bytes"
}
}{
"error": {
"code": "internal_error",
"message": "The request could not be completed"
}
}{
"error": {
"code": "upstream_unavailable",
"message": "The intern was created but setup is not ready yet, retry the request"
}
}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 in an explicit workspace.
Intern name, unique per creator within the workspace.
2 - 17^[a-z][a-z0-9]*(-[a-z0-9]+)*$Workspace that will own the intern. It must match the API key workspace.
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.
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.