Connect

@openmarketsai/connect-node · connect-web · POST /flow/v1/auth/account/link-sessions · POST /flow/v1/connect/link-sessions
Live

Venue accounts — Kalshi, Polymarket, ProphetX and the rest — get linked on one hosted, co-branded page, and never through your code. Connect is for everyone: yourself, your app's users, or your own customers who never get an OpenMarkets account.

Three ways in

The same hosted page at connect.openmarkets.ai; a different credential opens it.

Way inWhose venuesCredentialNeeds
Yourselfyour own accountConsole → Connectaccount:write — Pro and up
Through your appyour marketplace app's users, on their own accountsinstall key · POST /auth/account/link-sessionsthe user consented to account:link
For your own userspeople who are yours, not OpenMarkets' — one sub-account eachorg key · POST /connect/link-sessions · X-OpenMarkets-Accountconnect:read / write / trade — an organization plan
Pick by whose users they are. If people already have an OpenMarkets account — because they signed in to your app with it — use the second row. If they never will, you are an organization: the third row, with your own user ids. Do not give the same people both an install and a sub-account.

What you skip

OpenMarkets handles

  • The hosted page, co-branded with your name and icon (the OpenMarkets mark always shows)
  • Credential storage — encrypted at rest, tested against the venue before it is kept, never returned
  • Per-venue permissions the user sets: history:read, trade:execute, balance:read
  • Execution limits, pausing a venue, disconnecting — enforced server-side on every call
  • Venue history sync and the settled record it produces (OM-03)
  • Signed webhooks when a user connects, changes permissions, or syncs

You do

  • Hand the user a link, or open the page from a button
  • Read balances, positions and history through one API
  • Trade on their behalf, within what they granted
  • Verify the webhook and dedupe on delivery_id

Yourself

account:write

Open the console's Connect page and choose Manage venues. It mints a self link session and sends you to the hosted page; when you come back, your linked venues, balances and permissions are on the same page. Your API key then reads and trades on your own account with no act-as header at all.

A first-party app can do the same by calling the endpoint with the person's session: POST /flow/v1/auth/account/link-sessions with Authorization: Bearer returns a hosted_url to send them to.

Through your app

account:link · install key

Add account:link to your app's scopes. The user approves it on the consent screen; your app can then open the hosted page for them, branded with your app's name. The venues they link belong to their account, and your app reaches them only through the other scopes it holds.

const res = await fetch('https://api.openmarkets.ai/flow/v1/auth/account/link-sessions', {
  method: 'POST',
  headers: { 'X-API-Key': (await auth.getApiKey())!, 'Content-Type': 'application/json' },
  body: JSON.stringify({ return_url: 'https://yourapp.example/settings?linked=1', mode: 'connect' }),
})
const { data } = await res.json()
window.location.assign(data.hosted_url)   // 15-minute link; redirect, don't open a popup
  • return_url must be on the origin of one of your registered redirect URIs.
  • mode: connect to add a venue, manage (the default) to review what is linked and its permissions.
  • allowed_partners narrows the venues offered; omit it for all.
  • The response is { link_session_id, link_token, hosted_url, expires_at }. Any other credential — an organization key, say — is refused with 403 player_required.

The rest of the app story — sign-in, scopes, notifications — is on Sign in with OpenMarkets.

For your own users

connect:read · connect:write · connect:trade

You address every user by your own id. OpenMarkets provisions a sub-account for it on first use, keyed to your organization, and every call carries two headers: your key, and X-OpenMarkets-Account naming the user.

POST /flow/v1/connect/link-sessions
X-API-Key: om_exec_live_...

{ "external_user_id": "your-user-123",
  "return_url": "https://app.yourco.com/openmarkets/done" }

→ { "hosted_url": "https://connect.openmarkets.ai/start?token=lt_live_...", "link_token": "lt_live_..." }

Your Connect flow — venue allowlist, practice-only or real money, the permissions offered, which AI providers may be linked, branding, return URLs — is configured in the console under your organization. It is snapshotted onto each session at mint, so changing it never alters a link a user already holds.

The full walk-through — minting links, the button, webhooks, reading accounts, trading — is the integration guide.

What the user controls

  • Per-venue permissions. history:read, trade:execute and balance:read are granted per venue, per connection, on the hosted page. A venue without balance:read is omitted from balance reads; a buy on a venue without trade:execute is refused with 403 scope_not_granted, naming the venue. Your entitlement lets you act; it never overrides what the user agreed to.
  • Execution limits. A cap on any single order, a venue allowlist, a pause. Set on the hosted page; read-only to you at GET /connect/users/:id/policy.
  • Disconnect. Removes the stored credential. The consent record is kept, frozen.

The verified record

OM-03 · record:read

Once a venue is linked, OpenMarkets syncs its history and grades it: settled wins, losses, stake, return and ROI per venue, computed from the venue's own data. A person can share exactly that — not balances, not open bets — with an app that holds record:read. Details on Sign in with OpenMarkets.

Packages

@openmarketsai/connect-node wraps every organization call (users, link sessions, webhooks, act-as reads and orders, AI Connect). @openmarketsai/connect-web opens the hosted page from a button, in a popup or a redirect, with a React binding. Neither is required — everything here is plain HTTP.

Next