Skip to main content
The Polymarket Profile API lets your app set a user’s Polymarket username from their EOA wallet. The flow is built for platforms that already have a wallet-connected frontend and a backend that can call PolyNode with an API key. The user signs two payloads in their wallet. Your backend sends the signatures to PolyNode. PolyNode handles the Polymarket profile create or username update.
Never send user private keys to PolyNode. Never expose your PolyNode API key in a browser app. Your backend calls PolyNode. Your frontend only asks the user wallet to sign the returned messages.

What this does

This API can:
  • check whether a username is available
  • create a profile for a new EOA-backed Polymarket user
  • change the username for an existing EOA-backed Polymarket profile
  • return public profile state for an address
This API does not:
  • upload profile images
  • link X accounts
  • enable trading
  • bypass Polymarket compliance, eligibility, captcha, geoblock, or terms flows
  • accept private keys or long-lived Polymarket session credentials

Endpoints

All endpoints require a paid PolyNode API key.

The integration flow

  1. Your frontend collects the user’s EOA address and desired username.
  2. Your backend calls POST /v3/polymarket/profiles/username/challenge.
  3. Your frontend asks the user wallet to sign challenge.polymarket.message with personal_sign.
  4. Your frontend asks the user wallet to sign challenge.consent with eth_signTypedData_v4.
  5. Your backend calls POST /v3/polymarket/profiles/username/complete with both signatures.
  6. PolyNode logs in to Polymarket with the user-signed SIWE message, creates the profile if needed, and sets the username.
The two signatures are intentional:
  • The Polymarket SIWE signature authorizes sign-in to Polymarket.
  • The PolyNode consent signature authorizes this specific profile action: address, username, action, challenge id, chain id, and expiration.
That prevents a generic login signature from being reused later to mutate a username.

Backend: create a challenge

Your backend owns the PolyNode API key. With the TypeScript SDK:
With raw HTTP:
Challenge response shape:
expires_at is an ISO string for display. consent.message.expiresAt is a Unix timestamp because it is signed as uint256 in EIP-712.

Frontend: ask the wallet to sign

With an EIP-1193 wallet provider:
With viem:
With ethers v6:

Backend: complete the action

The complete request must be sent from your backend with the same PolyNode API key that created the challenge. With the TypeScript SDK:
With raw HTTP:
Complete response:

Username rules

PolyNode validates the username before calling Polymarket:
Polymarket is still the final authority. A username can pass local validation and still return available: false. Recommended UX:
  1. Call username-available as the user types, with debounce.
  2. Disable submit until it returns available: true.
  3. Re-check availability when creating the challenge.
  4. Handle username_taken on complete, because another user can claim the username between challenge and completion.

Security checklist

  • Keep POLYNODE_KEY only on your backend.
  • Never ask the user for a private key.
  • Treat challenge_id as one-time use.
  • Submit complete within 10 minutes.
  • Send complete with the same API key that created the challenge.
  • Verify on your side that the connected wallet address matches the address in the challenge before asking the wallet to sign.
  • Do not cache or log raw signatures, SIWE tokens, cookies, or Authorization headers.

Error codes

Error responses use:

Rate limits

Profile endpoints have stricter limits than normal data endpoints: Responses include the standard PolyNode rate-limit headers: