curl -X GET "https://api.tktchurch.com/v1/auth/devices/users/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const listUserDevices = async (accessToken, userId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/devices/users/${userId}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.json();
};
// Usage
try {
const devices = await listUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('User devices:', devices);
} catch (error) {
console.error('Failed to list devices:', error.message);
}
func listUserDevices(accessToken: String, userId: UUID) async throws -> [Device] {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/devices/users/\(userId)")!)
urlRequest.httpMethod = "GET"
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw error
}
return try JSONDecoder().decode([Device].self, from: data)
}
// Usage
do {
let devices = try await listUserDevices(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
userId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("User devices:", devices)
} catch {
print("Failed to list devices: \(error.localizedDescription)")
}
class DeviceService(private val client: OkHttpClient) {
suspend fun listUserDevices(accessToken: String, userId: String): List<Device> {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/devices/users/$userId")
.get()
.header("Authorization", "Bearer $accessToken")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
val error = response.body?.string()?.fromJson<ErrorResponse>()
throw Exception(error?.reason ?: "Failed to list devices")
}
return response.body?.string()?.fromJson<List<Device>>()
?: throw Exception("Empty response")
}
}
}
// Usage
try {
val devices = deviceService.listUserDevices(
"eyJhbGciOiJIUzI1NiIs...", // access token
"123e4567-e89b-12d3-a456-426614174000" // user ID
)
println("User devices: $devices")
} catch (e: Exception) {
println("Failed to list devices: ${e.message}")
}
import axios from 'axios';
interface DeviceInfo {
deviceId?: string;
deviceType: 'mobile' | 'tablet' | 'desktop' | 'other';
deviceName?: string;
deviceModel?: string;
osName?: string;
osVersion?: string;
appVersion?: string;
ipAddress?: string;
userAgent?: string;
lastLocation?: string;
}
interface Device {
id: string;
deviceInfo?: DeviceInfo;
lastUsedAt: string;
createdAt?: string;
expiresAt: string;
}
const listUserDevices = async (accessToken: string, userId: string): Promise<Device[]> => {
try {
const response = await axios.get(
`https://api.tktchurch.com/v1/devices/users/${userId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to list devices');
}
throw error;
}
};
// Usage
try {
const devices = await listUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('User devices:', devices);
} catch (error) {
console.error('Failed to list devices:', error.message);
}
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"deviceInfo": {
"deviceId": "device123",
"deviceType": "mobile",
"deviceName": "iPhone 13",
"deviceModel": "iPhone13,2",
"osName": "iOS",
"osVersion": "16.0",
"appVersion": "1.0.0",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"lastLocation": "New York, US"
},
"lastUsedAt": "2024-01-20T08:30:00Z",
"createdAt": "2024-01-01T00:00:00Z",
"expiresAt": "2024-02-01T00:00:00Z"
}
]
{
"error": {
"status": 400,
"reason": "Invalid user ID"
}
}
{
"error": {
"status": 401,
"reason": "Invalid or expired access token"
}
}
{
"error": {
"status": 403,
"reason": "Insufficient permissions"
}
}
{
"error": {
"status": 404,
"reason": "User not found"
}
}
Devices
List User Devices
List all active devices for a specific user
GET
/
devices
/
users
/
{userId}
curl -X GET "https://api.tktchurch.com/v1/auth/devices/users/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const listUserDevices = async (accessToken, userId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/devices/users/${userId}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.json();
};
// Usage
try {
const devices = await listUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('User devices:', devices);
} catch (error) {
console.error('Failed to list devices:', error.message);
}
func listUserDevices(accessToken: String, userId: UUID) async throws -> [Device] {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/devices/users/\(userId)")!)
urlRequest.httpMethod = "GET"
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw error
}
return try JSONDecoder().decode([Device].self, from: data)
}
// Usage
do {
let devices = try await listUserDevices(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
userId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("User devices:", devices)
} catch {
print("Failed to list devices: \(error.localizedDescription)")
}
class DeviceService(private val client: OkHttpClient) {
suspend fun listUserDevices(accessToken: String, userId: String): List<Device> {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/devices/users/$userId")
.get()
.header("Authorization", "Bearer $accessToken")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
val error = response.body?.string()?.fromJson<ErrorResponse>()
throw Exception(error?.reason ?: "Failed to list devices")
}
return response.body?.string()?.fromJson<List<Device>>()
?: throw Exception("Empty response")
}
}
}
// Usage
try {
val devices = deviceService.listUserDevices(
"eyJhbGciOiJIUzI1NiIs...", // access token
"123e4567-e89b-12d3-a456-426614174000" // user ID
)
println("User devices: $devices")
} catch (e: Exception) {
println("Failed to list devices: ${e.message}")
}
import axios from 'axios';
interface DeviceInfo {
deviceId?: string;
deviceType: 'mobile' | 'tablet' | 'desktop' | 'other';
deviceName?: string;
deviceModel?: string;
osName?: string;
osVersion?: string;
appVersion?: string;
ipAddress?: string;
userAgent?: string;
lastLocation?: string;
}
interface Device {
id: string;
deviceInfo?: DeviceInfo;
lastUsedAt: string;
createdAt?: string;
expiresAt: string;
}
const listUserDevices = async (accessToken: string, userId: string): Promise<Device[]> => {
try {
const response = await axios.get(
`https://api.tktchurch.com/v1/devices/users/${userId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to list devices');
}
throw error;
}
};
// Usage
try {
const devices = await listUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('User devices:', devices);
} catch (error) {
console.error('Failed to list devices:', error.message);
}
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"deviceInfo": {
"deviceId": "device123",
"deviceType": "mobile",
"deviceName": "iPhone 13",
"deviceModel": "iPhone13,2",
"osName": "iOS",
"osVersion": "16.0",
"appVersion": "1.0.0",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"lastLocation": "New York, US"
},
"lastUsedAt": "2024-01-20T08:30:00Z",
"createdAt": "2024-01-01T00:00:00Z",
"expiresAt": "2024-02-01T00:00:00Z"
}
]
{
"error": {
"status": 400,
"reason": "Invalid user ID"
}
}
{
"error": {
"status": 401,
"reason": "Invalid or expired access token"
}
}
{
"error": {
"status": 403,
"reason": "Insufficient permissions"
}
}
{
"error": {
"status": 404,
"reason": "User not found"
}
}
This endpoint requires authentication and the
viewUserDevices permission.Path Parameters
string
required
The UUID of the user whose devices to list
Response
Returns an array of active devices. Each device represents a refresh token and its associated access token.string
Unique identifier for the token (UUID)
object
Information about the device
Show Device Info
Show Device Info
string
Unique identifier for the device
string
Type of device. One of:
mobile: Mobile phonetablet: Tablet devicedesktop: Desktop computerother: Other device type
string
Name of the device
string
Model of the device
string
Operating system name
string
Operating system version
string
Application version
string
IP address of the device
string
User agent string
string
Last known location of the device
string
Timestamp when the token was last used
string
Timestamp when the token was created
string
Timestamp when the token expires
Error Responses
object
Common error cases:
- 400 Bad Request: Invalid user ID format
- 401 Unauthorized: Missing or invalid access token
- 403 Forbidden: Insufficient permissions (missing viewUserDevices)
- 404 Not Found: User not found
curl -X GET "https://api.tktchurch.com/v1/auth/devices/users/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const listUserDevices = async (accessToken, userId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/devices/users/${userId}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.json();
};
// Usage
try {
const devices = await listUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('User devices:', devices);
} catch (error) {
console.error('Failed to list devices:', error.message);
}
func listUserDevices(accessToken: String, userId: UUID) async throws -> [Device] {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/devices/users/\(userId)")!)
urlRequest.httpMethod = "GET"
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw error
}
return try JSONDecoder().decode([Device].self, from: data)
}
// Usage
do {
let devices = try await listUserDevices(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
userId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("User devices:", devices)
} catch {
print("Failed to list devices: \(error.localizedDescription)")
}
class DeviceService(private val client: OkHttpClient) {
suspend fun listUserDevices(accessToken: String, userId: String): List<Device> {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/devices/users/$userId")
.get()
.header("Authorization", "Bearer $accessToken")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
val error = response.body?.string()?.fromJson<ErrorResponse>()
throw Exception(error?.reason ?: "Failed to list devices")
}
return response.body?.string()?.fromJson<List<Device>>()
?: throw Exception("Empty response")
}
}
}
// Usage
try {
val devices = deviceService.listUserDevices(
"eyJhbGciOiJIUzI1NiIs...", // access token
"123e4567-e89b-12d3-a456-426614174000" // user ID
)
println("User devices: $devices")
} catch (e: Exception) {
println("Failed to list devices: ${e.message}")
}
import axios from 'axios';
interface DeviceInfo {
deviceId?: string;
deviceType: 'mobile' | 'tablet' | 'desktop' | 'other';
deviceName?: string;
deviceModel?: string;
osName?: string;
osVersion?: string;
appVersion?: string;
ipAddress?: string;
userAgent?: string;
lastLocation?: string;
}
interface Device {
id: string;
deviceInfo?: DeviceInfo;
lastUsedAt: string;
createdAt?: string;
expiresAt: string;
}
const listUserDevices = async (accessToken: string, userId: string): Promise<Device[]> => {
try {
const response = await axios.get(
`https://api.tktchurch.com/v1/devices/users/${userId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to list devices');
}
throw error;
}
};
// Usage
try {
const devices = await listUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('User devices:', devices);
} catch (error) {
console.error('Failed to list devices:', error.message);
}
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"deviceInfo": {
"deviceId": "device123",
"deviceType": "mobile",
"deviceName": "iPhone 13",
"deviceModel": "iPhone13,2",
"osName": "iOS",
"osVersion": "16.0",
"appVersion": "1.0.0",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"lastLocation": "New York, US"
},
"lastUsedAt": "2024-01-20T08:30:00Z",
"createdAt": "2024-01-01T00:00:00Z",
"expiresAt": "2024-02-01T00:00:00Z"
}
]
{
"error": {
"status": 400,
"reason": "Invalid user ID"
}
}
{
"error": {
"status": 401,
"reason": "Invalid or expired access token"
}
}
{
"error": {
"status": 403,
"reason": "Insufficient permissions"
}
}
{
"error": {
"status": 404,
"reason": "User not found"
}
}
