> ## 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.

# Pass Connect conformance

> Run your app's whole Connect journey against the sandbox, which deliberately causes errors, and earn the Connect pass that opens your app's production.

Prove your app handles the Connect journey before your traders depend on it. You open a run in the
Connect dashboard, use your app as your traders would, and the sandbox watches your backend's requests and
hosted Connect on your website. It also deliberately throws a rate limit, a risk lock, a dropped
stream and an expired Connect link at your integration. When you close the run, every rule comes
back passed, failed or not exercised, with what was seen.

Use this page when your app works end to end in the sandbox, and again after every fix. Runs are free
and unlimited, and the sandbox grades each one itself. By the end you have a closed run with every
rule passed, a certificate that lasts twelve months, and the Connect pass that opens your app's
production.

<Note>
  Runs are served only in the sandbox, because a deliberate fault must never reach a real trader.
  Connect apps run in the sandbox today. Once production opens to them, your app's Connect pass opens
  its production, as [Open production](#open-production) describes.
</Note>

## Before you start

1. Your app works end to end in the sandbox: your server creates Connect links, your page opens
   hosted Connect on your website, and your backend reads your traders' accounts and routes their
   orders. The [Connect quickstart](/guides/connect-quickstart) gets you there.
2. Your backend holds your app's sandbox API key, and you can sign in to the Connect dashboard as an
   owner or an editor of your app.
3. Your white-label paper is on, or your Connect offers a provider you hold a sandbox login for, so a
   test trader can complete a connection.
4. Use test traders, never real ones. While a run is open, requests made with your app's API keys,
   and the Connect links they create, can receive deliberate errors. Outside a run the sandbox
   behaves normally.

Drive the run with your real backend, page and reconnect code, not a test client written to pass:
the run is there to measure how your app behaves.

<Steps>
  <Step title="Open a run">
    In the Connect dashboard, open **Conformance** and start a run. It's graded under the `connect`
    ruleset at version `1.0`, and it lists its rules, each with how to exercise it. A run stays open
    for two hours, and you can have one open at a time.
  </Step>

  <Step title="Use your app">
    Go through the journey your traders take, more than once. During the run, make sure your app
    does all of this:

    | Do this | The rule it exercises |
    | - | - |
    | Create Connect links from your backend, each for a trader you name and with an `Idempotency-Key`. A passing run creates at least two | `connect_link_named` |
    | Open hosted Connect on your website with those links | `connect_opened` |
    | Complete a connection in hosted Connect: open your white-label paper, or sign in to a provider | `connect_completed` |
    | Read the trader's accounts with `GET /api/account/list` | `trader_accounts_read` |
    | Read one of their accounts, such as `GET /api/account/snapshot` with its provider and account | `trader_account_read` |
    | Hold `GET /api/account/stream` open for one of their accounts and read its snapshot | `trader_account_stream` |
    | Read `GET /api/trading/actions` for an account and an instrument before you route an order | `trading_actions_read` |
    | Route the trader's orders, each with a `clientOrderId` | `client_order_id_present` |
    | Move or cancel a working order with `POST /api/trading/replace` or `POST /api/trading/cancel` | `order_amended` |
    | Make every call with your API key from your backend, at least five in all | `api_key_server_side` |

    The run also answers some of your requests badly, once each, for your app to handle:

    | The sandbox | Your app must | Rule |
    | - | - | - |
    | Rate-limits one of your calls on a trader's routes with `429` and `Retry-After: 3` | Wait the stated three seconds before it calls again for that trader | `rate_limit_backoff` |
    | Risk-locks one of your orders with `423` | Stop sending that order. Stay quiet about it for at least ten seconds; you don't need to send it again | `risk_lock_respected` |
    | Drops one account stream after its snapshot | Reconnect and take the fresh snapshot | `stream_reconnect` |
    | Refuses one fresh Connect link as expired, on your first or second open. Your page hears `connect_unavailable` | Open Connect next with a fresh Connect link, never the one refused | `connect_link_renewed` |

    Every request the run sees answers with the header `x-trdrs-conformance-run`, naming the run, and
    each deliberate error also carries `x-trdrs-conformance-fault`. An expired Connect link looks
    exactly as a real one does. Handle each the way you would in production.
  </Step>

  <Step title="Read the tally">
    Check progress in **Conformance** at any time while the run is open. The grade lists each rule as
    passed, failed or not exercised, with its counts and a note saying what to do next or what went
    wrong. One failure fails its rule, and later successes don't
    erase it. A fault your app hasn't answered yet counts only when the run closes.
  </Step>

  <Step title="Close the run">
    Close the run in **Conformance** to grade it. After the injected risk lock, wait at least ten
    seconds first.

    The run closes passed only when every rule was exercised and passed. A rate limit, a dropped
    stream or an expired link your app never answered fails its rule; a risk lock you left alone for
    ten seconds passes. A passed run carries a certificate, twelve months on. Deliberate errors stop
    the moment the run closes.
  </Step>
</Steps>

## What a pass means

A pass measures how your app handled the journey and its faults on the wire. It earns a certificate
that stays current for twelve months under the ruleset's major version, and a new major version
expires it at once. When it nears its end, run again: runs are free, and a passing one takes an
afternoon. Nothing on your Connect shows that your app passed.

From a current certificate, the sandbox signs a Connect pass addressed to production, for an app
the Connect dashboard opened in both environments. The pass names that production app, the owner's
verified email, the run and when its certificate expires, and it opens your app's production.

A pass can't see your screens. Check yourself that a money field that's `null` shows as unknown,
never as zero.

## Open production

Open your app's production with its Connect pass, once a run has passed. An owner of your app opens it
from **Conformance** in the Connect dashboard: the dashboard reads your app's pass from the sandbox and
hands it to production. Production checks that the sandbox signed it, for this app and for your own
verified email, and records it. Your app's production is open from then:

* You create production API keys, which start `trdrs_ck_production_`.
* Each production website you add applies at once. It's an exact `https` origin.
* Your app is billed at \$2 per active trader each month, from the month production records its first
  pass. [Active traders](/guides/connect-active-traders) says who counts.

Opening production again with the same pass changes nothing, so a retry is safe.

<Note>
  Your app keeps running in production when its certificate expires: its API keys, websites and
  traders work as before. A new API key needs a certificate that stands, so pass a fresh run and open
  production again with its pass. A new major version of the ruleset expires every certificate at
  once.
</Note>

When production refuses a pass, it answers `403` with one of these codes:

| Code | When | What to do |
| - | - | - |
| `pass_invalid` | The pass isn't one the sandbox signed with a key production holds, or it was altered. | Open production again; the dashboard reads a fresh pass. |
| `pass_expired` | Its certificate expired, or the ruleset's major version changed since the run passed. | Pass a fresh run, then open production. |
| `pass_wrong_app` | It names another production app. | Open production from the app it names. |
| `pass_wrong_owner` | The sandbox signed it for another email than yours. | Sign in to the Connect dashboard as yourself, and open production with your own pass. |

Until your app holds a pass, production answers its API key and website routes with `409`
`conformance_required`. Once its certificate has expired, a new API key is answered with `409`
`conformance_expired`.

## When a run is refused

| What the dashboard says | When | What to do |
| - | - | - |
| A run is already open | Your app has a run open. | Read it or close it. |
| The run is closed | It already closed, and its grade says how it ended. | Open a new run. |
| Only in the sandbox | You're in production. | Run conformance in the sandbox. |
| Your role can't do this | An owner or an editor opens and closes runs, and a reader reads them. | Ask an owner or an editor. |

## The routes this page calls

The Connect dashboard makes these calls with your team's Connect sign-in:

| Step | Route |
| - | - |
| Open a run | `POST /api/connect/apps/{appId}/conformance/runs` |
| Read the tally | `GET /api/connect/apps/{appId}/conformance/runs/{runId}` |
| Close the run | `POST /api/connect/apps/{appId}/conformance/runs/{runId}/close` |
| Read your Connect pass | `GET /api/connect/apps/{appId}/production`, in the sandbox |
| Open production | `POST /api/connect/apps/{appId}/production`, in production |

## Next steps

<CardGroup cols={2}>
  <Card title="Route your traders' orders" icon="chart-line" href="/guides/route-your-traders-orders">
    Fix what the run found in your order routing and streams.
  </Card>

  <Card title="Connect SDK" icon="link" href="/sdks/connect">
    Handle `connect_unavailable` and the other events on your page.
  </Card>

  <Card title="Active traders" icon="receipt" href="/guides/connect-active-traders">
    See how Connect is billed per active trader.
  </Card>

  <Card title="Rate limits" icon="gauge" href="/api/rate-limits">
    Read how a `429` and its `Retry-After` work.
  </Card>
</CardGroup>


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