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

# runZero

> The runZero integration enables AirMDR to retrieve asset inventory and discovery data from a selected runZero organization. This information can support asset investigation, enrichment, exposure analysis, and security operations.

<AccordionGroup>
  <Accordion title="Purpose">
    To connect AirMDR to runZero to retrieve organization-scoped asset, site, and scan information through the runZero Export API.
  </Accordion>

  <Accordion title="Supported Versions">
    | Component | Supported configuration |
    | - | - |
    | runZero Cloud | Supported through the runZero HTTPS API |
    | Self-hosted runZero | Supported when AirMDR can reach the console URL |
    | Export API | `/api/v1.0/export` endpoints |
    | Authentication | Bearer token |
    | Recommended token | Organization-scoped Export token |
    | Organization API token | Supported only if the connector accepts it; provides broader access |
    | Account API token | Requires a runZero Platform license and an Organization ID |
    | Transport | HTTPS |
    | Data formats | JSON and CSV, depending on the endpoint |

    <Note>
      runZero states that the Export API provides read-only access to organization data. Organization API access requires a Professional or Platform license, while Account API access requires a Platform license.
    </Note>

    <Check>
      Use an Export token unless AirMDR explicitly requires organization-level write operations.
    </Check>
  </Accordion>

  <Accordion title="Authentication">
    runZero APIs use bearer-token authentication.

    ```http theme={null}
    Authorization: Bearer <RUNZERO_API_TOKEN>
    ```

    ### Supported token types

    | Token type | Scope | Access | Organization ID required | Recommended for AirMDR |
    | - | - | - | - | - |
    | Export token | One organization | Export API only; read-only | No | Yes |
    | Organization API token | One organization | Organization API and Export API; read/write | No | Only when write access is required |
    | Account API token | Entire account | Account, organization, and export APIs; read/write | Yes, for organization-specific requests | No |
    | API client credentials | Entire account | Generates account access tokens through OAuth 2.0 | Yes, when accessing organization data | No |
    | Download token | One organization | Explorer downloads only | No | No |

    ### Role and access considerations

    * The user generating the token must be permitted to edit the selected runZero organization.
    * Use an organization-scoped Export token for read-only AirMDR operations.
    * Do not use a Download token because it cannot access inventory data.
    * Avoid an Account API token unless there is a confirmed requirement for account-wide access.
    * If using an Account API token, enter the organization’s unique ID in the AirMDR **Organization ID** field.
    * Restrict API access through the runZero IP allowlist when AirMDR has known static egress addresses.
  </Accordion>
</AccordionGroup>

## Pre-requisites

> <Check>
>   An active runZero organization access.
> </Check>
>
> <Check>
>   Permission to edit the selected organization or request a token from a runZero administrator.
> </Check>

## Setup Steps

