<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-M74D8PB" height="0" width="0" style="display:none;visibility:hidden">
Loading
Skip to NavigationSkip to Main Content
Create a CSV Report of Devices and Enrolled Users Using an API
Okta Identity Engine
Multi-Factor Authentication
Overview

This article provides steps to create a CSV report of users and their registered devices using the API and Postman.

Applies To
  • Okta Identity Engine (OIE)
  • API
  • Devices
  • Okta Reports
Solution

To generate the report, an API call must be configured and executed in Postman, followed by a script that processes the response data.

  1. Configure the API request. There are two methods to create the GET call:
    • Method 1: Direct Creation
      • Use the GET method on the following endpoint: https://<yourdomain>.okta.com/api/v1/devices?expand=userSummary.
    • Method 2: Using Postman Collection
      1. Import the Devices collection from the Okta Postman Collections page.
      2. Duplicate the GET all devices request.
      3. Modify the request URL from {{url}}/api/v1/devices to {{url}}/api/v1/devices?expand=userSummary.
  2. Under Headers, add the following key-value pairs:
    • ACCEPT: application/json
    • Content-Type: application/json
    • Authorization: SSWS {{apikey}}. NOTE: The {{apikey}} value is the token generated in the Admin Console under Security > API > Tokens.Postman  
  3. The API call returns a raw JavaScript Object Notation (JSON) body response containing details for all devices and their associated users.
  4. To format this JSON response into a filtered table, navigate to the Scripts tab in Postman and create a post-response script.
  5. Send the API to generate the report. The CSV table is in the response Body under the Visualize tab.

Postman  

Example of a post-response script: 

const template = `
    <style>
        body { font-family: sans-serif; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; vertical-align: top; }
        th { background-color: #f2f2f2; }
        tr:nth-child(even) { background-color: #f9f9f9; }
        pre { margin: 0; background-color: #eee; padding: 5px; border-radius: 4px; white-space: pre-wrap; word-break: break-all; }
    </style>

    <h2>Filtered Device Report</h2>
    <table>
        <thead>
            <tr>
                <th>User Login</th>
                <th>Device ID</th>
                <th>Device Profile (JSON)</th>
            </tr>
        </thead>
        <tbody>
            {{#each devices}}
                <tr>
                    <td>{{userLogin}}</td>
                    <td>{{id}}</td>
                    <td><pre><code>{{profile}}</code></pre></td>
                </tr>
            {{/each}}
        </tbody>
    </table>
`;


if (pm.response.code === 200) {
    console.log("Request was successful (200 OK). Processing response...");
    
    
    const responseData = pm.response.json();
    
    
    if (Array.isArray(responseData) && responseData.length > 0) {
        console.log("Found " + responseData.length + " devices in this response page.");
        
        const flattenedData = responseData.flatMap(device => {
            const users = device._embedded?.users || [];
            
            
            if (users.length === 0) {
                return [{
                    id: device.id,
                    profile: JSON.stringify(device.profile, null, 2),
                    userLogin: "N/A"
                }];
            }
            
            
            
            return users.map(userEntry => {
                return {
                    id: device.id,
                    profile: JSON.stringify(device.profile, null, 2),
                    userLogin: userEntry.user?.profile?.login || "N/A"
                };
            });
        });
        
        console.log("Data successfully flattened. Total rows created:", flattenedData.length);
        console.log("First data object:", flattenedData[0]);

        
        pm.visualizer.set(template, { devices: flattenedData });
        console.log("Visualizer data set. Click the 'Visualize' tab to see the report.");

    } else {
        console.warn("Response was successful, but contained no device data.");
        pm.visualizer.set("<h3>Response is empty. No devices found on this page.</h3>");
    }
} else {
   
    console.error("API request failed with status code: " + pm.response.code);
    console.error("Response Body:", pm.response.text());
    pm.visualizer.set(`
        <h2 style="color:red;">API Request Failed</h2>
        <p><b>Status:</b> ${pm.response.code} ${pm.response.status}</p>
        <p>Check the Postman Console for more details.</p>
    `);
}

 

NOTE: If a rate limit error occurs, use the Postman runner and stop at the device rate limit specified in the tenant. Alternatively, use pagination by following this pagination guide.

Loading
Create a CSV Report of Devices and Enrolled Users Using an API