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

# Connect SDK

> Open the hosted account picker from your website, with your Venue key kept on your server.

Let a trader connect their trading account from your own website. Use this page when your venue
wants Connect, the trdrs account picker, inside your site rather than only in the trdrs trading
app.

Your server creates a short-lived session with your Venue key, your page asks your server for the
session's token, and the SDK opens the hosted picker in a secure frame. Your page never holds the
key and never builds the frame itself. By the end a trader can connect from your site, and your
server can confirm what happened.

<Info>
  Hosted Connect is a preview. The sandbox host is `https://trdrsco-connect-sandbox.fly.dev`.
  Production access and the final host are arranged before launch.
</Info>

## Before you start

1. Create a Venue key with the `connect:manage` scope in API access in the sandbox. It stays on
   your server.
2. Register your website's exact origin under **Developers → Connect websites** in the sandbox
   back office. An origin is the scheme and host, such as `https://your-app.example`, with no path
   and no wildcard. It must use `https`, except `http://localhost` while you develop. A sandbox
   website is approved at once; a production website waits for review.
3. Put your venue's id in `TRDRS_VENUE_ID` and the key in `TRDRS_VENUE_KEY` on your server.

<Steps>
  <Step title="Create a session on your server">
    When a signed-in trader asks to connect, your server creates a session for that trader's email
    and your page's origin. This call must run on your server, because it carries the Venue key.

    ```js server.js theme={null}
    const response = await fetch(
      `https://sandbox.trdrs.co/api/partner/venues/${process.env.TRDRS_VENUE_ID}/connect/sessions`,
      {
        method: 'POST',
        headers: {
          authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,
          'content-type': 'application/json',
          'idempotency-key': crypto.randomUUID(),
        },
        body: JSON.stringify({
          origin: 'https://your-app.example',
          email: 'trader@example.com',
          expiresInSeconds: 300,
        }),
      },
    )

    if (!response.ok) throw new Error('Connect session could not be created')
    const { session } = await response.json()
    // Send session.token to this trader's browser. Never send the Venue key.
    ```

    The response is `201` with a `session` carrying its `id`, the `token` for the browser,
    `expiresAt`, the `origin` and the `environment`. Keep the `id` on your server to check the
    result later.

    `expiresInSeconds` is required, a whole number from 60 to 600, so a session lasts ten minutes
    at most. The token works for one venue, one environment, one origin and one email. Send a new
    `idempotency-key` each time you mean to create a new session, and reuse it only to retry the
    same one.

    Required scope: `connect:manage`.
  </Step>

  <Step title="Open Connect in the browser">
    Your page asks your server for a token, then calls `createConnect` and `open()`. The SDK adds
    the frame and removes it when Connect closes.

    ```html index.html theme={null}
    <button id="connect-account" type="button">Connect a trading account</button>
    <p id="connect-status" role="status"></p>

    <script type="module">
      import { createConnect } from
        'https://trdrsco-connect-sandbox.fly.dev/sdk/connect.js'

      const button = document.querySelector('#connect-account')
      const status = document.querySelector('#connect-status')

      button.addEventListener('click', async () => {
        const response = await fetch('/api/connect-session', { method: 'POST' })
        if (!response.ok) throw new Error('Connect session could not be created')
        const { token } = await response.json()

        const connect = createConnect({
          token,
          host: 'https://trdrsco-connect-sandbox.fly.dev',
        })

        connect.on(event => {
          if (event.type === 'connected') status.textContent = 'Connected. Checking with the server.'
          if (event.type === 'closed') status.textContent = 'Connect was closed.'
          if (event.type === 'error') status.textContent = `Connect error: ${event.code}`
        })

        connect.open()
      })
    </script>
    ```

    `/api/connect-session` is your own server route from the first step. The trader signs in to
    trdrs inside the frame and picks or connects an account.

    The SDK sends four events:

    | Event | What it means |
    | - | - |
    | `ready` | The picker loaded and is ready for the trader. |
    | `connected` | A connection finished. It's a signal only and carries no account details. |
    | `closed` | The trader closed Connect without finishing. |
    | `error` | Connect couldn't continue. `code` says why, and it's safe to show. |

    `close()` removes the frame. To open Connect again after a session finishes or expires, create
    a new session. Where a frame doesn't fit, such as a small mobile web view, call
    `connect.redirect()` instead of `open()`: the trader goes to the hosted page and comes back to
    yours when they're done.
  </Step>

  <Step title="Confirm the result on your server">
    A browser event is for your interface, never proof of anything. Your server reads the session
    it created:

    ```bash theme={null}
    curl "https://sandbox.trdrs.co/api/partner/venues/$TRDRS_VENUE_ID/connect/sessions/$SESSION_ID" \
      -H "Authorization: Bearer $TRDRS_VENUE_KEY"
    ```

    The response gives the session's status and a redacted outcome. It never returns provider
    credentials, the browser's tokens or another trader's account. To end a session early, send
    `DELETE` to the same path. Closing is safe to repeat and never undoes a finished connection.
  </Step>
</Steps>

## Follow the security rules

* Keep the Venue key on your server. Never put it in JavaScript, HTML, a mobile app or a Connect
  address.
* Register exact origins. `https://app.example.com` and `https://admin.example.com` are different
  origins, and each needs its own entry.
* Create each session for the signed-in trader's real email. A different trdrs user can't use it.
* Treat `connected` as a hint for your interface, and confirm anything important on your server.

## When a session is refused

| Status | What it means | What to do |
| - | - | - |
| `400` | The body is invalid: an origin with a path or wildcard, a malformed email, or `expiresInSeconds` outside 60 to 600. | Fix the request. |
| `400` | `idempotency_key_required`: the request has no `idempotency-key` header. | Send one. |
| `401` | The Venue key is missing or invalid. | Check the key. |
| `403` | The key lacks `connect:manage` (`permission_denied`), or the origin isn't an approved website for your venue (`origin_not_approved`). | Add the scope, or register the origin. |
| `409` | The `idempotency-key` was already used with a different body. | Use a new key for a new session. |

## Next steps

<Columns cols={2}>
  <Card title="Connect overview" icon="link" href="/guides/connect-overview">
    See how traders reach your venue's accounts through Connect.
  </Card>

  <Card title="Venue keys" icon="key" href="/guides/venue-keys">
    Create a Venue key with only the scopes your server needs.
  </Card>

  <Card title="Create a Connect session" icon="code" href="/api-reference/venue-platform-preview/create-a-connect-link-session">
    Read every field of the session request and response.
  </Card>
</Columns>
