AArtery
On this page

Portfolio

GET /v1/portfolio aggregates wallet positions across every provider Artery supports for on-chain identities. One call fans out — currently Polymarket

  • Hyperliquid — and returns a unified envelope with both the raw upstream payload (native) and a normalized valueUsd per slice.

When to use this

  • Account dashboards — show "total USDC across all venues" for a wallet without writing per-venue glue code.
  • PnL reconciliation — pair with /v1/me/pnl to compare realized vs current value.
  • Risk monitoring — sum exposure across Polymarket bets and HL perps for a watched address.

For per-wallet trade history (fills, fees, etc.) use /v1/me/fills — it shares the same wallet identity model.

Request

bashcurl -H "Authorization: Bearer art_live_<your-key>" \
  "https://api.artery.questflow.ai/v1/portfolio?user=0x9d84cbc7eb19c4cbb24f3866c70a5fcab502d1dc&provider=polymarket,hyperliquid"

Query parameters

ParameterTypeRequiredDescription
userstringyesEVM address, 0x + 40 hex chars. Lowercased server-side before forwarding.
providerstringnoComma-separated subset of polymarket, hyperliquid. Omit to fan out to every supported provider.

Unknown provider names return 400 unknown_provider with the offending values listed. The full set lives in the providers field of every response so you can discover-then-filter.

Response

jsonc{
  "user": "0x9d84cbc7eb19c4cbb24f3866c70a5fcab502d1dc",
  "providers": ["polymarket", "hyperliquid"],
  "slices": [
    {
      "provider": "polymarket",
      "native": [
        // Verbatim Polymarket position array — one row per market the
        // wallet has any size on. Keys match Polymarket's own API.
      ],
      "valueUsd": 1234.56,
      "note": null
    },
    {
      "provider": "hyperliquid",
      "native": {
        // Verbatim HL `clearinghouseState` — assetPositions[], marginSummary,
        // crossMarginSummary, withdrawable, time. See HL docs for the full shape.
      },
      "valueUsd": 5678.90,
      "note": null
    }
  ],
  "summary": {
    "totalValueUsd": 6913.46,
    "providersReporting": 2
  },
  "warnings": [],
  "fetchedAt": "2026-05-19T07:00:00.000Z"
}

Aggregation semantics

  • slices[i].native is the untransformed upstream payload. Polymarket returns an array (one row per position); Hyperliquid returns an object (the full clearinghouseState envelope including assetPositions[], marginSummary, crossMarginSummary, withdrawable, and time). Consumers that want raw venue data don't have to make two more calls.
  • slices[i].valueUsd is the USDC-denominated wallet value when the provider exposes one, else null. Polymarket returns position notionals; HL returns account equity from marginSummary.accountValue. Implementations evolve — treat this field as best-effort and fall back to native for audit-grade work.
  • summary.totalValueUsd sums slices that returned a number. Slices with valueUsd: null are excluded from the sum but still counted in slices. providersReporting is the count of slices that contributed.
  • warnings[] carries soft failures — provider 404, upstream timeout, partial parse — so one bad provider doesn't 5xx the whole response. When a provider call fails entirely you'll see a warning AND slices[i].note describing the failure, with valueUsd: null.
  • fetchedAt is when the server completed the fan-out. Both legs are fetched in parallel via Promise.allSettled; the slower one bounds the total response time.

Error responses

HTTPerror.codeWhen
400validation_faileduser missing or not a 0x-40-hex address.
400unknown_providerprovider= contains a name not in the supported set.
401unauthenticatedMissing / invalid Authorization header.
403insufficient_scopeKey lacks the read scope.
429rate_limitedOver the portfolio.read SKU quota — see headers x-quota-portfolio-*.

Worked example

bash# A wallet active on both Polymarket + HL perps
curl -H "Authorization: Bearer art_live_<your-key>" \
  "https://api.artery.questflow.ai/v1/portfolio?user=0xabc...&provider=polymarket,hyperliquid"
jsonc{
  "user": "0xabc...",
  "providers": ["polymarket", "hyperliquid"],
  "slices": [
    {
      "provider": "polymarket",
      "native": [
        {
          "conditionId": "0xCONDITION_ID",
          "outcome": "YES",
          "size": "150.00",
          "avgPrice": "0.62",
          "currentValue": "93.00"
        }
      ],
      "valueUsd": 93.0,
      "note": null
    },
    {
      "provider": "hyperliquid",
      "native": {
        "assetPositions": [
          { "type": "oneWay", "position": { "coin": "BTC", "szi": "0.5", "entryPx": "65000", "positionValue": "33850.5" } }
        ],
        "marginSummary": { "accountValue": "12450.78", "totalNtlPos": "33850.5" },
        "withdrawable": "8400.21",
        "time": 1779163200000
      },
      "valueUsd": 12450.78,
      "note": null
    }
  ],
  "summary": {
    "totalValueUsd": 12543.78,
    "providersReporting": 2
  },
  "warnings": [],
  "fetchedAt": "2026-05-19T07:00:00.000Z"
}

When the same wallet has no Polymarket activity:

jsonc{
  "user": "0xabc...",
  "providers": ["polymarket", "hyperliquid"],
  "slices": [
    { "provider": "polymarket",  "native": [],     "valueUsd": null, "note": null },
    { "provider": "hyperliquid", "native": { ... }, "valueUsd": 12450.78, "note": null }
  ],
  "summary": { "totalValueUsd": 12450.78, "providersReporting": 1 },
  "warnings": [],
  "fetchedAt": "2026-05-19T07:00:00.000Z"
}

valueUsd: null + empty native[] is the canonical "no positions" shape — not an error. summary ignores the null and the total still makes sense.

Quota

This endpoint is metered under the portfolio.read SKU. Each successful response counts as 1 unit. Per-tier daily caps live in the rate limits page.

Edit this page on GitHubLast updated
Portfolio · Artery API Docs