PAT Authentication
Base URL
https://api.example.com
POST
/api/v1/auth/pat/request
Request API access
Agent requests API access. Sends approval email to admin. Returns poll_token for status checking.
Responses
200Successful Response422Validation Error
curl -X POST 'https://api.example.com/api/v1/auth/pat/request' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
-d '{
"client_id": "string",
"owner_email": "user@example.com",
"project_name": "string",
"requested_scopes": [
"jobs:submit",
"jobs:read",
"content:read",
"content:write",
"content:deploy"
],
"ttl_hours": 72,
"fingerprint": {
"agent_type": "unknown",
"hostname": "string",
"cwd": "string",
"platform": "string",
"node_version": "string",
"project_name": "string"
},
"multi_brand": false
}'
import httpx
resp = httpx.post(
"https://api.example.com/api/v1/auth/pat/request",
headers={"Authorization": "Bearer ", "Content-Type": "application/json"},
json={"client_id": "string", "owner_email": "user@example.com", "project_name": "string", "requested_scopes": ["jobs:submit", "jobs:read", "content:read", "content:write", "content:deploy"], "ttl_hours": 72, "fingerprint": {"agent_type": "unknown", "hostname": "string", "cwd": "string", "platform": "string", "node_version": "string", "project_name": "string"}, "multi_brand": false},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/request", {
method: "POST",
headers: { "Authorization": "Bearer ", "Content-Type": "application/json" },
body: JSON.stringify({"client_id": "string", "owner_email": "user@example.com", "project_name": "string", "requested_scopes": ["jobs:submit", "jobs:read", "content:read", "content:write", "content:deploy"], "ttl_hours": 72, "fingerprint": {"agent_type": "unknown", "hostname": "string", "cwd": "string", "platform": "string", "node_version": "string", "project_name": "string"}, "multi_brand": false})
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"client_id": "string", "owner_email": "user@example.com", "project_name": "string", "requested_scopes": ["jobs:submit", "jobs:read", "content:read", "content:write", "content:deploy"], "ttl_hours": 72, "fingerprint": {"agent_type": "unknown", "hostname": "string", "cwd": "string", "platform": "string", "node_version": "string", "project_name": "string"}, "multi_brand": false}`)
req, _ := http.NewRequest("POST", "https://api.example.com/api/v1/auth/pat/request", body)
req.Header.Set("Authorization", "Bearer ")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
Request body
{"client_id":"string","ttl_hours":72,"fingerprint":{"cwd":"string","hostname":"string","platform":"string","agent_type":"unknown","node_version":"string","project_name":"string"},"multi_brand":false,"owner_email":"user@example.com","project_name":"string","requested_scopes":["jobs:submit","jobs:read","content:read","content:write","content:deploy"]}
POST
/api/v1/auth/pat/request-by-email
Request access by email only
Simplified flow - provide admin email only, discovers client automatically.
Responses
200Successful Response422Validation Error
curl -X POST 'https://api.example.com/api/v1/auth/pat/request-by-email' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
-d '{
"email": "user@example.com",
"project_name": "string",
"requested_scopes": [
"jobs:submit",
"jobs:read",
"content:read",
"content:write",
"content:deploy"
],
"ttl_hours": 72,
"fingerprint": {
"agent_type": "unknown",
"hostname": "string",
"cwd": "string",
"platform": "string",
"node_version": "string",
"project_name": "string"
},
"multi_brand": false,
"name": "string",
"description": "string",
"photo": "string",
"monthly_budget_usd": 0.0,
"rate_limit_rpm": 0,
"rate_limit_rpd": 0,
"allowed_models": [
"string"
]
}'
import httpx
resp = httpx.post(
"https://api.example.com/api/v1/auth/pat/request-by-email",
headers={"Authorization": "Bearer ", "Content-Type": "application/json"},
json={"email": "user@example.com", "project_name": "string", "requested_scopes": ["jobs:submit", "jobs:read", "content:read", "content:write", "content:deploy"], "ttl_hours": 72, "fingerprint": {"agent_type": "unknown", "hostname": "string", "cwd": "string", "platform": "string", "node_version": "string", "project_name": "string"}, "multi_brand": false, "name": "string", "description": "string", "photo": "string", "monthly_budget_usd": 0.0, "rate_limit_rpm": 0, "rate_limit_rpd": 0, "allowed_models": ["string"]},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/request-by-email", {
method: "POST",
headers: { "Authorization": "Bearer ", "Content-Type": "application/json" },
body: JSON.stringify({"email": "user@example.com", "project_name": "string", "requested_scopes": ["jobs:submit", "jobs:read", "content:read", "content:write", "content:deploy"], "ttl_hours": 72, "fingerprint": {"agent_type": "unknown", "hostname": "string", "cwd": "string", "platform": "string", "node_version": "string", "project_name": "string"}, "multi_brand": false, "name": "string", "description": "string", "photo": "string", "monthly_budget_usd": 0.0, "rate_limit_rpm": 0, "rate_limit_rpd": 0, "allowed_models": ["string"]})
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"email": "user@example.com", "project_name": "string", "requested_scopes": ["jobs:submit", "jobs:read", "content:read", "content:write", "content:deploy"], "ttl_hours": 72, "fingerprint": {"agent_type": "unknown", "hostname": "string", "cwd": "string", "platform": "string", "node_version": "string", "project_name": "string"}, "multi_brand": false, "name": "string", "description": "string", "photo": "string", "monthly_budget_usd": 0.0, "rate_limit_rpm": 0, "rate_limit_rpd": 0, "allowed_models": ["string"]}`)
req, _ := http.NewRequest("POST", "https://api.example.com/api/v1/auth/pat/request-by-email", body)
req.Header.Set("Authorization", "Bearer ")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
Request body
{"name":"string","email":"user@example.com","photo":"string","ttl_hours":72,"description":"string","fingerprint":{"cwd":"string","hostname":"string","platform":"string","agent_type":"unknown","node_version":"string","project_name":"string"},"multi_brand":false,"project_name":"string","allowed_models":["string"],"rate_limit_rpd":0,"rate_limit_rpm":0,"requested_scopes":["jobs:submit","jobs:read","content:read","content:write","content:deploy"],"monthly_budget_usd":0}
GET
/api/v1/auth/pat/request/{request_id}/status
Poll for approval status
CLI polls this endpoint every 3 seconds while waiting for admin approval.
Parameters
request_id
string
path
required
poll_token
string
query
required
Poll token from initial request
Responses
200Successful Response422Validation Error
curl -X GET 'https://api.example.com/api/v1/auth/pat/request/{request_id}/status' \
-H 'Authorization: Bearer '
import httpx
resp = httpx.get(
"https://api.example.com/api/v1/auth/pat/request/{request_id}/status",
headers={"Authorization": "Bearer "},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/request/{request_id}/status", {
method: "GET",
headers: { "Authorization": "Bearer " }
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.example.com/api/v1/auth/pat/request/{request_id}/status", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
GET
/api/v1/auth/pat/request/{request_id}/approve
Approve access request
Admin clicks this link in the approval email to grant access.
Parameters
request_id
string
path
required
approval_token
string
query
required
Approval token from email
Responses
200Successful Response422Validation Error
curl -X GET 'https://api.example.com/api/v1/auth/pat/request/{request_id}/approve' \
-H 'Authorization: Bearer '
import httpx
resp = httpx.get(
"https://api.example.com/api/v1/auth/pat/request/{request_id}/approve",
headers={"Authorization": "Bearer "},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/request/{request_id}/approve", {
method: "GET",
headers: { "Authorization": "Bearer " }
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.example.com/api/v1/auth/pat/request/{request_id}/approve", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
GET
/api/v1/auth/pat/request/{request_id}/deny
Deny access request
Admin clicks this link in the approval email to deny access.
Parameters
request_id
string
path
required
approval_token
string
query
required
Approval token from email
Responses
200Successful Response422Validation Error
curl -X GET 'https://api.example.com/api/v1/auth/pat/request/{request_id}/deny' \
-H 'Authorization: Bearer '
import httpx
resp = httpx.get(
"https://api.example.com/api/v1/auth/pat/request/{request_id}/deny",
headers={"Authorization": "Bearer "},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/request/{request_id}/deny", {
method: "GET",
headers: { "Authorization": "Bearer " }
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.example.com/api/v1/auth/pat/request/{request_id}/deny", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
DELETE
/api/v1/auth/pat/{token_id}
Revoke an agent token
Revoke a specific agent token. Requires authentication.
Parameters
token_id
string
path
required
Responses
200Successful Response422Validation Error
curl -X DELETE 'https://api.example.com/api/v1/auth/pat/{token_id}' \
-H 'Authorization: Bearer '
import httpx
resp = httpx.delete(
"https://api.example.com/api/v1/auth/pat/{token_id}",
headers={"Authorization": "Bearer "},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/{token_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer " }
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.example.com/api/v1/auth/pat/{token_id}", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
GET
/api/v1/auth/pat/agents
List agent tokens
List all agent tokens for the authenticated client. Admin can see all.
Parameters
client_id
any
query
Filter by client (admin only)
include_inactive
boolean
query
Include revoked/expired tokens
Responses
200Successful Response422Validation Error
curl -X GET 'https://api.example.com/api/v1/auth/pat/agents' \
-H 'Authorization: Bearer '
import httpx
resp = httpx.get(
"https://api.example.com/api/v1/auth/pat/agents",
headers={"Authorization": "Bearer "},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/agents", {
method: "GET",
headers: { "Authorization": "Bearer " }
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.example.com/api/v1/auth/pat/agents", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
GET
/api/v1/auth/pat/status
Check authentication status
Check if the current token is valid and return its info.
Responses
200Successful Response
curl -X GET 'https://api.example.com/api/v1/auth/pat/status' \
-H 'Authorization: Bearer '
import httpx
resp = httpx.get(
"https://api.example.com/api/v1/auth/pat/status",
headers={"Authorization": "Bearer "},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://api.example.com/api/v1/auth/pat/status", {
method: "GET",
headers: { "Authorization": "Bearer " }
});
const data = await resp.json();
console.log(data);
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.example.com/api/v1/auth/pat/status", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}
Ask AI