curl --request POST \
--url https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"bodySha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
'import requests
url = "https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign"
payload = { "bodySha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }
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({bodySha256: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'})
};
fetch('https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign', 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}/daemon-access/sign",
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([
'bodySha256' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
]),
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}/daemon-access/sign"
payload := strings.NewReader("{\n \"bodySha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"\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}/daemon-access/sign")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"bodySha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign")
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 \"bodySha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"\n}"
response = http.request(request)
puts response.read_body{
"x-ori-invoke-signature": "MEUCIQ...",
"x-ori-invoke-timestamp": "1789000000",
"x-ori-invoke-user": "user_2abc"
}{
"error": {
"code": 400,
"message": "Invalid request body",
"metadata": {
"reason": "invalid_body",
"retryable": false
}
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": 403,
"message": "Personal connections require ori login --oidc.",
"metadata": {
"reason": "personal_identity_required",
"retryable": false
}
}
}{
"error": {
"code": 404,
"message": "Intern not found",
"metadata": {
"reason": "not_found",
"retryable": false
}
}
}{
"error": {
"code": 408,
"message": "Operation timed out after 10s. Please try again later.",
"metadata": {
"reason": "timeout",
"retryable": true
}
}
}{
"error": {
"code": 413,
"message": "Request body exceeds 1048576 bytes",
"metadata": {
"reason": "payload_too_large",
"retryable": false
}
}
}{
"error": {
"code": 415,
"message": "Request body must be sent as application/json",
"metadata": {
"reason": "unsupported_media_type",
"retryable": false
}
}
}{
"error": {
"code": 429,
"message": "Too many intern turns. Please wait a moment.",
"metadata": {
"reason": "rate_limited",
"retryable": true
}
}
}{
"error": {
"code": 500,
"message": "The request could not be completed",
"metadata": {
"reason": "internal_error",
"retryable": true
}
}
}Sign a daemon request with the caller's identity (deprecated alias)
Deprecated alias of POST /interns/{internId}/daemon/sign with the same request, response, and errors. The API key selects the caller, workspace and visible interns. An intern’s own API key sees only that intern: the collection and every other intern answer 404 to it. 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/{internId}/daemon-access/sign \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"bodySha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
'import requests
url = "https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign"
payload = { "bodySha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }
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({bodySha256: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'})
};
fetch('https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign', 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}/daemon-access/sign",
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([
'bodySha256' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
]),
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}/daemon-access/sign"
payload := strings.NewReader("{\n \"bodySha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"\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}/daemon-access/sign")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"bodySha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/interns/{internId}/daemon-access/sign")
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 \"bodySha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"\n}"
response = http.request(request)
puts response.read_body{
"x-ori-invoke-signature": "MEUCIQ...",
"x-ori-invoke-timestamp": "1789000000",
"x-ori-invoke-user": "user_2abc"
}{
"error": {
"code": 400,
"message": "Invalid request body",
"metadata": {
"reason": "invalid_body",
"retryable": false
}
}
}{
"error": {
"code": 401,
"message": "Invalid or missing API key"
}
}{
"error": {
"code": 403,
"message": "Personal connections require ori login --oidc.",
"metadata": {
"reason": "personal_identity_required",
"retryable": false
}
}
}{
"error": {
"code": 404,
"message": "Intern not found",
"metadata": {
"reason": "not_found",
"retryable": false
}
}
}{
"error": {
"code": 408,
"message": "Operation timed out after 10s. Please try again later.",
"metadata": {
"reason": "timeout",
"retryable": true
}
}
}{
"error": {
"code": 413,
"message": "Request body exceeds 1048576 bytes",
"metadata": {
"reason": "payload_too_large",
"retryable": false
}
}
}{
"error": {
"code": 415,
"message": "Request body must be sent as application/json",
"metadata": {
"reason": "unsupported_media_type",
"retryable": false
}
}
}{
"error": {
"code": 429,
"message": "Too many intern turns. Please wait a moment.",
"metadata": {
"reason": "rate_limited",
"retryable": true
}
}
}{
"error": {
"code": 500,
"message": "The request could not be completed",
"metadata": {
"reason": "internal_error",
"retryable": true
}
}
}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
Lower-case hex SHA-256 of the exact bytes the CLI will send as the daemon request body.
^[0-9a-f]{64}$"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
Response
Signature headers for the digest.
Headers the CLI copies onto the daemon request so the sidecar can verify who is asking.
Base64 Ed25519 signature over the intern id, timestamp, user and body digest.
Unix seconds at signing; the daemon refuses proofs older than its window.
The verified OAuth subject the proof names. Never taken from the request.