---
title: "Universal asset search (exact-match dossier)"
method: GET
path: "/api/v1/me/assets/search"
tags: ["Verifications"]
---

# Universal asset search (exact-match dossier)

`GET /api/v1/me/assets/search`

## Request

- Base URL: `https://api.proof.holdings`
- URL: `https://api.proof.holdings/api/v1/me/assets/search`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `auth_token`

Look up a FULL asset value (email, E.164 phone, domain, social handle, wallet, telegram bot) and receive everything the account knows about it: the owner's own verified records (account-global), end-user verifications, request assets (requested and verified identifiers), and provably linked authorizations/confirmations. Exact match only — identifiers are encrypted with blind-index equality lookup. Identifiers in the response are masked (SEC-001). Route scope verifications:read; the authorization/confirmation families additionally require hitl:read for API-key callers.

## Query parameters

- `value` string, required: FULL asset value to look up (exact match — identifiers are blind-indexed, no prefix/substring). Email, E.164 phone, domain, social handle, wallet address, or telegram bot username.
- `type` 'phone' | 'email' | 'domain' | 'social' | 'wallet' | 'telegram_bot': Pin the value type instead of type-sniffing (restricts candidate normalization)
- `environment` 'production' | 'test': Scope env-aware families (verifications/requests/authorizations/confirmations) to test or production; the account group is environment-less by design

## Response `200`

Asset dossier grouped by record family

- MeAssetSearchResponse: Exact-match asset dossier. `*_masked` fields are always masked; the owner's JWT session additionally receives unmasked `identifier`/`recipient` twins — never returned to API-key callers (owner-vs-not boundary, SEC-001). Authorizations/confirmations require hitl:read for API-key callers; related records follow the provable verification_id -> authorization_id chain only.
  - `data` object, required
    - `value_masked` string, required
    - `detected_types` string[], required
    - `account` object, required: The owner's own verified records — account-global (no environment field on these models). For API-key callers each family mirrors its own read surface: assets require the assets:read scope; emails/phones/domains are JWT-only and return empty for any API key
      - `assets` object[], required
        - `id` string, required
        - `type` string, required
        - `channel` string, required
        - `identifier_masked` string, required
        - `identifier` string, nullable: Unmasked asset identifier — present ONLY for the owner's JWT (dashboard) session, never for API-key callers (owner-vs-not masking boundary, SEC-001)
        - `status` string, required
        - `verified_at` string, nullable, required
        - `proof_expires_at` string, nullable, required
      - `emails` object[], required
        - `id` string, required
        - `identifier_masked` string, required
        - `identifier` string, nullable: Unmasked email address — present ONLY for the owner's JWT (dashboard) session, never for API-key callers (owner-vs-not masking boundary, SEC-001)
        - `verification_channel` string, required
        - `verified_methods` string[], required
        - `is_primary` boolean, required
        - `status` string, required
        - `verified_at` string, nullable, required
      - `phones` object[], required
        - `id` string, required
        - `identifier_masked` string, required
        - `identifier` string, nullable: Unmasked phone number — present ONLY for the owner's JWT (dashboard) session, never for API-key callers (owner-vs-not masking boundary, SEC-001)
        - `verification_channel` string, required
        - `verified_channels` string[], required
        - `is_primary` boolean, required
        - `status` string, required
        - `verified_at` string, nullable, required
      - `domains` object[], required
        - `id` string, required
        - `domain` string, required
        - `status` string, required
        - `verification_method` string, required
        - `verified_providers` string[], required
        - `verified_at` string, nullable, required
    - `verifications` object[], required
      - `id` string, required
      - `type` string, required
      - `channel` string, required
      - `status` string, required
      - `identifier_masked` string, required
      - `identifier` string, nullable: Unmasked verification identifier — present ONLY for the owner's JWT (dashboard) session, never for API-key callers (owner-vs-not masking boundary, SEC-001)
      - `external_user_id` string, nullable, required
      - `created_at` string, required
      - `verified_at` string, nullable, required
      - `proof_expires_at` string, nullable, required
      - `api_key_id` string, nullable, required
      - `attribution` 'api_key' | 'dashboard' | 'unattributed', required: API-key attribution is forward-only and dashboard writes carry no key — unattributed rows predate attribution
    - `requests` object[], required
      - `id` string, required
      - `reference_id` string, nullable, required
      - `status` string, required
      - `created_at` string, required
      - `expires_at` string, required
      - `completed_at` string, nullable, required
      - `api_key_id` string, nullable, required
      - `attribution` 'api_key' | 'dashboard' | 'agent' | 'unattributed', required: API-key attribution is forward-only and dashboard writes carry no key — unattributed rows predate attribution. `agent` is a request an AI agent made signed in as the owner, named in `agent_name`
      - `agent_name` string, nullable, required: The name the agent's MCP client gave itself (self-declared), when `attribution` is `agent`; null otherwise
      - `matched_assets` object[], required
        - `type` string, required
        - `status` string, required
        - `identifier_masked` string, required
        - `identifier` string, nullable: Unmasked matched asset identifier — present ONLY for the owner's JWT (dashboard) session, never for API-key callers (owner-vs-not masking boundary, SEC-001)
        - `verified_channel` string, nullable, required
        - `verified_at` string, nullable, required
    - `authorizations` object[], required
      - `id` string, required
      - `hitl_id` string, required
      - `channel` string, required
      - `scope` string, required
      - `status` string, required
      - `recipient_masked` string, required
      - `recipient` string, nullable: Unmasked approver recipient (phone/chat id) — present ONLY for the owner's JWT (dashboard) session, never for API-key callers (owner-vs-not masking boundary, SEC-001)
      - `authorized_at` string, nullable, required
      - `expires_at` string, required
      - `revoked_at` string, nullable, required
      - `confirmations_sent` number, required
      - `api_key_id` string, nullable, required
      - `attribution` 'api_key' | 'dashboard' | 'unattributed', required: API-key attribution is forward-only and dashboard writes carry no key — unattributed rows predate attribution
    - `confirmations` object[], required
      - `id` string, required
      - `hitl_id` string, required
      - `status` string, required
      - `action` string, nullable, required
      - `resolved_at` string, nullable, required
      - `created_at` string, required
      - `api_key_id` string, nullable, required
      - `attribution` 'api_key' | 'dashboard' | 'unattributed', required: API-key attribution is forward-only and dashboard writes carry no key — unattributed rows predate attribution
  - `total` number, required

## Other responses

- `400`: Invalid query (value shorter than 3 chars or malformed type/environment)
- `401`: Missing or invalid authentication
- `429`: Rate limited (dedicated me-asset-search pool, 30/min per IP)

---

[API](https://skmtc.dev/proof/apis/proof-holdings-api.md) · [All operations](https://skmtc.dev/proof/apis/proof-holdings-api/llms.txt) · [OpenAPI document](https://skmtc.dev/proof/apis/proof-holdings-api/revisions/b15f506de696?raw)
