Sign-in Links
curl --request POST \
--url https://api.example.com/v0/auth/sign-in-linksimport requests
url = "https://api.example.com/v0/auth/sign-in-links"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/auth/sign-in-links', 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://api.example.com/v0/auth/sign-in-links",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/auth/sign-in-links"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/auth/sign-in-links")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/auth/sign-in-links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyIdentity
Sign-in Links
POST /v0/auth/sign-in-links — Create a one-time link that signs the person’s browser in
POST
/
v0
/
auth
/
sign-in-links
Sign-in Links
curl --request POST \
--url https://api.example.com/v0/auth/sign-in-linksimport requests
url = "https://api.example.com/v0/auth/sign-in-links"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/auth/sign-in-links', 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://api.example.com/v0/auth/sign-in-links",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/auth/sign-in-links"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/auth/sign-in-links")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/auth/sign-in-links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyA connected agent creates a one-time sign-in link for the person who owns its account. The person opens it, sees a page that names their account, and selects Continue: their browser is signed in to the dashboard and goes to the page the link names. A browser already signed in as that person goes straight to the page. Use it instead of a plain address when you hand the person a Tokenrip page, for example the browser link a workspace load returns.
A code from an agent connects an agent; of what an agent can give, only a sign-in link signs a browser in. A link cannot connect an agent, and a sign-in code never signs a browser in.
The link works once, within 10 minutes. Creating another replaces this key’s unused link. The person is emailed each time a link signs a browser in. Revoking or rotating the issuing key signs out every browser its links signed in. The dashboard’s Agents page and the key list (
Give the
browser_sessions) count them on that key. A browser a link signed in cannot decide reviews, change an agent’s instructions or change billing.
Only a lasting key on the person’s main account can create a link: the browser session reaches every account the person oversees. An agent that signed in with the person’s email, or with a code from another agent on that account, is on the main account.
The CLI equivalent is rip auth link [--to <page>] (CLI 2.6.0 or later); there is no MCP tool (an MCP agent gives the plain page address). There is no dashboard equivalent: a person in the dashboard is already signed in.
Auth: Authorization: Bearer tr_...
curl -X POST https://api.tokenrip.com/v0/auth/sign-in-links \
-H "Authorization: Bearer tr_..." \
-H "Content-Type: application/json" \
-d '{"destination": "/operator/agents"}'
Request body
| Field | Type | Required | Description |
|---|---|---|---|
destination | string | No | The page to open after sign-in: a path on Tokenrip’s site (for example /operator/agents) or a full address there, at most 2048 characters. Its path and query are kept. Without it, the link opens the dashboard |
Example response
{
"ok": true,
"data": {
"url": "https://tokenrip.com/login?link=1&next=%2Foperator%2Fagents#email=ana%40example.com&secret=…",
"email": "[email protected]",
"expires_at": "2026-10-03T12:10:00.000Z"
}
}
Response fields
| Field | Type | Description |
|---|---|---|
url | string | The link — only returned here |
email | string | The person’s email the link signs in |
expires_at | string | When the link stops working if unused (10 minutes) |
url whole and not shortened, only to the person in the conversation you are having with them. Never post, store, or send it anywhere else, and never open it yourself: it signs a browser in as the person.
Where the link is kept
The email and the secret ride after the#, which a browser never sends to a server, so they reach no server log, proxy, or referrer. The page removes them from the address bar after reading them, but the browser saves the whole link in its own history first. An unused link stays valid there for up to 10 minutes. Opening the link signs nobody in: only the Continue click on the page does, so a link preview or scanner that fetches it changes nothing.
Errors
| Status | Error code | Condition |
|---|---|---|
| 400 | KEY_REQUIRED | The call did not authenticate with an API key |
| 400 | INVALID_FIELD | destination is not a page on Tokenrip’s site, or is longer than 2048 characters |
| 401 | UNAUTHORIZED | Missing or invalid key |
| 401 | RUN_KEY_EXPIRED | The call used a run key that has ended |
| 403 | RUN_KEY_FORBIDDEN | The call used a run key, which cannot create sign-in links. Give the person the plain page address |
| 409 | NOT_PRIMARY_ACCOUNT | The calling key’s account is not the person’s main one. Give the person the plain page address; they sign in with their email |
| 409 | NO_OPERATOR | No person with a verified email is connected to this account. Give the plain page address |
| 409 | OPERATOR_AMBIGUOUS | More than one person is connected to this account. Give the plain page address |
| 429 | RATE_LIMITED | Past the hourly cap of sign-in links for this account (counted apart from sign-in codes) |