Skip to main content
This guide is for exchanges, DeFi aggregators, trading terminals, agents, and other applications that want to let their users trade on QFEX while earning builder rewards. The recommended integration has two independent pieces:
  1. OAuth identifies and authorises the QFEX user. Each end user signs in to QFEX and authorises your application. New users create their QFEX account on QFEX rather than sharing QFEX credentials with your application.
  2. Your builder code identifies your integration. Your application attaches the same builder code to each authenticated Trade WebSocket session it opens for those users.
A builder code is not assigned permanently to an end-user account. It is attached to a Trade WebSocket connection. Every eligible order sent over that connection is attributed to the builder code for the life of the connection.

Integration model

A typical aggregator has:
  • one QFEX account owned by the aggregator;
  • one active builder code owned by that account;
  • one registered QFEX OAuth client for the aggregator application; and
  • one OAuth grant and token set for each QFEX user who connects their account.
You do not create a new builder code for every trader. For example, if an aggregator has builder code 11111111-1111-4111-8111-111111111111, it uses that same code when authenticating the QFEX Trade WebSocket for Alice, Bob, and every other user who trades through the aggregator. Each user still authenticates with their own QFEX OAuth access token.

Before you start

1. Create your builder code

Sign in to QFEX and create a builder code in Developer Settings → Builder code. You can also create it with POST /user/builder-code. Store the returned UUID as application configuration, for example:
The builder code is an identifier, not a user credential. Your QFEX API secrets and OAuth tokens are sensitive and must be stored separately. See Builder Codes API for fee-share configuration and builder-code lifecycle operations.

2. Register an OAuth client

Contact support@qfex.com to register your integration as a QFEX OAuth client. Provide:
  • your application name;
  • your production redirect URI or URIs;
  • a logo URL, if available; and
  • whether the client is public or confidential.
Use a confidential client when your application has a backend that can keep a client secret. Browser-only, mobile, and desktop applications must use a public client and must never embed a client secret. QFEX OAuth uses the OAuth 2.1 authorization-code flow with PKCE.
A QFEX OAuth access token is a user session credential and can authorise trading as that user. Treat access and refresh tokens as secrets. Do not log them, put them in analytics events, or expose a confidential client’s tokens to the browser.

End-user flow

Step 1: User selects Connect QFEX

When the user selects Connect QFEX in your application:
  1. Generate a high-entropy state value.
  2. Generate a PKCE code_verifier.
  3. Derive the SHA-256 code_challenge from the verifier.
  4. Store state and code_verifier in the user’s server-side session or another secure short-lived store.
  5. Redirect the user to the QFEX authorization endpoint.
Example in Node.js:
Never omit state or PKCE.

Step 2: QFEX handles sign-in or account creation

The user is sent to QFEX, not to a credential form owned by your application.
  • If the user already has a QFEX account, they sign in and complete any required MFA.
  • If the user does not have an account, they create one with QFEX and complete the required QFEX onboarding steps.
  • The user reviews the OAuth authorisation request and approves or denies your application.
Your application should not collect the user’s QFEX password, MFA code, API secret, or service-role credentials. It should also not create users directly through the underlying authentication provider. Keeping account creation on QFEX ensures that QFEX controls account verification, terms, eligibility, and onboarding.
During the current pre-release flow, OAuth continuation through brand-new account signup and onboarding is still being completed. Existing QFEX users can complete the OAuth round-trip end-to-end. A user who creates a new QFEX account may need to finish onboarding, return to your application, and select Connect QFEX again. This extra step is intended to be removed before the builder integration is generally available.

Step 3: Handle the OAuth callback

After approval, QFEX redirects to the registered redirect_uri with an authorization code and the original state.
On your callback endpoint:
  1. Reject the request if state does not exactly match the value stored in the user’s session.
  2. Read the stored PKCE code_verifier.
  3. Exchange the authorization code for tokens.
  4. Delete the one-time state and code_verifier from the session.

