SSO with ShortGrantCode
Once your backend can mint a partner access token, the short grant code handoff sends a signed-in user to a NinjaTrader-hosted page, such as the trader dashboard or an account page, without a second login. The access token stays on your backend and only a short-lived, single-use code travels through the browser.
How the Flow Works
- Your backend calls
shortGrantCodewith the partner access token it holds for that user. - NinjaTrader returns
codeandexpires_in. - Your backend redirects the user’s browser to the NinjaTrader application with the code attached, and the application redeems it with
exchangeShortGrantCode.
Prerequisites
This flow uses the same onboarding as the base integration, with nothing extra. Your issuer, signing keys and JWKS URL, audience, API hostnames, and pilot user IDs are all you need. NinjaTrader confirms the application host you should redirect users to at the same time it confirms your API hostnames.
Minting a Code
expectedClientIp is the address from which the user’s browser will reach the exchange endpoint, resolved through your own load-balancer-aware logic. The code is bound to it, and redemption from anywhere else is rejected.
expectedClientIp is what selects partner mode, and the schema does not require it. Omitting it does not return an error. The request silently falls back to the non-partner path, which binds the code to your backend’s address instead of the user’s, so the redirect then fails at redemption. Always send it.Note the underscore in expires_in. Read the lifetime back from that field rather than assuming it, because ttl is a request and not a guarantee: the server clamps it to the per-environment maximum, which is 30 seconds in production, and omitting ttl or sending zero or less gives 15 seconds.
Other properties worth knowing:
codeis opaque. Do not parse it, log it, or hold it longer than the redirect needs.- Codes are single-use, and minting a second code for the same user invalidates the first.
- Unused codes expire on their own, so there is nothing to clean up if the user closes the tab.
- The partner access token used to mint a code identifies the same user as the
subin your original assertion. You cannot mint a code for one user with another user’s token.
Mint the code at the moment you are ready to redirect, not in advance.
Redirecting the User
Pass the code as the h query parameter:
Or in the browser:
The host must be the one NinjaTrader confirmed during onboarding. An unrecognized host fails at redemption, because the exchange only accepts NinjaTrader-owned origins.
A query parameter is appropriate here even though the code is sensitive: its lifetime is measured in seconds, it is single-use and redeemed within about a second of page load, it is bound to the redeeming client’s address, and the application strips h from the URL immediately after reading it. The URL fragment is reserved for the iframe flow, where the value that travels is a full access token rather than a one-shot code.
Keep the redirect URL clean:
- Do not include the partner access token, the assertion, a user ID, or any other partner-side identifier. The
hparameter is all that is needed. - Do not add tracking parameters or custom query strings, which may be treated as misuse.
- Do not use a meta refresh or a delayed link. The code can expire before the user acts, so redirect immediately.
Rate Limits
Quotas are tier-dependent and confirmed during onboarding.
Handling Errors
The two endpoints do not share a response shape, and neither signals failure through the status code alone.
HTTP 200 for policy rejections as well as successes, so do not branch on the status code. Test for success by checking both errorText and whether a token is present: at redemption, a restricted session returns an accessToken alongside a non-empty errorText carrying a warning, so errorText alone misreads that case as a failure. HTTP 401 means only that the access token is missing or expired, and HTTP 400 means the request failed field validation.At the minting step, every partner-policy rejection returns the same message, "Short grant codes are not available for this account". The specific reason is deliberately not disclosed on the wire and is recorded only in NinjaTrader’s logs. The underlying causes are:
At redemption, failures do surface distinct messages, including an unrecognized or already-redeemed code, an address that does not match the one the code was bound to, and an origin outside the NinjaTrader-owned hosts. The full list is on exchangeShortGrantCode.
Because the address comparison is an exact string match, two textual forms of the same IPv6 address do not match. Emit expectedClientIp in the form the client will present at redemption.
Testing
Mint a code bound to your egress address, then open the redirect in a browser and confirm you land in the NinjaTrader application already signed in. Worth exercising before go-live:
Going Live
- The base integration is complete on staging and can mint partner access tokens for pilot users.
- The application host for production is confirmed and configured on your side.
expectedClientIpis populated from the user’s address, verified behind your load balancer.- The redirect happens immediately after minting, with no delay or user interaction in between.
HTTP 429and redemption failures are handled, with a fresh code minted on retry.
Next Steps
- Partner Token: the assertion exchange this flow builds on.
shortGrantCodeandexchangeShortGrantCode: full request, response, and error reference.