<Steps>
  <Step title="Generate a runZero Export token">
    1. Sign in to the runZero Console.
       * For the runZero cloud console, use: [https://console.runzero.com](https://console.runzero.com)
       * For a self-hosted deployment, use your organization’s runZero Console URL.
    2. From the runZero navigation menu, select **Organizations**.
    3. Select the organization that AirMDR must query.
           <Info>
             Export tokens are limited to the organization from which they are generated.
           </Info>
    4. On the organization details page, select **Edit organization**.
    5. Scroll to the **Export tokens** section.
    6. Select the option to generate an Export token.

       If an Export token already exists, runZero may display an option to regenerate it.

           <Warning>
             Regenerating a token can invalidate the credential used by existing integrations. Confirm its current usage before regenerating it.
           </Warning>
    7. Copy the generated token.
    8. Store the token temporarily in an approved password manager or secrets-management system.
    9. Do not include the token in tickets, screenshots, emails, chat messages, or documentation.

           <Note>
             The [token-type](https://help.runzero.com/docs/leveraging-the-api/?utm_source=chatgpt.com) section of runZero’s identifies Export tokens with an `ET` prefix, while some examples on the same page display an `XT` placeholder.

             <Check>
               Select the token explicitly generated from the organization’s **Export tokens** section instead of validating it only by its prefix
             </Check>
           </Note>
  </Step>

  <Step title="Find the runZero Console URL">
    1. Use the URL that your browser uses to access runZero.
       * **runZero Cloud**: [https://console.runzero.com](https://console.runzero.com)
       * **Self-hosted runZero**: [https://runzero.example.com](https://runzero.example.com)
    2. Enter only the base console URL. Do not add an API endpoint such as `/api/v1.0/export`.<br />Example: Enter `https://console.runzero.com`, not `https://console.runzero.com/api/v1.0/export/org/assets.json`.
  </Step>

  <Step title="Find the Organization ID">
    The Organization ID is normally unnecessary when using an organization-scoped Export token or Organization API token because the organization is encoded in the credential.

    The Organization ID is required when using an Account API token.

    To locate it:

    1. Sign in to the runZero Console.
    2. Select **Organizations**.
    3. Open the organization that AirMDR must query.
    4. Locate the unique organization ID on the organization information page.
    5. Copy the ID without adding spaces.
           <Note>
             Leave the AirMDR **Organization ID** field empty when using an Export token unless the AirMDR connector validation specifically requires it.
           </Note>
  </Step>

  <Step title="Configure the API IP address allowlist">
    Complete these steps only when the runZero API allowlist is enabled.

    1. Obtain the approved AirMDR egress IP addresses.
    2. In runZero, open **Account settings**.
    3. Locate **API key IP address allowlist**.
    4. Add the AirMDR egress IP addresses or CIDR ranges.
    5. Separate multiple values with commas.
    6. Save the account settings.<br />Example: 203.0.113.10/32, 203.0.113.11/32
           <Info>
             The allowlist applies to API requests across the runZero console. If AirMDR’s source address is not allowed, runZero rejects the request even when the token is valid. An empty allowlist disables this restriction.
           </Info>
  </Step>
</Steps>

## runZero Credential Reference Table

| AirMDR Field | What to Enter | Where to Get It in the runZero UI | Example |
| - | - | - | - |
| **Instance** | A unique name for the runZero connection | User-defined in AirMDR | `runZero-Production` |
| **Organization** | The AirMDR organization associated with the integration | Select the appropriate organization from the AirMDR **Organization** list | `AirMDR Organization` |
| **Description** | A brief description of the connection | User-defined in AirMDR | `runZero production integration` |
| **API Token** | An organization-scoped runZero **Export token** for read-only API access | In runZero, navigate to **Organizations**, select the required organization, click **Edit organization**, and generate a token under **Export tokens** | `<RUNZERO_EXPORT_TOKEN>` |
| **Console URL** | The base URL of the runZero cloud or self-hosted console. Do not include an API endpoint path | Copy the base URL displayed in the browser while signed in to the runZero Console | Cloud: `https://console.runzero.com` |
| **Organization ID** | The unique runZero organization ID. Required when using an Account API token; normally not required for an organization-scoped Export token | Navigate to **Organizations** and open the required organization’s information page | `2a74d1e0-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
| **Verify SSL** | Whether AirMDR must verify the runZero Console’s TLS certificate. Enable this for production connections | Security setting configured in AirMDR | `true` |

<Note>
  Use an organization-scoped **Export token** for the AirMDR integration because it provides read-only access to the selected runZero organization. Leave **Organization ID** empty unless you are using an Account API token or AirMDR validation explicitly requires it.
</Note>

## Validate Connectivity

Use the following request to retrieve the organization’s sites:

<AccordionGroup>
  <Accordion title="Sample Request">
    ```json theme={null}
    export RUNZERO_CONSOLE_URL="https://console.runzero.com"
    export RUNZERO_EXPORT_TOKEN="<RUNZERO_EXPORT_TOKEN>"

    curl --request GET \
      "${RUNZERO_CONSOLE_URL}/api/v1.0/export/org/sites.json" \
      --header "Authorization: Bearer ${RUNZERO_EXPORT_TOKEN}" \
      --header "Accept: application/json"
    ```
  </Accordion>

  <Accordion title="Sample Response">
    ```json theme={null}
    A successful request returns JSON data from the organization associated with the token.
    ```
  </Accordion>
</AccordionGroup>

<Tip>
  Do not run commands containing production tokens on shared systems. Clear the environment variable after testing.
</Tip>

## Configure runZero in AirMDR Integrations Dashboard

1. Navigate to [AirMDR](https://app.airmdr.com/auth/login), provide the credentials and click **Login**
2. Navigate to the AirMDR Integrations Dashboard in the left navigation pane and select **ADMIN → Integrations**.
3. Use the search option, enter the keyword "**runZero**", select the **Connections** tab, and click **+ New Connection** button.
4. Use the following values in the AirMDR integration configuration screen:
   | AirMDR field | Required | Description | Example |
   | :- | -: | :- | :- |
   | **Instance** | Yes | Unique name for the connection | `runZero-Production` |
   | **Organization** | Yes | AirMDR organization that owns the connection | `ASO – AirMDR System Organization` |
   | **Description** | Yes | Brief purpose of the integration | `Read-only runZero asset inventory integration` |
   | **API Token** | Yes | Export token generated for the selected runZero organization | `<stored securely>` |
   | **Console URL** | Conditional | Base URL of the runZero console; use the cloud URL or your self-hosted URL | `https://console.runzero.com` |
   | **Organization ID** | Conditional | Unique runZero organization ID; required for an Account API token | `2a74d1e0-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
   | **Verify SSL** | Recommended | Enables validation of the console’s TLS certificate | `true` |
5. Set **Verify SSL** to `true`.
6. Confirm that the API token belongs to the correct runZero organization.
7. Select **Save**.
8. Run the available connection test or a read-only skill to confirm that AirMDR can retrieve data.
   <Tip>
     Keep **Verify SSL** enabled for production connections. Disable certificate validation only for controlled troubleshooting and restore it immediately afterward.
   </Tip>

## Skills provided by this Integration

<AccordionGroup>
  <Accordion title="Inventory and Discovery">
    These read-only skills retrieve AI asset inventories, discovered tools, and web-domain activity.

    | Skill ID | Purpose | Minimum Pluto Role | Required Access |
    | - | - | - | - |
    | `get_pluto_inventory` | Retrieves records from Pluto’s AI inventories, including builders, applications, MCP servers, browser extensions, AI assistants, AI models, skills, VPNs, remote-access tools, and packages. | API user with inventory-view access | Read access to the selected Pluto inventory type |
    | `get_pluto_discovered_tools` | Retrieves the organization’s discovered-tool catalogue and associated approval tags, including **Approved**, **Rejected**, and **In Review**. | API user with discovered-tool access | Read access to discovered tools and their tags |
    | `get_pluto_web_domain_summary` | Summarizes web domains accessed by AI agents, including allowed and blocked activity and unique-user counts. | API user with agent-activity access | Read access to web-domain activity and policy results |

    <Note>
      When retrieving inventory for a specific system or user, provide `hostname` or `user_email` to limit the result set.
    </Note>
  </Accordion>

  <Accordion title="Issue Investigation and Response">
    These skills retrieve Pluto security issues and write investigation outcomes back to Pluto.

    | Skill ID | Purpose | Minimum Pluto Role | Required Access |
    | - | - | - | - |
    | `get_pluto_issues` | Retrieves Pluto security issues for investigation and supports filtering by duration, status, severity, issue type, server, or entity. | API user with issue-view access | Read access to Pluto issues and affected-host information |
    | `update_pluto_issue` | Updates an issue’s status, risk level, or assignees after investigation. | API user authorized to modify issues | Write access to issue status, risk level, and assignee fields |
    | `manage_pluto_issue_comment` | Creates, updates, or deletes investigation comments in the Pluto issue timeline. | API user authorized to manage issue comments | Write access to issue comments |

    <Note>
      In `update_pluto_issue`, `assignee_emails` and `assignee_ids` replace the existing assignee list. Use `clear_assignees` to remove all existing assignees.
    </Note>
  </Accordion>

  <Accordion title="AI Agent Activity and Audit">
    These read-only skills support investigation of AI coding-agent activity and organization-level audit events.

    | Skill ID | Purpose | Minimum Pluto Role | Required Access |
    | - | - | - | - |
    | `get_pluto_claude_code_session_events` | Retrieves Claude Code session events, including prompts, tool results, API requests, errors, permission decisions, token usage, and endpoint context. | API user with Claude Code activity access | Read access to Claude Code session events |
    | `get_pluto_agentic_tool_hook_events` | Retrieves hook events from supported AI coding tools, including Claude Code, Cursor, Codex, Windsurf, VS Code, and Copilot Studio. | API user with agent-event access | Read access to agent hook events and policy decisions |
    | `get_pluto_audit_log` | Retrieves Pluto audit activity such as logins, policy changes, tag updates, integration changes, automation changes, issue updates, and data access. | API user with audit-log access | Read access to the Pluto organization audit log |

    <Note>
      Pluto rejects Claude Code session-event and agentic-hook queries with a time window greater than 14 days. Use a duration of `14d` or less.
    </Note>
  </Accordion>

  <Accordion title="Governance and Inventory Management">
    These skills manage approval tags, inventory metadata, and organization-level business context.

    | Skill ID | Purpose | Minimum Pluto Role | Required Access |
    | - | - | - | - |
    | `manage_pluto_tags` | Creates an organization tag or assigns and removes an existing tag from a Pluto entity. | API user authorized to manage tags | Read and write access to organization tags and supported entities |
    | `update_pluto_inventory_metadata` | Adds a review comment or updates the risk level of a supported inventory entity. | API user authorized to modify inventory metadata | Write access to inventory comments and supported risk-level fields |
    | `get_or_update_pluto_business_context` | Retrieves or replaces the organization’s customer-supplied business description used by Pluto for risk detection and classification. | API user authorized to view or manage organization context | Read access to retrieve context; write access to replace or clear it |

    <Warning>
      Pluto returns `403 Forbidden` when tagging is disabled for the organization. IDE-extension tags are managed by Pluto and cannot be changed through the API.
    </Warning>

    **Inventory metadata limitations**

    * `risk_level` can be updated only for `builder` and `application` entity types.
    * Use `comment` when updating other supported entity types.
    * Passing an empty `business_context` value clears the existing business-context field.
    * The business-context value is limited to 4,000 characters.
    * The Pluto-managed `org_info` field is not modified by the business-context skill.
  </Accordion>

  <Accordion title="AI Add-on Security Scanning">
    These skills submit MCP servers or agent skills for scanning and retrieve their results.

    | Skill ID | Purpose | Minimum Pluto Role | Required Access |
    | - | - | - | - |
    | `submit_pluto_addon_scan` | Submits an MCP server or agent skill to Pluto Studio for asynchronous security scanning. | API user authorized to submit scans | Write access to Pluto Studio scan-submission endpoints |
    | `get_pluto_addon_scan` | Retrieves the status and result of a previously submitted MCP-server or agent-skill scan. | API user with scan-result access | Read access to Pluto Studio scan results |
  </Accordion>
</AccordionGroup>

<Tip>
  To view the details of Input Parameters and Output for the respective skills

  * Go to AirMDR → runZero Integration page.
  * Select the **Skills** tab and click on the required listed skills.
</Tip>

## Additional Information

<AccordionGroup>
  <Accordion title="🛑 Security & Access Best Practices">
    **✅ Do**

    * Use an organization-scoped Export token.
    * Follow least-privilege access principles.
    * Keep **Verify SSL** enabled.
    * Restrict API access to approved AirMDR egress addresses.
    * Store tokens in an approved secrets-management system.
    * Rotate tokens according to your security policy.
    * Review API usage and integration failures regularly.
    * Use separate tokens for production and non-production integrations.
    * Revoke tokens when an integration is decommissioned.
    * Sanitize logs and screenshots before sharing them.

    **❌ Don’t**

    * Using Account API tokens for read-only asset retrieval.
    * Reusing one token across unrelated systems.
    * Including tokens in documentation or support tickets.
    * Storing tokens in source-control repositories.
    * Sending tokens through email or chat.
    * Disabling SSL verification in production.
    * Regenerating a shared token without checking dependencies.
    * Logging the `Authorization` header.
    * Allowing unrestricted API access when static egress addresses are available.
  </Accordion>

  <Accordion title="👉 Support & Maintenance">
    * 📧 Contact [**AirMDR Support**](mailto:support@airmdr.com) through your designated support channel.
    * 🔁 Rotate credentials regularly. Recommended cadence: Every 90 days or as per internal security policy
    * 🔄 **Reconnect in AirMDR immediately when API Keys are changed.**
  </Accordion>

  <Accordion title="🔄 Monitoring & Logs">
    **AirMDR monitoring**

    Review the AirMDR integration or skill-execution logs for:

    * Connection-test results
    * Authentication failures
    * TLS certificate errors
    * Request timeouts
    * API rate-limit responses
    * Skill execution status
    * Response parsing failures

    **runZero monitoring**

    Depending on the deployment and permissions, review:

    * API usage headers returned with API responses
    * Account security settings
    * Organization activity or audit information
    * Self-hosted console and reverse-proxy logs

    runZero returns the following rate-limit headers:

    ```text theme={null}
    X-API-Usage-Total
    X-API-Usage-Today
    X-API-Usage-Limit
    X-API-Usage-Remaining
    ```

    **Illustrative log entries**

    The following entries are examples for documentation and may not match the exact AirMDR log format:

    ```text theme={null}
    INFO  runZero connection started instance=runZero-Production
    INFO  runZero API request completed endpoint=/api/v1.0/export/org/assets.json status=200
    WARN  runZero API rate limit approaching remaining=25
    ERROR runZero API authentication failed status=401
    ERROR runZero TLS certificate validation failed verify_ssl=true
    ```

    **Recommended log levels**

    | Level | Use |
    | :- | :- |
    | `INFO` | Successful connection, request completion, and synchronization summary |
    | `WARN` | Low remaining API quota, incomplete responses, and retryable failures |
    | `ERROR` | Authentication failure, TLS error, timeout, or invalid configuration |
    | `DEBUG` | Temporary troubleshooting without logging tokens or sensitive response data |

    <Check>
      Never record the API token or complete authorization header in logs.
    </Check>
  </Accordion>

  <Accordion title="🛑 Data Flow & Security">
    **Data exchanged**

    Depending on the AirMDR skill and requested endpoint, runZero can return:

    * Asset identifiers and names
    * IP and MAC addresses
    * Hostnames
    * Operating-system and hardware details
    * Discovered services
    * Site information
    * Scan information and timestamps
    * Asset attributes, tags, and related inventory metadata

    For the standard read-only integration, AirMDR sends:

    * The bearer token in the authorization header
    * The requested API path
    * Optional search or filtering parameters
    * The Organization ID when an Account API token is used

    **Encryption in transit**

    * API communication should use HTTPS.
    * Bearer tokens are transmitted in the HTTPS authorization header.
    * Enable **Verify SSL** to validate the runZero server certificate.
    * For self-hosted deployments, use a certificate signed by a trusted certificate authority.

    **Encryption at rest**

    The referenced API guide does not specify a particular encryption-at-rest algorithm for integration data or credentials. Confirm the applicable AirMDR and runZero security controls for your deployment before documenting a specific algorithm.

    **Ports and endpoints**

    | Direction | Protocol/port | Destination | Purpose |
    | :- | :- | :- | :- |
    | AirMDR → runZero | HTTPS/TCP 443 | `console.runzero.com` or the self-hosted console | API requests |
    | runZero → AirMDR | Response over established HTTPS session | AirMDR requester | Returns API results |

    Common Export API endpoints include:

    ```text theme={null}
    GET /api/v1.0/export/org/assets.json
    GET /api/v1.0/export/org/sites.json
    GET /api/v1.0/export/org/scans.json
    ```

    If a self-hosted console uses a non-standard HTTPS port, permit that configured port instead of TCP 443.
  </Accordion>

  <Accordion title="🧰 Error Handling">
    | Error or symptom | Probable cause | Resolution |
    | :- | :- | :- |
    | `401 Unauthorized` | Invalid, revoked, or regenerated token | Generate or copy the correct token and update the AirMDR connection |
    | `403 Forbidden` | Incorrect token type, insufficient scope, or blocked source IP | Use an Export token and verify the API IP allowlist |
    | `404 Not Found` | Incorrect Console URL or API path | Enter only the correct base Console URL and verify the endpoint |
    | `429 Too Many Requests` | API rate limit exceeded | Delay requests and retry with backoff |
    | TLS or certificate error | Untrusted, expired, or mismatched certificate | Correct the certificate chain or hostname; keep SSL verification enabled |
    | Connection timeout | Firewall, DNS, proxy, or routing issue | Verify outbound access to the console hostname and port |
    | No data returned | Incorrect organization, filters, or empty inventory | Confirm the token’s organization and test without optional filters |
    | Data from the wrong organization | Incorrect organization-scoped token or Organization ID | Replace the credential with one generated for the intended organization |
    | Account token request fails | Missing or incorrect Organization ID | Copy the unique ID from the runZero organization information page |
    | All requests rejected after enabling allowlist | AirMDR egress IP address is absent | Add the correct AirMDR source addresses to the runZero allowlist |

    ### Rate-limit recovery

    runZero documents a limit of 2,000 requests per five minutes for each source IP address. It also applies a daily limit based on licensed assets.

    For an HTTP `429` response:

    1. Stop immediate retries.
    2. Read the API usage and remaining-limit headers.
    3. Apply exponential backoff.
    4. Reduce unnecessary requests.
    5. Resume after the applicable limit resets.

    Example retry schedule:

    ```text theme={null}
    Attempt 1: wait 30 seconds
    Attempt 2: wait 60 seconds
    Attempt 3: wait 120 seconds
    Attempt 4: stop and alert an administrator
    ```

    <br />
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.