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

# Get Profile

> Retrieve a comprehensive wallet profile by address, including onchain labels, token holdings, DeFi positions, web demographics, and lifecycle data.

Retrieves wallet profile information for a given address. Returns comprehensive profile data including wallet properties, labels, tokens, and apps.

If you have Formo installed on your website and app, you will also get the user's web demographics (country, device, browser, operating system), lifecycle, volume, and revenue.

<Frame>
  <img src="https://mintcdn.com/formo/YsINreB6FL0NqsXY/images/profile-api-diagram.png?fit=max&auto=format&n=YsINreB6FL0NqsXY&q=85&s=63caf53a7bd638330f826ab363606eb9" alt="Profiles API architecture diagram showing user device, Profiles API, and Wallet Profiles interaction" width="1247" height="598" data-path="images/profile-api-diagram.png" />
</Frame>

## Authentication

<Tabs>
  <Tab title="Workspace API Key">
    This endpoint requires a **Workspace API Key** with `profiles:read` permission. Include the API key in your request headers:

    ```bash theme={null}
    Authorization: Bearer <your_workspace_api_key>
    ```

    ```bash theme={null}
    curl -sS \
      -H "Authorization: Bearer <your_workspace_api_key>" \
      "https://api.formo.so/v0/profiles/<address>"
    ```

    <Note>
      Create a key with **profiles:read** scope in **Team Settings > API Keys**.
    </Note>
  </Tab>

  <Tab title="x402">
    AI agents can access this endpoint through the **x402 gateway** with no Formo API key required. The agent pays per request using the [x402 protocol](https://www.x402.org/).

    **Gateway URL:**

    ```
    https://formo.x402.paysponge.com/v0/profiles/{address}
    ```

    **Price:** 0.05 USDC per request (Base network)

    The gateway issues a `402 Payment Required` challenge on the first request. A compliant x402 client handles the payment automatically.

    **Using the Sponge wallet SDK:**

    ```typescript theme={null}
    import { SpongeWallet } from '@paysponge/sdk';

    const wallet = await SpongeWallet.connect({ apiKey: process.env.SPONGE_API_KEY });

    const response = await wallet.x402Fetch({
      url: 'https://formo.x402.paysponge.com/v0/profiles/<address>',
      method: 'GET',
    });

    console.log(response.data); // wallet profile object
    ```

    **Raw HTTP (after payment):**

    ```http theme={null}
    GET /v0/profiles/<address> HTTP/1.1
    Host: formo.x402.paysponge.com
    PAYMENT-SIGNATURE: <x402 payment payload>
    ```

    The response shape is identical to the standard endpoint. The `expand` query parameter works the same way.
  </Tab>

  <Tab title="MPP">
    AI agents can also access this endpoint through the **MPP gateway** using the [MPP protocol](https://mpp.dev/).

    **Gateway URL:**

    ```
    https://formo.mpp.paysponge.com/v0/profiles/{address}
    ```

    **Price:** 0.05 USDC.e per request (Tempo network)

    The gateway issues a `402 Payment Required` challenge. A compliant MPP client handles the payment authorization automatically.

    **Using the mppx SDK:**

    ```typescript theme={null}
    import { createTempoClient } from 'mppx';

    const client = createTempoClient({
      privateKey: process.env.TEMPO_PRIVATE_KEY,
    });

    const response = await client.fetch(
      'https://formo.mpp.paysponge.com/v0/profiles/<address>',
    );

    const profile = await response.json();
    ```

    **Raw HTTP (after payment):**

    ```http theme={null}
    GET /v0/profiles/<address> HTTP/1.1
    Host: formo.mpp.paysponge.com
    Authorization: Payment <mpp payment payload>
    ```

    The response shape is identical to the standard endpoint. The `expand` query parameter works the same way.
  </Tab>
</Tabs>

## Path parameters

* `address` (string): A wallet address or ENS name. Accepts an EVM address (e.g. `0x0000000000000000000000000000000000000000`), a Solana address, or an ENS name (e.g. `vitalik.eth`). ENS names are resolved to an address before lookup.

## Query parameters

### `expand`

Comma-separated list of optional sections to include in the response.

Supported values:

* `apps` - DeFi app interactions and balances
* `chains` - Per-chain activity metrics (net worth, tx count, first/last activity per chain)
* `tokens` - Token holdings with balances and prices
* `labels` - Wallet labels from various sources

Examples:

```bash theme={null}
curl -sS \
  -H "Authorization: Bearer <your_workspace_api_key>" \
  "https://api.formo.so/v0/profiles/0x0000000000000000000000000000000000000000?expand=apps,chains,tokens,labels"
```

<Note>
  The `apps`, `chains`, and `tokens` collections are capped at **50 items** each.
</Note>

## Response Fields

### Core Profile Data

| Field           | Type           | Description                                  |
| --------------- | -------------- | -------------------------------------------- |
| `address`       | string         | The wallet address                           |
| `net_worth_usd` | number         | Total net worth in USD across all chains     |
| `tx_count`      | integer        | Total transaction count across all chains    |
| `first_onchain` | string \| null | First on-chain activity timestamp (ISO 8601) |
| `last_onchain`  | string \| null | Last on-chain activity timestamp (ISO 8601)  |
| `updated_at`    | string \| null | Last profile update timestamp (ISO 8601)     |

### Lifecycle

| Field       | Type           | Description                                     |
| ----------- | -------------- | ----------------------------------------------- |
| `lifecycle` | string \| null | User lifecycle stage based on activity patterns |

Possible lifecycle values:

* `New` - Recently acquired user
* `Returning` - User who has returned after absence
* `Power user` - Highly active user
* `Resurrected` - User who returned after long absence
* `At Risk` - Established user who is still active but going quiet
* `Churned` - User who has stopped engaging

### Social & Identity

| Field       | Type           | Description        |
| ----------- | -------------- | ------------------ |
| `ens`       | string \| null | ENS name           |
| `farcaster` | string \| null | Farcaster username |
| `lens`      | string \| null | Lens handle        |
| `basenames` | string \| null | Base names         |
| `linea`     | string \| null | Linea identifier   |
| `discord`   | string \| null | Discord username   |
| `telegram`  | string \| null | Telegram username  |
| `twitter`   | string \| null | Twitter/X handle   |
| `github`    | string \| null | GitHub username    |
| `linkedin`  | string \| null | LinkedIn profile   |
| `email`     | string \| null | Email address      |
| `website`   | string \| null | Website URL        |
| `instagram` | string \| null | Instagram handle   |
| `facebook`  | string \| null | Facebook profile   |
| `tiktok`    | string \| null | TikTok handle      |
| `youtube`   | string \| null | YouTube channel    |
| `reddit`    | string \| null | Reddit username    |

### Profile Display

| Field          | Type           | Description         |
| -------------- | -------------- | ------------------- |
| `avatar`       | string \| null | Avatar image URL    |
| `display_name` | string \| null | Display name        |
| `description`  | string \| null | Profile description |

### User Engagement Data

These fields are populated based on events tracked in your project:

| Field            | Type            | Description                                 |
| ---------------- | --------------- | ------------------------------------------- |
| `first_seen`     | string \| null  | First seen timestamp in your app (ISO 8601) |
| `last_seen`      | string \| null  | Last seen timestamp in your app (ISO 8601)  |
| `num_sessions`   | integer \| null | Total number of sessions                    |
| `revenue`        | number \| null  | Total revenue                               |
| `volume`         | number \| null  | Total volume                                |
| `points`         | number \| null  | Total points                                |
| `activity_dates` | array \| null   | Array of activity dates (YYYY-MM-DD format) |

### Device & Location

| Field      | Type           | Description                  |
| ---------- | -------------- | ---------------------------- |
| `location` | string \| null | User location (country code) |
| `device`   | string \| null | Device type                  |
| `browser`  | string \| null | Browser name                 |
| `os`       | string \| null | Operating system             |

### Attribution & UTM

| Field                | Type           | Description             |
| -------------------- | -------------- | ----------------------- |
| `first_utm_source`   | string \| null | First UTM source        |
| `last_utm_source`    | string \| null | Last UTM source         |
| `first_utm_medium`   | string \| null | First UTM medium        |
| `last_utm_medium`    | string \| null | Last UTM medium         |
| `first_utm_campaign` | string \| null | First UTM campaign      |
| `last_utm_campaign`  | string \| null | Last UTM campaign       |
| `first_utm_content`  | string \| null | First UTM content       |
| `last_utm_content`   | string \| null | Last UTM content        |
| `first_utm_term`     | string \| null | First UTM term          |
| `last_utm_term`      | string \| null | Last UTM term           |
| `first_referrer`     | string \| null | First referrer domain   |
| `last_referrer`      | string \| null | Last referrer domain    |
| `first_referrer_url` | string \| null | First referrer full URL |
| `last_referrer_url`  | string \| null | Last referrer full URL  |
| `first_ref`          | string \| null | First referral code     |
| `last_ref`           | string \| null | Last referral code      |

### Last Event

| Field             | Type           | Description                         |
| ----------------- | -------------- | ----------------------------------- |
| `last_type`       | string \| null | Last event type                     |
| `last_event`      | string \| null | Last event name                     |
| `last_properties` | string \| null | Last event properties (JSON string) |

### Expanded Fields

When using the `expand` parameter, these additional fields are included:

#### `chains` (when `expand=chains`)

Array of per-chain wallet data:

| Field           | Type    | Description                     |
| --------------- | ------- | ------------------------------- |
| `chain_id`      | string  | Chain ID                        |
| `net_worth_usd` | number  | Net worth on this chain         |
| `tx_count`      | integer | Transaction count on this chain |
| `first_onchain` | string  | First activity on this chain    |
| `last_onchain`  | string  | Last activity on this chain     |

#### `labels` (when `expand=labels`)

Array of wallet labels:

| Field      | Type   | Description                            |
| ---------- | ------ | -------------------------------------- |
| `id`       | string | Label ID                               |
| `value`    | string | Label value                            |
| `chain_id` | string | Chain ID where label applies           |
| `source`   | string | Label source (e.g., manual, automated) |

#### `apps` (when `expand=apps`)

Array of DeFi app interactions:

| Field         | Type           | Description                 |
| ------------- | -------------- | --------------------------- |
| `chain_id`    | string         | Chain ID                    |
| `id`          | string         | App ID                      |
| `name`        | string         | App name                    |
| `img`         | string \| null | App image URL               |
| `url`         | string \| null | App URL                     |
| `balance_usd` | number         | Balance in USD for this app |

#### `tokens` (when `expand=tokens`)

Array of token holdings:

| Field           | Type           | Description                                     |
| --------------- | -------------- | ----------------------------------------------- |
| `chain_id`      | string         | Chain ID                                        |
| `token_address` | string         | Token contract address                          |
| `app_id`        | string         | App ID                                          |
| `name`          | string         | Token name                                      |
| `symbol`        | string         | Token symbol                                    |
| `img`           | string \| null | Token image URL                                 |
| `decimals`      | integer        | Token decimals                                  |
| `price`         | number         | Token price in USD                              |
| `balance`       | string         | Token balance (as string to preserve precision) |
| `balance_usd`   | number         | Token balance value in USD                      |

## Example Response

```json theme={null}
{
  "address": "0x9CC3cB28cd94eB4423B15cdA73346e204f59a407",
  "net_worth_usd": 125000.5,
  "ens": "vitalik.eth",
  "farcaster": null,
  "lens": null,
  "tx_count": 1234,
  "first_onchain": "2024-01-15T10:30:00Z",
  "last_onchain": "2025-01-20T14:22:00Z",
  "lifecycle": "Returning",
  "first_seen": "2024-01-15T10:30:00Z",
  "last_seen": "2025-01-20T14:22:00Z",
  "num_sessions": 45,
  "revenue": 1500.75,
  "volume": 50000.0,
  "points": 2500,
  "chains": [
    {
      "chain_id": "1",
      "net_worth_usd": 100000.0,
      "tx_count": 1000,
      "first_onchain": "2024-01-15T10:30:00Z",
      "last_onchain": "2025-01-20T14:22:00Z"
    },
    {
      "chain_id": "137",
      "net_worth_usd": 25000.5,
      "tx_count": 234,
      "first_onchain": "2024-03-01T08:00:00Z",
      "last_onchain": "2025-01-18T12:00:00Z"
    }
  ],
  "labels": [
    {
      "id": "label_123",
      "value": "Whale",
      "chain_id": "1",
      "source": "manual"
    }
  ],
  "apps": [
    {
      "chain_id": "1",
      "id": "uniswap",
      "name": "Uniswap",
      "img": "https://example.com/uniswap.png",
      "url": "https://uniswap.org",
      "balance_usd": 50000.0
    }
  ],
  "tokens": [
    {
      "chain_id": "1",
      "token_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "app_id": "usdc",
      "name": "USD Coin",
      "symbol": "USDC",
      "img": "https://example.com/usdc.png",
      "decimals": 6,
      "price": 1.0,
      "balance": "1000000000",
      "balance_usd": 1000.0
    }
  ]
}
```

## Error Responses

| Status | Code                    | Description                                                        |
| ------ | ----------------------- | ------------------------------------------------------------------ |
| 400    | `BAD_REQUEST`           | Invalid address or ENS name, or the ENS name could not be resolved |
| 401    | `UNAUTHORIZED`          | Missing or invalid API key                                         |
| 403    | `FORBIDDEN`             | API key does not have `profiles:read` permission                   |
| 404    | `PROFILE_NOT_FOUND`     | Profile does not exist                                             |
| 500    | `INTERNAL_SERVER_ERROR` | Failed to fetch wallet profile data                                |


## OpenAPI

````yaml GET /v0/profiles/{address}
openapi: 3.1.0
info:
  title: Formo Public API
  description: >-
    REST API for managing Formo projects, analytics, alerts, boards, charts,
    contracts, segments, and AI chat.


    **Auth.** All endpoints require a workspace API key with the appropriate
    scopes (see `x-api-scopes`).


    **Response shape.** Successful responses return the resource directly (or `{
    data: [...], total, page, size, has_more }` for paginated lists). HTTP
    status carries success/failure; there is no envelope wrapping success
    bodies.


    **Errors.** Every non-2xx response uses the `Error` envelope: `{ error: {
    code, message, doc_url, param?, details? } }`. Branch on the
    machine-readable `code` (see `ErrorCode` enum) and follow `doc_url` to the
    matching section of the [errors
    reference](https://docs.formo.so/api/errors).


    **Idempotency.** Pass an `Idempotency-Key` header on POST/PUT/PATCH/DELETE
    to make retries safe; the response is cached for 24 h and replayed on
    duplicate keys.
  version: 0.1.0
  contact:
    name: Formo
    url: https://formo.so
servers:
  - url: https://api.formo.so
    description: API Server (boards, alerts, contracts, segments, profiles, query, import)
  - url: https://events.formo.so
    description: Events Server (event ingestion)
security:
  - WorkspaceApiKey: []
tags:
  - name: Alerts
    description: Manage project alerts and notifications
  - name: Boards
    description: Manage dashboard boards
  - name: Charts
    description: Manage charts within boards
  - name: Contracts
    description: Manage blockchain contract monitoring
  - name: Segments
    description: Manage user segments
  - name: Profiles
    description: Wallet profiles and import
  - name: Query
    description: >-
      Execute SQL queries and call pre-built analytics endpoints (KPIs, top
      pages, lifecycle, retention, revenue). Requires the query:read scope.
  - name: Events
    description: Event ingestion API (events.formo.so)
paths:
  /v0/profiles/{address}:
    get:
      tags:
        - Profiles
      summary: Get wallet profile
      operationId: getProfile
      parameters:
        - name: address
          in: path
          required: true
          schema:
            type: string
          description: >-
            Wallet address. Accepts an EVM (0x...) or Solana address, or an ENS
            name (e.g. vitalik.eth) which is resolved to an address.
        - name: expand
          in: query
          schema:
            type: string
          description: 'Comma-separated: apps, chains, tokens, labels'
      responses:
        '200':
          description: Profile details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Profile'
              example:
                address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
                ens: vitalik.eth
                display_name: vitalik.eth
                avatar: https://euc.li/vitalik.eth
                description: mi pinxe lo crino tcati
                location: Earth
                net_worth_usd: 1581720.97
                tx_count: 18743
                first_onchain: '2015-09-28T08:24:43.000Z'
                last_onchain: '2026-04-01T03:34:47.000Z'
                twitter: vitalikbuterin
                farcaster: vitalik.eth
                lens: vitalik.lens
                basenames: vb62831.base.eth
                linea: null
                github: vbuterin
                reddit: null
                linkedin: null
                telegram: null
                discord: null
                email: null
                website: vitalik.ca
                youtube: null
                tiktok: null
                instagram: null
                facebook: null
                first_seen: '2025-09-14T03:11:42.000Z'
                last_seen: '2026-04-26T18:09:53.000Z'
                lifecycle: Returning
                num_sessions: 12
                revenue: 0
                volume: 482.55
                points: 0
                device: desktop
                browser: brave
                os: macOS
                first_utm_source: twitter
                first_utm_medium: social
                first_utm_campaign: devcon-launch
                first_utm_content: null
                first_utm_term: null
                first_referrer: twitter.com
                first_referrer_url: https://twitter.com/vitalikbuterin/status/1234567890
                first_ref: null
                last_utm_source: direct
                last_utm_medium: null
                last_utm_campaign: null
                last_utm_content: null
                last_utm_term: null
                last_referrer: null
                last_referrer_url: null
                last_ref: null
                last_type: track
                last_event: Swap Confirmed
                last_properties: '{"chain_id":1,"volume":482.55}'
                activity_dates:
                  - '2026-04-22'
                  - '2026-04-23'
                  - '2026-04-25'
                  - '2026-04-26'
                chains:
                  - chain_id: '1'
                    net_worth_usd: 1491971.89
                    tx_count: 1655
                    first_onchain: '2015-09-28T08:24:43.000Z'
                    last_onchain: '2026-04-01T03:34:47.000Z'
                  - chain_id: '8453'
                    net_worth_usd: 41871.88
                    tx_count: 16
                    first_onchain: '2023-07-30T12:40:39.000Z'
                    last_onchain: '2026-02-10T22:48:51.000Z'
                  - chain_id: '56'
                    net_worth_usd: 21108.72
                    tx_count: 8
                    first_onchain: '2022-10-21T13:52:11.000Z'
                    last_onchain: '2025-12-20T16:00:26.000Z'
                  - chain_id: '10'
                    net_worth_usd: 16668.39
                    tx_count: 40
                    first_onchain: '2021-12-17T15:15:45.000Z'
                    last_onchain: '2026-01-13T07:42:51.000Z'
                apps:
                  - chain_id: '1'
                    id: uniswap-v3
                    name: Uniswap V3
                    img: https://cdn.formo.so/apps/uniswap.png
                    url: https://app.uniswap.org
                    balance_usd: 124820.41
                  - chain_id: '1'
                    id: aave-v3
                    name: Aave V3
                    img: https://cdn.formo.so/apps/aave.png
                    url: https://app.aave.com
                    balance_usd: 88421.07
                tokens:
                  - chain_id: '1'
                    token_address: '0x0000000000000000000000000000000000000000'
                    app_id: ''
                    name: Ethereum
                    symbol: ETH
                    img: https://cdn.formo.so/tokens/eth.png
                    decimals: 18
                    price: 3290.42
                    balance: '184.732910421054811234'
                    balance_usd: 607823.55
                  - chain_id: '1'
                    token_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
                    app_id: ''
                    name: USD Coin
                    symbol: USDC
                    img: https://cdn.formo.so/tokens/usdc.png
                    decimals: 6
                    price: 1
                    balance: '125804.520000'
                    balance_usd: 125804.52
                labels:
                  - id: ethereum.founder
                    value: ''
                    chain_id: '-'
                    source: system
                  - id: whale
                    value: ''
                    chain_id: '-'
                    source: formo
                  - id: coinbase.verified_account
                    value: 'true'
                    chain_id: '1'
                    source: coinbase
                updated_at: '2026-04-27T01:00:00.000Z'
        '404':
          description: Profile not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RestApiError'
components:
  schemas:
    Profile:
      type: object
      description: Comprehensive wallet profile with onchain and offchain data
      properties:
        address:
          type: string
        net_worth_usd:
          type: number
        tx_count:
          type: integer
        first_onchain:
          type: string
          description: First onchain activity date
        last_onchain:
          type: string
          description: Last onchain activity date
        updated_at:
          type: string
          format: date-time
        ens:
          type: string
          nullable: true
        farcaster:
          type: string
          nullable: true
        lens:
          type: string
          nullable: true
        basenames:
          type: string
          nullable: true
        linea:
          type: string
          nullable: true
        avatar:
          type: string
          nullable: true
        display_name:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        discord:
          type: string
          nullable: true
        telegram:
          type: string
          nullable: true
        twitter:
          type: string
          nullable: true
        github:
          type: string
          nullable: true
        linkedin:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        instagram:
          type: string
          nullable: true
        facebook:
          type: string
          nullable: true
        website:
          type: string
          nullable: true
        reddit:
          type: string
          nullable: true
        youtube:
          type: string
          nullable: true
        tiktok:
          type: string
          nullable: true
        first_seen:
          type: string
          nullable: true
          description: First seen in project
        last_seen:
          type: string
          nullable: true
          description: Last seen in project
        lifecycle:
          type: string
          nullable: true
          enum:
            - New
            - Returning
            - Power user
            - Resurrected
            - At Risk
            - Churned
        num_sessions:
          type: integer
          nullable: true
        revenue:
          type: number
          nullable: true
        volume:
          type: number
          nullable: true
        points:
          type: number
          nullable: true
        device:
          type: string
          nullable: true
        browser:
          type: string
          nullable: true
        os:
          type: string
          nullable: true
        location:
          type: string
          nullable: true
        first_utm_source:
          type: string
          nullable: true
        first_utm_medium:
          type: string
          nullable: true
        first_utm_campaign:
          type: string
          nullable: true
        first_referrer:
          type: string
          nullable: true
        last_utm_source:
          type: string
          nullable: true
        last_utm_medium:
          type: string
          nullable: true
        last_utm_campaign:
          type: string
          nullable: true
        last_referrer:
          type: string
          nullable: true
        first_referrer_url:
          type: string
          nullable: true
          description: First referrer full URL
        last_referrer_url:
          type: string
          nullable: true
          description: Last referrer full URL
        first_ref:
          type: string
          nullable: true
          description: First referral code
        last_ref:
          type: string
          nullable: true
          description: Last referral code
        first_utm_content:
          type: string
          nullable: true
          description: First UTM content
        last_utm_content:
          type: string
          nullable: true
          description: Last UTM content
        first_utm_term:
          type: string
          nullable: true
          description: First UTM term
        last_utm_term:
          type: string
          nullable: true
          description: Last UTM term
        last_type:
          type: string
          nullable: true
          description: Last event type
        last_event:
          type: string
          nullable: true
          description: Last event name
        last_properties:
          type: string
          nullable: true
          description: Last event properties (JSON string)
        activity_dates:
          type: array
          items:
            type: string
            format: date
          nullable: true
          description: Array of activity dates (YYYY-MM-DD format)
        chains:
          type: array
          items:
            $ref: '#/components/schemas/WalletChain'
          description: Requires expand=chains
        apps:
          type: array
          items:
            $ref: '#/components/schemas/WalletApp'
          description: Requires expand=apps
        tokens:
          type: array
          items:
            $ref: '#/components/schemas/WalletToken'
          description: Requires expand=tokens
        labels:
          type: array
          items:
            $ref: '#/components/schemas/WalletLabel'
          description: Requires expand=labels
    RestApiError:
      $ref: '#/components/schemas/Error'
      description: >-
        Deprecated alias for `Error`. Existing endpoint specs reference this
        name; new specs should reference `Error` directly.
    WalletChain:
      type: object
      properties:
        chain_id:
          type: string
        net_worth_usd:
          type: number
        tx_count:
          type: integer
        first_onchain:
          type: string
        last_onchain:
          type: string
    WalletApp:
      type: object
      properties:
        chain_id:
          type: string
        id:
          type: string
        name:
          type: string
        img:
          type: string
          nullable: true
        url:
          type: string
          nullable: true
        balance_usd:
          type: number
    WalletToken:
      type: object
      properties:
        chain_id:
          type: string
        token_address:
          type: string
        app_id:
          type: string
        name:
          type: string
        symbol:
          type: string
        img:
          type: string
          nullable: true
        decimals:
          type: integer
        price:
          type: number
        balance:
          type: string
        balance_usd:
          type: number
    WalletLabel:
      type: object
      properties:
        id:
          type: string
          description: e.g. coinbase.verified_account
        value:
          type: string
        chain_id:
          type: string
        source:
          type: string
    Error:
      type: object
      description: >-
        Standard error envelope returned by every public API endpoint for any
        non-2xx response. The HTTP status code carries success/failure; the body
        provides a machine-readable `code`, a human-readable `message`, and a
        `doc_url` pointing at the matching section of the docs so agents can
        fetch context on the fly.
      properties:
        error:
          type: object
          required:
            - code
            - message
            - doc_url
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: >-
                Human-readable error description. Wording may change between
                releases, so branch on `code`, not `message`.
            doc_url:
              type: string
              format: uri
              description: >-
                Link to the matching section of the errors reference at
                https://docs.formo.so/api/errors.
            param:
              type: string
              description: >-
                When the error pertains to a specific request field, the dotted
                path to that field (e.g. `body.trigger_filters.0.value`).
            details:
              type: object
              additionalProperties: true
              description: >-
                Code-specific extra context. For `INVALID_VALIDATION_REQUEST`
                this is a `{ fieldPath: message }` map of every Zod validation
                failure.
      required:
        - error
    ErrorCode:
      type: string
      description: >-
        Stable, enumerated error codes. New codes may be added in any release;
        clients should treat unknown codes as the closest matching HTTP status
        family.
      enum:
        - INTERNAL_SERVER_ERROR
        - INVALID_VALIDATION_REQUEST
        - UNAUTHORIZED
        - BAD_REQUEST
        - FORBIDDEN
        - NOT_FOUND
        - CONFLICT
        - INVALID_CHAIN_ID
        - CONTEXT_LIMIT_EXCEEDED
        - SERVICE_UNAVAILABLE
        - TOO_MANY_REQUESTS
        - IDEMPOTENCY_IN_PROGRESS
        - INVALID_IDEMPOTENCY_KEY
  securitySchemes:
    WorkspaceApiKey:
      type: http
      scheme: bearer
      description: >-
        Workspace API key (e.g. `formo_xxx`). Create one in the Formo dashboard
        under Team Settings > API Keys.

````