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

# Get NHI persona detail

> What the TOTAL NHI persona page shows for this identity: profile,
generated persona, permissions, resource and actor edges, operations,
call samples and rhythm, asset tier, cluster rank, stewards, custody,
drift, and drift drivers.




## OpenAPI

````yaml https://eris.platform.total.truu.ai/api/v1/external/docs get /nhi/personas/{nuid}/detail
openapi: 3.0.3
info:
  title: TOTAL Public API
  version: 3.0.0
  description: >
    The TOTAL API gives you programmatic access to your organization's

    security data. Use it to query cases, threat events, personas, and

    non-human identities, and to feed verdicts back into the platform.


    ## Authentication


    All routes in this specification are served under `/api/v1/external` and

    require a domain-scoped API key via the `X-API-Key` header. Generate and

    manage keys from the API Keys page in Settings.


    The admin console (Atlas) uses separate JWT-authenticated routes under

    `/api/v1/eris/...` (for example `GET /api/v1/eris/integrations`); those are

    not part of this public API surface.


    ## Scopes

    Each key carries scopes. A key never reaches further than the person who

    made it: it is granted only scopes its creator's TOTAL access allows, and

    on every request it keeps only those its creator can still grant. A key

    whose creator is deactivated or loses every granting role stops working

    (`401`); a route answers `403` when the key lacks the scope it needs.


    | Scope | Grants |

    |---|---|

    | `cases:read` | `GET /cases`; with `users:read`, `GET /users/{tuid}/cases`;
    the `security` block on `GET /users/{tuid}`; `case_status` on persona detail
    |

    | `cases:write` | `POST /cases/{case_id}/claim`, `POST
    /cases/{case_id}/verdict` |

    | `threats:read` | `GET /threats` |

    | `users:read` | `GET /users`, `GET /users/{tuid}`, `GET
    /users/{tuid}/cases` |

    | `watchlist:write` | `POST /watchlist` |

    | `personas:read` | every `/personas` and `/nhi` route |


    ## SOAR integration

    1. **Poll** `GET /cases?updated_after=<watermark>`. Reading never changes
       a case. Every change to a case moves its `updated_at`: being published
       to analysts, being claimed, being closed in TOTAL or through this API,
       an approved update to its findings. With `updated_after`, results come
       oldest change first; keep the last item's `updated_at` as the next
       watermark. The bound is inclusive and TOTAL also touches cases for its
       own bookkeeping, so the same case can come back unchanged: deduplicate
       by `case_id` and `updated_at`, and act on `case_state`. Add
       `state=discover` to see only cases waiting for triage.
    2. **Claim** `POST /cases/{case_id}/claim`. The case moves to
       `pending_investigation`, exactly as when an analyst escalates it in
       TOTAL, and leaves the analysts' triage queue. Claiming again changes
       nothing.
    3. **Work** the case: it already carries its threat events; `/users` and
       `/personas` add context. `/threats` is for looking events up, not for
       polling: a threat appears only once its case is published, so new
       threats are seen through `/cases`.
    4. **Close** it with `POST /cases/{case_id}/verdict`, or read the verdict
       an analyst closed it with in TOTAL from `case_state`, `close_reason`
       and `close_note`.

    Approved updates to a case never appear as a separate case: the case

    keeps its `case_id`. Cases are about a person (`identity_kind: human`) or

    a non-human identity (`identity_kind: nhi`, `tuid` holding its `nuid`).


    ## Pagination

    List routes use cursor pagination: `page_size` (default 50, max 200) and

    optional `next_cursor` from the previous page. Responses include

    `next_cursor` when more results are available. On case lists the cursor is

    an opaque string; elsewhere it is the id of the last item. A cursor is

    valid only with the same filters.


    ## Errors

    An error body is `{"error": "<what went wrong>"}`. A request body that

    fails validation answers `422` with `details`: where and why, never the

    values sent. An unexpected failure answers `500` with a `request_id` to

    quote to support.


    ## Versioning

    Breaking changes ship under a new path (`/api/v2/...`); `/api/v1` keeps

    its behaviour once released.


    ## Rate Limits

    Limits apply per API key. Read endpoints in this API are limited to 1,000

    requests/minute; write endpoints to 200 requests/minute.


    ## Availability

    Every route returns `423 Locked` with `error: not_available` until the

    TOTAL API is enabled for your domain. The `/nhi` routes also return it

    when your domain does not have non-human identities.


    ---


    ## Appendix A — Finding the source record behind a threat event


    Each threat event carries `source` (where it was found), `source_table`

    (the table, sourcetype or repository within that source) and

    `source_event_ids` (the records the finding cites, all from that one

    `source_table`). What an ID is, and how to look it up, depends on

    `source`:


    | `source` | `source_table` | Each `source_event_ids` value | Lookup |

    |---|---|---|---|

    | `azure_log_analytics` | Log Analytics table, e.g. `SigninLogs` | the row's
    `_ItemId` | `<source_table> | where _ItemId == "<id>"` in your workspace |

    | `splunk` | sourcetype, or `index:sourcetype` | `<_bkt>::<_cd>`, the bucket
    and offset that identify one event | `search index=<index>
    sourcetype=<sourcetype> | where _bkt="<_bkt>" AND _cd="<_cd>"` |

    | `crowdstrike_logscale` | repository or view | the event's `@id` | `@id =
    "<id>"` in that repository |

    | `outlook` | — | Microsoft Graph message id | `GET
    /users/{user}/messages/{id}` |

    | `msft-calendar` | — | Microsoft Graph event id | `GET
    /users/{user}/events/{id}` |

    | `teams` | — | `<chatId>:<messageId>` | `GET
    /users/{user}/chats/{chatId}/messages/{messageId}` |

    | `office365` | — | unified audit log record `id` | Search the user's audit
    log in Microsoft Purview and match on `id` |
servers:
  - url: https://eris.platform.total.truu.ai/api/v1/external
    description: TOTAL Public API
security:
  - ApiKeyAuth: []
tags:
  - name: Cases
    description: Threat investigation cases and verdicts
  - name: Users
    description: Provisioned users and their cases
  - name: Personas
    description: Personas, as the TOTAL persona page shows them
  - name: Threats
    description: Raw threat events
  - name: NHI
    description: Non-human identity personas and cluster catalogue
  - name: Watchlist
    description: People under watch
paths:
  /nhi/personas/{nuid}/detail:
    get:
      tags:
        - NHI
      summary: Get NHI persona detail
      description: |
        What the TOTAL NHI persona page shows for this identity: profile,
        generated persona, permissions, resource and actor edges, operations,
        call samples and rhythm, asset tier, cluster rank, stewards, custody,
        drift, and drift drivers.
      operationId: getNhiPersonaDetail
      parameters:
        - name: nuid
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: NHI persona page payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NhiPersonaDetail'
        '401':
          description: Invalid or inactive API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scope — personas:read required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Unknown nuid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '423':
          description: Resource not ready yet for this domain
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceNotReady'
components:
  schemas:
    NhiPersonaDetail:
      type: object
      description: >
        What the TOTAL NHI persona page shows for this identity: its profile,
        the generated persona, and the facts behind the page's graph, tables and
        charts, each as stored.
      properties:
        nuid:
          type: string
          format: uuid
        profile:
          type: object
          properties:
            display_name:
              type: string
              nullable: true
            nhi_class:
              type: string
            nhi_class_label:
              type: string
              nullable: true
            archetype:
              type: string
              nullable: true
            archetype_label:
              type: string
              nullable: true
            archetype_explanation:
              type: string
              nullable: true
            provider:
              type: object
              properties:
                key:
                  type: string
                label:
                  type: string
            creator_upn:
              type: string
              nullable: true
            owning_tenant_id:
              type: string
              nullable: true
            ms_first_party:
              type: boolean
              nullable: true
            tenant:
              type: object
              description: Who operates the identity.
              properties:
                relation:
                  type: string
                  enum:
                    - microsoft_first_party
                    - this_tenant
                    - external
                    - unknown
                label:
                  type: string
                  nullable: true
            first_seen:
              type: string
              format: date-time
              nullable: true
            last_seen:
              type: string
              format: date-time
              nullable: true
        identity_persona:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            The generated persona, section by section, as stored. Null until one
            is generated.
        story_summary:
          type: string
          nullable: true
        function_verdict_counts:
          type: object
          properties:
            total:
              type: integer
            by_verdict:
              type: object
              additionalProperties:
                type: integer
        permissions:
          type: array
          nullable: true
          items:
            type: object
            additionalProperties: true
        resource_edges:
          type: array
          nullable: true
          items:
            type: object
            additionalProperties: true
        operations:
          type: array
          description: Operations per resource, busiest resource first.
          items:
            type: object
            additionalProperties: true
        actor_edges:
          type: array
          items:
            type: object
            additionalProperties: true
        call_samples:
          type: array
          items:
            type: object
            additionalProperties: true
        asset_tier:
          type: object
          nullable: true
          additionalProperties: true
        cluster_rank:
          type: object
          nullable: true
          additionalProperties: true
        call_rhythm:
          type: object
          nullable: true
          additionalProperties: true
        stewards:
          type: array
          items:
            type: object
            additionalProperties: true
        custody:
          type: object
          nullable: true
          additionalProperties: true
        drift:
          type: object
          nullable: true
          properties:
            magnitude:
              type: number
              nullable: true
            cume_dist:
              type: number
              nullable: true
            drivers:
              type: array
              items:
                type: object
                additionalProperties: true
        drift_drivers:
          $ref: '#/components/schemas/DriftDrivers'
    Error:
      type: object
      properties:
        error:
          type: string
        details:
          type: array
          description: >-
            422 only: where the body is invalid and why. Never echoes the values
            sent.
          items:
            type: object
            properties:
              loc:
                type: array
                items: {}
              msg:
                type: string
              type:
                type: string
        request_id:
          type: string
          description: '500 only: quote to support.'
    ResourceNotReady:
      type: object
      properties:
        error:
          type: string
          description: Always `not_available`
        resource:
          type: string
          description: >-
            One of `cases`, `threats`, `users`, `watchlist`, `personas`, `nhi`,
            `nhi-clusters`
        message:
          type: string
          description: Human-readable readiness status message
    DriftDrivers:
      type: object
      description: >
        How the identity's behaviour moved in its latest drift scoring run,
        driver by driver, against its own past and its peers.
      properties:
        tuid:
          type: string
          format: uuid
        run_date:
          type: string
          format: date
          nullable: true
        magnitude:
          type: number
          nullable: true
          description: Overall peer-relative drift.
        cume_dist:
          type: number
          nullable: true
          description: Rank among scored identities, 0–1.
        flagged:
          type: boolean
        cohort_group:
          type: string
          nullable: true
        drivers:
          type: array
          items:
            type: object
            properties:
              signal:
                type: string
              label:
                type: string
              description:
                type: string
                nullable: true
              unit:
                type: string
                nullable: true
              unit_label:
                type: string
                nullable: true
              category:
                type: string
                nullable: true
              pattern:
                type: string
                nullable: true
                description: e.g. fast, slow, sustained
              peer_pct:
                type: number
                nullable: true
                description: Percentile against peers, 0–100.
              change_pct:
                type: number
                nullable: true
                description: Change of the recent window against the baseline.
              tempo:
                type: string
                nullable: true
                description: Window pair that moved, e.g. `7v30`.
              baseline:
                type: number
                nullable: true
              recent:
                type: number
                nullable: true
              cohort_group:
                type: string
                nullable: true
              peer_count:
                type: integer
                nullable: true
              peer_values:
                type: array
                items:
                  type: number
              window_means:
                type: object
                additionalProperties:
                  type: number
              series:
                type: array
                items:
                  type: object
                  properties:
                    date:
                      type: string
                      format: date-time
                    value:
                      type: number
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: |
        Domain-scoped API key. Generate and manage keys from the API Keys
        page in Settings.

        Accepted in two forms:
        - `X-API-Key: <key>` header (preferred)
        - `Authorization: Bearer <key>` header (also accepted)

````

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