An investment in knowledge pays the best interest.
Benjamin Franklin

Users

Users API#

The Users API provides developer-facing endpoints for discovering users and viewing live presence. All developer API requests require an Azure API Management (APIM) subscription key. The APIM custom domain is the primary client endpoint; Azure Front Door (AFD) can be configured as an optional/fallback edge.

  • Base URL:
    markup
    https://api.pay.ledger1.ai/portalpay
  • Authentication (Developer APIs): APIM subscription key in header
    • markup
      Ocp-Apim-Subscription-Key: {your-subscription-key}
  • Gateway posture: APIM custom domain is primary. If AFD is enabled, APIM accepts an internal
    markup
    x-edge-secret
    header per policy.
  • Rate limit headers (if enabled):
    markup
    X-RateLimit-Limit
    ,
    markup
    X-RateLimit-Remaining
    ,
    markup
    X-RateLimit-Reset

Search users by wallet/displayName text, XP range, and dynamic metrics (domains, platforms, languages).

Query parameters:

  • markup
    q
    (string, optional): case-insensitive text search across wallet and displayName
  • markup
    domains
    (string, optional): comma-separated list; user must have all of these domains in metrics
  • markup
    platforms
    (string, optional): comma-separated list; user must have all of these platforms in metrics
  • markup
    languages
    (string, optional): comma-separated list; user must have all of these languages in metrics
  • markup
    minXp
    (number, optional): minimum XP (>= 0)
  • markup
    maxXp
    (number, optional): maximum XP (>= 0)
  • markup
    live
    (boolean, optional): if
    markup
    true
    , only returns users currently live and with
    markup
    spacePublic = true
  • markup
    limit
    (number, optional): number of results to return; clamped to [1, 100], default 25
  • markup
    scan
    (number, optional): max items scanned server-side before filtering; clamped to [limit, 1000], default 400

Headers:

markup
Ocp-Apim-Subscription-Key: {your-subscription-key}

Example requests

curl -X GET "https://api.pay.ledger1.ai/portalpay/api/users/search?q=alice&minXp=100&domains=gaming,defi&limit=25" \
  -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY"
GET/portalpay/api/users/search

Try It: Users Search

Search users with filters.

Default is the APIM custom domain. For AFD, enter only the AFD endpoint host (e.g., https://afd-endpoint-pay-...) without any path; the /portalpay prefix is added automatically for /api/* and /healthz.

The key is kept only in memory while this page is open. Do not paste secrets on shared machines.

For public reads (GET /api/inventory, GET /api/shop/config), include the merchant wallet (0x-prefixed 40-hex). Non-GET requests should use JWT and will ignore this header.

Query Parameters
Using server-side proxy to avoid CORS. Requests go through /api/tryit-proxy to AFD/APIM.
cURL
curl -X GET "https://api.pay.ledger1.ai/portalpay/api/users/search?limit=25"
Response Status
Response Headers
Response Body

Success (200 OK):

json
{
  "users": [
    {
      "wallet": "0x1234...abcd",
      "displayName": "Alice",
      "pfpUrl": "https://cdn.example/pfp/alice.png",
      "xp": 1234,
      "live": true,
      "lastSeen": 1698790000000,
      "lastHeartbeat": 1698790100000,
      "domains": ["gaming", "defi"],
      "platforms": ["farcaster", "twitter"],
      "languages": ["en", "es"]
    }
  ],
  "total": 1
}

Degraded (Cosmos unavailable):

json
{ "users": [], "degraded": true, "reason": "cosmos_unavailable" }

Notes:

  • Ordering defaults to XP descending server-side.
  • Filtering for domains/platforms/languages requires that the user has all requested keys in metrics.
  • markup
    scan
    controls how many items are scanned before server-side filtering; results are then sliced to
    markup
    limit
    .

Possible responses: 200 (OK), 429 (rate limited)


GET /portalpay/api/users/live#

Returns users with recent presence heartbeats, indicating they are currently live and public.

Behavior:

  • Active if
    markup
    lastHeartbeat
    within the last 2 minutes
  • Only returns users with
    markup
    live = true
    and
    markup
    spacePublic = true

Headers:

markup
Ocp-Apim-Subscription-Key: {your-subscription-key}

Example requests

curl -X GET "https://api.pay.ledger1.ai/portalpay/api/users/live" \
  -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY"
GET/portalpay/api/users/live

Try It: Users Live

List currently live/public users.

Default is the APIM custom domain. For AFD, enter only the AFD endpoint host (e.g., https://afd-endpoint-pay-...) without any path; the /portalpay prefix is added automatically for /api/* and /healthz.

The key is kept only in memory while this page is open. Do not paste secrets on shared machines.

For public reads (GET /api/inventory, GET /api/shop/config), include the merchant wallet (0x-prefixed 40-hex). Non-GET requests should use JWT and will ignore this header.

Using server-side proxy to avoid CORS. Requests go through /api/tryit-proxy to AFD/APIM.
cURL
curl -X GET "https://api.pay.ledger1.ai/portalpay/api/users/live"
Response Status
Response Headers
Response Body

Success (200 OK):

json
{
  "live": [
    {
      "wallet": "0x1234...abcd",
      "displayName": "Alice",
      "pfpUrl": "https://cdn.example/pfp/alice.png",
      "spaceUrl": "https://portalpay.com/alice",
      "liveSince": 1698789000000,
      "lastHeartbeat": 1698790100000,
      "languages": ["en"],
      "domains": ["gaming"],
      "platform": "farcaster"
    }
  ]
}

Degraded (Cosmos unavailable):

json
{ "live": [], "degraded": true, "reason": "cosmos_unavailable" }

Possible responses: 200 (OK), 429 (rate limited)


Rate Limiting and Gateway Posture#

  • APIM custom domain is primary; if AFD is enabled it injects
    markup
    x-edge-secret
    which APIM validates.
  • Responses may include
    markup
    X-RateLimit-Limit
    ,
    markup
    X-RateLimit-Remaining
    ,
    markup
    X-RateLimit-Reset
    .
  • On
    markup
    429 Too Many Requests
    , implement exponential backoff.

Scopes#

Typical APIM scopes for Users endpoints:

  • markup
    users:read
Requests missing the required scope return
markup
403 Forbidden
.

Notes on Auth Models#

  • Developer reads must use
    markup
    Ocp-Apim-Subscription-Key
    . Wallet identity is resolved automatically at the gateway based on your subscription.
  • Admin/UI write operations related to users (e.g., profile updates, presence tracking writes, follow/unfollow mutations) are performed within the PortalPay app and require JWT cookies (
    markup
    cb_auth_token
    ) with CSRF protections and role checks; these are not available via APIM developer subscriptions.
  • Do not send wallet identity headers; APIM strips wallet headers and stamps the resolved identity.