List User Pats
curl --request GET \
--url https://api.example.com/user-pats \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.example.com/user-pats"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.example.com/user-pats', 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/user-pats",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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/user-pats"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/user-pats")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/user-pats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"name": "<string>",
"value": "<string>",
"created_at": "<string>",
"expires_at": "<string>"
}
]PATs
List User Personal Access Tokens
GET
/
user-pats
List User Pats
curl --request GET \
--url https://api.example.com/user-pats \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.example.com/user-pats"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.example.com/user-pats', 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/user-pats",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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/user-pats"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/user-pats")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/user-pats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"name": "<string>",
"value": "<string>",
"created_at": "<string>",
"expires_at": "<string>"
}
]User PATs (
pat_…) are Logto-native personal access tokens with no local database row at all — see Authentication for how they differ from organization API keys. They’re addressed by name, not id, and names must be unique per user. None of the other seven PAT/key management endpoints require a dedicated manage scope — a PAT or key is inherently scoped to the caller’s own identity, so any authenticated request can call them.
Scoped to the caller’s own Logto user id — organization context is irrelevant here, since user PATs aren’t org-bound. This reads straight from Logto’s personal-access-token list for the caller, filtered to names carrying the pat_ prefix this app uses internally (org API keys are backed by Logto PATs too, but named differently, so they don’t leak into this list).
The
value field below is whatever Logto’s Management API returns for each token on this call. Because user PATs are entirely Logto-managed (no local hash-and-discard step like ak_ keys), this reference cannot promise it’s a one-time reveal the way pat_key on org keys is — treat any value you receive as sensitive and avoid depending on repeat calls continuing to return it.Auth
Requirespats:read, which every default role carries. This reads the caller’s own Logto personal access tokens, keyed on the token’s subject — there is no way to read another member’s, not even as an org admin. No active organization is needed either: user PATs aren’t org-bound.
Response
200 OK — a bare JSON array.
| Field | Type | Description |
|---|---|---|
name | string | Token name with the internal pat_ storage prefix stripped. |
value | string | The token value as returned by Logto for this call. |
created_at | string | null | ISO 8601 timestamp. |
expires_at | string | null | ISO 8601 timestamp, or null if the token never expires. |