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 Response
  • 422Validation Error
POST /api/v1/auth/pat/request
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 Response
  • 422Validation Error
POST /api/v1/auth/pat/request-by-email
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 Response
  • 422Validation Error
GET /api/v1/auth/pat/request/{request_id}/status
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 Response
  • 422Validation Error
GET /api/v1/auth/pat/request/{request_id}/approve
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 Response
  • 422Validation Error
GET /api/v1/auth/pat/request/{request_id}/deny
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 Response
  • 422Validation Error
DELETE /api/v1/auth/pat/{token_id}
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 Response
  • 422Validation Error
GET /api/v1/auth/pat/agents
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
GET /api/v1/auth/pat/status
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()
}