---
title: "Get an organization's asset"
method: GET
path: "/v1/organizations/{organization_id}/assets/{asset_id}"
tags: ["organizations"]
---

# Get an organization's asset

`GET /v1/organizations/{organization_id}/assets/{asset_id}`

## Request

- Base URL: `https://api.ethiack.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.ethiack.com/v1/organizations/{organization_id}/assets/{asset_id}`
- Auth: none declared

Return one asset belonging to an organization.

Args:
    organization_id (int): Identifier of the organization.
    asset_id (int): Primary key of the asset.
    db (AsyncSession): Request-scoped database session.
    context (ActiveContext): Resolved caller identity and scope.

Returns:
    AssetDetailResponse: The requested asset.

## Path parameters

- `organization_id` integer, required
- `asset_id` integer, required

## Response `200`

Successful Response

- AssetDetailResponse: Detailed asset representation (single-item view). Extends :class:`AssetResponse` with the timestamps, the resolved IP address, the asset's risk band, and the services discovered on it — everything the asset detail panel renders, in one call. Attributes: created (datetime.datetime | None): Creation timestamp. risk_score (str): The asset's risk band — ``high`` when any open or triaged finding is high severity or above (critical and cosmic fold in), ``medium`` when any is medium, else ``low``. Filled by the route from :meth:`AssetService.risk_scores`. ip (str | None): The asset's resolved IP address, or ``null``. services (list[str]): Names of the services discovered on the asset, deduplicated. Their ports, protocols and technologies are served by ``GET /v1/assets/{id}/services``. ports (list[int]): The distinct ports those services listen on.
  - `id` integer, required
  - `value` string, required
  - `type` string, required
  - `tier` 'low' | 'medium' | 'high': Tier (importance level) of an asset. Stored as the lowercase token (``low``/``medium``/``high``) — the same value the public API uses, so no wire<->storage mapping is needed.
  - `organization_id` integer, required
  - `private` boolean, nullable
  - `created` string, date-time, nullable
  - `ip` string, nullable: The asset's resolved IP address, if one is known.
  - `risk_score` string: Highest actionable severity: `high`, `medium` or `low`.
  - `services` string[]: Service names discovered on the asset, deduplicated.
  - `ports` integer[]: Ports the asset's services listen on, deduplicated.
  - `technologies` TechnologyResponse[]: Technologies detected across the asset's services, deduplicated by id.
    - `id` integer, required
    - `name` string, required
    - `vendor` string
    - `version` string
    - `os` string
  - `organization_name` string: Name of the organization that owns the asset.
  - `tld` boolean: Whether the asset's value is itself a domain the owning organization has proven, via an active verification.
  - `n_findings` integer: How many of the asset's findings are open or triaged.
  - `findings` AssetFindingsResponse: The findings block embedded in an asset's detail response. A single-key object rather than a bare array because that is the shape this endpoint has always served: a caller reads ``asset["findings"]["findings"]``. The paginated :class:`~phoenix.api.rest.schemas.findings.FindingListResponse` is a different thing -- it answers ``/v1/findings/`` and carries the page counters this embed has no room for. Attributes: findings (list[FindingResponse]): The embedded findings.
    - `findings` FindingResponse[]: The asset's open and triaged findings.
      - `id` integer, required
      - `title` string, required
      - `md` string, nullable
      - `html` string, nullable
      - `asset_id` integer, nullable
      - `asset_value` string, required
      - `status` 'draft' | 'open' | 'triaged' | 'invalid' | 'fixed' | 'duplicate' | 'accepted', required: Finding lifecycle status. ``DRAFT`` is the author-private pre-submission state: a hacker (or machine) composes the finding as a draft, then ``submit`` advances it to ``OPEN`` / ``TRIAGED``, at which point it becomes visible to the event's other members. Drafts are only ever seen by their author (and privileged actors).
      - `previous_status` 'draft' | 'open' | 'triaged' | 'invalid' | 'fixed' | 'duplicate' | 'accepted': Finding lifecycle status. ``DRAFT`` is the author-private pre-submission state: a hacker (or machine) composes the finding as a draft, then ``submit`` advances it to ``OPEN`` / ``TRIAGED``, at which point it becomes visible to the event's other members. Drafts are only ever seen by their author (and privileged actors).
      - `severity` string, required
      - `score` number, nullable
      - `requested_score` number, nullable
      - `cve` string, nullable
      - `cvss_vector` string, nullable
      - `created` string, date-time, required
      - `pentest_slug` string, nullable
      - `epss` FindingEpssResponse: The latest EPSS sample for a finding's CVE. Attributes: score (float): EPSS score. percentile (float): EPSS percentile. date (datetime.date): Date the sample was published.
        - `score` number, required
        - `percentile` number, required
        - `date` string, date, required
      - `kev` boolean, nullable: Whether the CVE is in the CISA KEV catalog
      - `priority` number: Triage urgency in [0, 3]; lower is more urgent
      - `event_slug` string, nullable, required: Previous name for pentest_slug.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/ethiack/apis/ethiack-api.md) - [All operations](https://skmtc.dev/ethiack/apis/ethiack-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ethiack/apis/ethiack-api/revisions/4eaba89bfebf?raw)
