curl -X POST "https://api.tktchurch.com/v1/devices/users/123e4567-e89b-12d3-a456-426614174000/revoke-all" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const revokeAllUserDevices = async (accessToken, userId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/devices/users/${userId}/revoke-all`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.status === 204;
};
// Usage
try {
await revokeAllUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('All devices revoked successfully');
} catch (error) {
console.error('Failed to revoke devices:', error.message);
}
func revokeAllUserDevices(accessToken: String, userId: UUID) async throws {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/devices/users/\(userId)/revoke-all")!)
urlRequest.httpMethod = "POST"
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (_, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 204 {
throw URLError(.badServerResponse)
}
}
// Usage
do {
try await revokeAllUserDevices(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
userId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("All devices revoked successfully")
} catch {
print("Failed to revoke devices: \(error.localizedDescription)")
}
class DeviceService(private val client: OkHttpClient) {
suspend fun revokeAllUserDevices(accessToken: String, userId: String) {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/devices/users/$userId/revoke-all")
.post(RequestBody.create(null, ByteArray(0)))
.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 revoke devices")
}
}
}
}
// Usage
try {
deviceService.revokeAllUserDevices(
"eyJhbGciOiJIUzI1NiIs...", // access token
"123e4567-e89b-12d3-a456-426614174000" // user ID
)
println("All devices revoked successfully")
} catch (e: Exception) {
println("Failed to revoke devices: ${e.message}")
}
import axios from 'axios';
const revokeAllUserDevices = async (
accessToken: string,
userId: string
): Promise<void> => {
try {
await axios.post(
`https://api.tktchurch.com/v1/devices/users/${userId}/revoke-all`,
null,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to revoke devices');
}
throw error;
}
};
// Usage
try {
await revokeAllUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('All devices revoked successfully');
} catch (error) {
console.error('Failed to revoke devices:', error.message);
}
{
"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
Revoke All User Devices
Revoke access for all devices belonging to a user except the current one
POST
/
devices
/
users
/
{userId}
/
revoke-all
curl -X POST "https://api.tktchurch.com/v1/devices/users/123e4567-e89b-12d3-a456-426614174000/revoke-all" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const revokeAllUserDevices = async (accessToken, userId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/devices/users/${userId}/revoke-all`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.status === 204;
};
// Usage
try {
await revokeAllUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('All devices revoked successfully');
} catch (error) {
console.error('Failed to revoke devices:', error.message);
}
func revokeAllUserDevices(accessToken: String, userId: UUID) async throws {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/devices/users/\(userId)/revoke-all")!)
urlRequest.httpMethod = "POST"
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (_, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 204 {
throw URLError(.badServerResponse)
}
}
// Usage
do {
try await revokeAllUserDevices(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
userId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("All devices revoked successfully")
} catch {
print("Failed to revoke devices: \(error.localizedDescription)")
}
class DeviceService(private val client: OkHttpClient) {
suspend fun revokeAllUserDevices(accessToken: String, userId: String) {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/devices/users/$userId/revoke-all")
.post(RequestBody.create(null, ByteArray(0)))
.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 revoke devices")
}
}
}
}
// Usage
try {
deviceService.revokeAllUserDevices(
"eyJhbGciOiJIUzI1NiIs...", // access token
"123e4567-e89b-12d3-a456-426614174000" // user ID
)
println("All devices revoked successfully")
} catch (e: Exception) {
println("Failed to revoke devices: ${e.message}")
}
import axios from 'axios';
const revokeAllUserDevices = async (
accessToken: string,
userId: string
): Promise<void> => {
try {
await axios.post(
`https://api.tktchurch.com/v1/devices/users/${userId}/revoke-all`,
null,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to revoke devices');
}
throw error;
}
};
// Usage
try {
await revokeAllUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('All devices revoked successfully');
} catch (error) {
console.error('Failed to revoke devices:', error.message);
}
{
"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 revoke
Response
A successful request returns HTTP 204 No Content status. The following actions are performed:- If the current device belongs to the target user, it is preserved
- All other refresh tokens for the user are blacklisted
- All associated access tokens are blacklisted
- The blacklisted tokens are removed from the database
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 POST "https://api.tktchurch.com/v1/devices/users/123e4567-e89b-12d3-a456-426614174000/revoke-all" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const revokeAllUserDevices = async (accessToken, userId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/devices/users/${userId}/revoke-all`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.status === 204;
};
// Usage
try {
await revokeAllUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('All devices revoked successfully');
} catch (error) {
console.error('Failed to revoke devices:', error.message);
}
func revokeAllUserDevices(accessToken: String, userId: UUID) async throws {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/devices/users/\(userId)/revoke-all")!)
urlRequest.httpMethod = "POST"
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (_, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 204 {
throw URLError(.badServerResponse)
}
}
// Usage
do {
try await revokeAllUserDevices(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
userId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("All devices revoked successfully")
} catch {
print("Failed to revoke devices: \(error.localizedDescription)")
}
class DeviceService(private val client: OkHttpClient) {
suspend fun revokeAllUserDevices(accessToken: String, userId: String) {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/devices/users/$userId/revoke-all")
.post(RequestBody.create(null, ByteArray(0)))
.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 revoke devices")
}
}
}
}
// Usage
try {
deviceService.revokeAllUserDevices(
"eyJhbGciOiJIUzI1NiIs...", // access token
"123e4567-e89b-12d3-a456-426614174000" // user ID
)
println("All devices revoked successfully")
} catch (e: Exception) {
println("Failed to revoke devices: ${e.message}")
}
import axios from 'axios';
const revokeAllUserDevices = async (
accessToken: string,
userId: string
): Promise<void> => {
try {
await axios.post(
`https://api.tktchurch.com/v1/devices/users/${userId}/revoke-all`,
null,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to revoke devices');
}
throw error;
}
};
// Usage
try {
await revokeAllUserDevices(
'eyJhbGciOiJIUzI1NiIs...', // access token
'123e4567-e89b-12d3-a456-426614174000' // user ID
);
console.log('All devices revoked successfully');
} catch (error) {
console.error('Failed to revoke devices:', error.message);
}
{
"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"
}
}
