curl --request PATCH \
--url https://openrouter.ai/api/v1/interns/{internId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"description": "Researches customer questions",
"model": "openai/gpt-5.4"
}
'import requests
url = "https://openrouter.ai/api/v1/interns/{internId}"
payload = {
"description": "Researches customer questions",
"model": "openai/gpt-5.4"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({description: 'Researches customer questions', model: 'openai/gpt-5.4'})
};
fetch('https://openrouter.ai/api/v1/interns/{internId}', 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}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'description' => 'Researches customer questions',
'model' => 'openai/gpt-5.4'
]),
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}"
payload := strings.NewReader("{\n \"description\": \"Researches customer questions\",\n \"model\": \"openai/gpt-5.4\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://openrouter.ai/api/v1/interns/{internId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"Researches customer questions\",\n \"model\": \"openai/gpt-5.4\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns/{internId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"Researches customer questions\",\n \"model\": \"openai/gpt-5.4\"\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"
}{
"error": {
"code": "invalid_body",
"message": "Invalid request body"
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": 403,
"message": "Forbidden"
}
}{
"error": {
"code": "not_found",
"message": "Intern not found"
}
}{
"error": {
"code": 408,
"message": "Request timed out"
}
}{
"error": {
"code": "payload_too_large",
"message": "Request body exceeds 1048576 bytes"
}
}{
"error": {
"code": "internal_error",
"message": "The request could not be completed"
}
}Update an intern
Changes the intern name, description, instructions or model. Omitted fields stay unchanged. 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 PATCH \
--url https://openrouter.ai/api/v1/interns/{internId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"description": "Researches customer questions",
"model": "openai/gpt-5.4"
}
'import requests
url = "https://openrouter.ai/api/v1/interns/{internId}"
payload = {
"description": "Researches customer questions",
"model": "openai/gpt-5.4"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({description: 'Researches customer questions', model: 'openai/gpt-5.4'})
};
fetch('https://openrouter.ai/api/v1/interns/{internId}', 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}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'description' => 'Researches customer questions',
'model' => 'openai/gpt-5.4'
]),
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}"
payload := strings.NewReader("{\n \"description\": \"Researches customer questions\",\n \"model\": \"openai/gpt-5.4\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://openrouter.ai/api/v1/interns/{internId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"Researches customer questions\",\n \"model\": \"openai/gpt-5.4\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns/{internId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"Researches customer questions\",\n \"model\": \"openai/gpt-5.4\"\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"
}{
"error": {
"code": "invalid_body",
"message": "Invalid request body"
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": 403,
"message": "Forbidden"
}
}{
"error": {
"code": "not_found",
"message": "Intern not found"
}
}{
"error": {
"code": 408,
"message": "Request timed out"
}
}{
"error": {
"code": "payload_too_large",
"message": "Request body exceeds 1048576 bytes"
}
}{
"error": {
"code": "internal_error",
"message": "The request could not be completed"
}
}Authorizations
API key as bearer token in Authorization header
Path Parameters
ID of an intern visible to the authenticated API key.
1"7c9e6679-7425-40de-944b-e07fc1f90ae7"
Body
Lifecycle settings to change. Omitted fields stay unchanged and null clears a field.
New free-form description. Null clears it.
2000New standing instructions. Null clears them.
100000New OpenRouter model slug. Null restores the workspace default.
200New intern name, unique per creator within the workspace.
2 - 17^[a-z][a-z0-9]*(-[a-z0-9]+)*$Response
Updated intern.
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.