> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tktchurch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Revoke All User Devices

> Revoke access for all devices belonging to a user except the current one

<Note>
  This endpoint requires authentication and the `viewUserDevices` permission.
</Note>

### Path Parameters

<ParamField path="userId" type="string" required>
  The UUID of the user whose devices to revoke
</ParamField>

### Response

A successful request returns HTTP 204 No Content status. The following actions are performed:

1. If the current device belongs to the target user, it is preserved
2. All other refresh tokens for the user are blacklisted
3. All associated access tokens are blacklisted
4. The blacklisted tokens are removed from the database

### Error Responses

<ResponseField name="error" type="object">
  Error details when the request fails

  <Expandable title="Error Object">
    <ResponseField name="status" type="integer">
      HTTP status code
    </ResponseField>

    <ResponseField name="reason" type="string">
      Error message explaining why the request failed
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  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
</Note>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.tktchurch.com/v1/devices/users/123e4567-e89b-12d3-a456-426614174000/revoke-all" \
    -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
  ```

  ```javascript JavaScript theme={null}
  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);
  }
  ```

  ```swift Swift theme={null}
  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)")
  }
  ```

  ```kotlin Kotlin theme={null}
  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}")
  }
  ```

  ```typescript React Native theme={null}
  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);
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 204 No Content theme={null}
  ```

  ```json 400 Bad Request theme={null}
  {
    "error": {
      "status": 400,
      "reason": "Invalid user ID"
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "status": 401,
      "reason": "Invalid or expired access token"
    }
  }
  ```

  ```json 403 Forbidden theme={null}
  {
    "error": {
      "status": 403,
      "reason": "Insufficient permissions"
    }
  }
  ```

  ```json 404 Not Found theme={null}
  {
    "error": {
      "status": 404,
      "reason": "User not found"
    }
  }
  ```
</ResponseExample>