Step 4: Exchange the code for QFEX tokens

For a confidential server-side client, authenticate the client with HTTP Basic auth and send the PKCE verifier:
A successful response contains an access token and refresh token. Store both securely against the connected user. For a public client, omit the client secret and include client_id in the form body instead. Public clients still use PKCE.

Step 5: Open the Trade WebSocket and attach your builder code

Use the user’s OAuth access_token as the JWT. The WebSocket upgrade and the QFEX auth message both use the user’s token; your builder code is added to the auth message.
If the user selected a QFEX subaccount, include its ID on the same auth message:
The builder code is now fixed for the lifetime of that WebSocket connection. Do not add it to each individual order.

Step 6: Trade normally

After the auth response succeeds, place orders using the normal Trade WebSocket API.
Orders, stop orders, and TWAPs submitted over the attributed connection inherit your builder code automatically. Builder rewards are credited to the QFEX account that owns the builder code. OAuth does not bypass QFEX account requirements. If the account still needs identity verification, updated terms acceptance, or another required onboarding step, trading can be rejected until the user completes it on QFEX. See:

Step 7: Refresh tokens and reconnect

OAuth access tokens expire. Use the refresh token to obtain a new access token before expiry or after an authentication failure. For a confidential client:
When you create a new Trade WebSocket with the refreshed access token, attach your builder code again in the new auth message. If the user revokes your application in QFEX, stop trading for that user and send them through the OAuth flow again if they choose to reconnect.

Existing users and new users use the same entry point

Your integration should expose one Connect QFEX action. Do not build separate “sign up” and “sign in” APIs on your side.

Builder attribution is connection-scoped

Builder attribution is intentionally independent of account creation and OAuth. This means:
  • the end user’s QFEX account is not permanently tied to a builder;
  • the same user can trade through different builders at different times;
  • a user trading directly on QFEX is not automatically attributed to your builder;
  • every Trade WebSocket your integration opens must include your builder_code; and
  • reconnecting without the code removes builder attribution from that new connection.
This also means you should set builder_code from trusted application configuration rather than accepting an arbitrary value from the browser or end user.

Security checklist

Before going live:
  • use Authorization Code + PKCE for every OAuth flow;
  • validate state on every callback;
  • register exact HTTPS redirect URIs and avoid wildcard callbacks;
  • keep confidential-client secrets, access tokens, and refresh tokens server-side;
  • encrypt refresh tokens at rest;
  • never log access tokens, refresh tokens, authorization codes, or QFEX API secrets;
  • do not ask users for QFEX passwords or MFA codes inside your application;
  • reconnect the Trade WebSocket with the new access token after a refresh;
  • attach your configured builder code on every new Trade WebSocket; and
  • stop trading immediately if authorization is revoked.
The standard OAuth scopes describe identity information returned by the OAuth provider. They should not be treated as a read-only or trade-only permission boundary for QFEX trading. An access token used with QFEX trading APIs must be protected as a credential capable of acting as the user.

End-to-end checklist

A production integration is complete when you can test all of the following:
  1. A user with no QFEX account can enter the QFEX account-creation flow from Connect QFEX and, once new-user OAuth continuation is released, return to the original authorisation request after onboarding.
  2. An existing QFEX user can connect without sharing credentials with your application.
  3. Your callback rejects an invalid state or PKCE verifier.
  4. You can exchange the authorization code and securely store the returned token set.
  5. You can authenticate wss://trade.qfex.com with the user’s access token.
  6. The Trade WebSocket auth message includes your builder UUID automatically.
  7. A normal order, stop order, and TWAP placed through that connection are attributed to your builder.
  8. Token refresh followed by WebSocket reconnection preserves builder attribution.
  9. Revoking the connected application prevents continued use of the revoked authorization.
If you need an OAuth client registered for an integration, contact support@qfex.com.