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

# Migrate to Polymarket Protocol V2

> Add V2 markets to an existing SDK, API, or smart-contract integration.

export const MigrationPicker = () => {
  const options = [{
    id: "sdk",
    label: "SDK",
    detail: "I trade through @polymarket/client or polymarket-client.",
    title: "SDK integration",
    description: "Upgrade the SDK, select outcomes, and approve V2 trading.",
    href: "/migrate/polymarket-v2/sdk-integrations"
  }, {
    id: "api",
    label: "API",
    detail: "I call the Gamma and CLOB APIs directly and sign orders myself.",
    title: "API integration",
    description: "Update identifiers, approvals, balance reads, and order signing.",
    href: "/migrate/polymarket-v2/api-integrations"
  }, {
    id: "contracts",
    label: "Smart contracts",
    detail: "My contracts or backend call Polymarket contracts directly.",
    title: "Smart contract integration",
    description: "Update contracts, position operations, payouts, and event indexing.",
    href: "/migrate/polymarket-v2/contract-integrations"
  }];
  const primary = "rgb(var(--primary))";
  const primaryTint = "rgb(var(--primary) / 0.08)";
  const [selected, setSelected] = useState([]);
  const toggle = id => setSelected(current => current.includes(id) ? current.filter(item => item !== id) : [...current, id]);
  const guides = options.filter(option => selected.includes(option.id));
  return <div className="not-prose rounded-xl border border-gray-200 dark:border-zinc-800" style={{
    padding: "20px"
  }}>
      <div id="migration-picker-question" className="font-semibold text-gray-900 dark:text-gray-100" style={{
    display: "block",
    fontSize: "16px"
  }}>
        How does your integration connect to Polymarket?
      </div>
      <div className="text-sm text-gray-600 dark:text-gray-400" style={{
    display: "block",
    marginTop: "4px"
  }}>
        Select all that apply.
      </div>

      <div role="group" aria-labelledby="migration-picker-question" style={{
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(190px, 1fr))",
    gap: "12px",
    marginTop: "16px"
  }}>
        {options.map(option => {
    const isSelected = selected.includes(option.id);
    return <button key={option.id} type="button" aria-pressed={isSelected} onClick={() => toggle(option.id)} className={isSelected ? "" : "border-gray-200 dark:border-zinc-800"} style={{
      display: "block",
      width: "100%",
      textAlign: "left",
      padding: "12px 14px",
      borderRadius: "10px",
      borderWidth: "1px",
      borderStyle: "solid",
      cursor: "pointer",
      ...isSelected ? {
        borderColor: primary,
        backgroundColor: primaryTint
      } : {
        backgroundColor: "transparent"
      }
    }}>
              <span className="font-medium text-gray-900 dark:text-gray-100" style={{
      display: "flex",
      alignItems: "center",
      gap: "8px"
    }}>
                <span aria-hidden="true" className={isSelected ? "" : "border-gray-300 dark:border-zinc-600"} style={{
      display: "inline-flex",
      alignItems: "center",
      justifyContent: "center",
      flexShrink: 0,
      width: "16px",
      height: "16px",
      borderRadius: "4px",
      borderWidth: "1px",
      borderStyle: "solid",
      fontSize: "11px",
      lineHeight: 1,
      color: "#fff",
      ...isSelected ? {
        borderColor: primary,
        backgroundColor: primary
      } : {}
    }}>
                  {isSelected ? "✓" : ""}
                </span>
                {option.label}
              </span>
              <span className="text-sm text-gray-600 dark:text-gray-400" style={{
      display: "block",
      marginTop: "6px"
    }}>
                {option.detail}
              </span>
            </button>;
  })}
      </div>

      <div className="border-gray-200 dark:border-zinc-800" style={{
    marginTop: "20px",
    paddingTop: "20px",
    borderTopWidth: "1px",
    borderTopStyle: "solid"
  }}>
        {guides.length === 0 ? <div className="text-sm text-gray-600 dark:text-gray-400">
            Select an option to see the guide for your integration.
          </div> : <div style={{
    display: "grid",
    gap: "12px"
  }}>
            {guides.map(guide => <a key={guide.id} href={guide.href} className="border-gray-200 dark:border-zinc-800" style={{
    display: "block",
    padding: "12px 14px",
    borderRadius: "10px",
    borderWidth: "1px",
    borderStyle: "solid",
    textDecoration: "none"
  }}>
                <span className="font-medium text-gray-900 dark:text-gray-100" style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    gap: "12px"
  }}>
                  {guide.title}
                  <span aria-hidden="true" style={{
    color: primary
  }}>
                    →
                  </span>
                </span>
                <span className="text-sm text-gray-600 dark:text-gray-400" style={{
    display: "block",
    marginTop: "4px"
  }}>
                  {guide.description}
                </span>
              </a>)}
          </div>}
      </div>
    </div>;
};

<Check>
  **App and website users:** No technical migration is required. Complete any
  approval prompts shown in the app.
</Check>

Polymarket Protocol V2 introduces new position tokens and contracts for
trading, position operations, and resolution. Follow the guide for your
integration while retaining CTF support. Existing CTF holdings are not converted.

## What Changes

* **Market identifiers:** Integrations select V2 position IDs or CTF token IDs using the market's version.
* **Trading:** V2 orders use ExchangeV3, signing domain version `"3"`, and new approval targets. CLOB balance and allowance requests for V2 positions use `CONDITIONAL-V2`.
* **Position operations:** V2 balances live in PositionManager. V2 split, merge, and redemption use Router, with updated calls and payout handling.

## Migration Guides

<MigrationPicker />

For integrations already using pUSD and the CTFExchangeV2 order format,
collateral, wallets, CLOB credentials, and endpoints stay the same.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.