---
title: "Generate Connection Portal URL"
method: POST
path: "/snapTrade/login"
tags: ["Authentication"]
---

# Generate Connection Portal URL

`POST /snapTrade/login`

Authenticates a SnapTrade user and returns the Connection Portal URL used for connecting brokerage accounts. Please check [this guide](/docs/implement-connection-portal) for how to integrate the Connection Portal into your app.

Please note that the returned URL expires in 5 minutes.

## Query parameters

- `userId` string, required — SnapTrade User ID. This is chosen by the API partner and can be any string that is a) unique to the user, and b) immutable for the user. It is recommended to NOT use email addresses for this property because they are usually not immutable.
- `userSecret` string, required — SnapTrade User Secret. This is a randomly generated string and should be stored securely. If compromised, please rotate it via the [rotate user secret endpoint](/reference/Authentication/Authentication_resetSnapTradeUserSecret).

## Request body

- SnapTradeLoginUserRequestBody — Data to login a user via SnapTrade Partner
  - `broker` string — Slug of the brokerage to connect the user to. See [the integrations page](https://support.snaptrade.com/brokerages) for a list of supported brokerages and their slugs.
  - `immediateRedirect` boolean — When set to `true`, user will be redirected back to the partner's site instead of the connection portal. This parameter is ignored if the connection portal is loaded inside an iframe. See the [guide on ways to integrate the connection portal](/docs/implement-connection-portal) for more information.
  - `customRedirect` string — URL to redirect the user to after the user connects their brokerage account. This parameter is ignored if the connection portal is loaded inside an iframe. See the [guide on ways to integrate the connection portal](/docs/implement-connection-portal) for more information.
  - `reconnect` string — The UUID of the brokerage connection to be reconnected. This parameter should be left empty unless you are reconnecting a disabled connection. See the [guide on fixing broken connections](/docs/fix-broken-connections) for more information.
  - `connectionType` 'read' | 'trade' | 'trade-if-available' — Determines connection permissions (default: read) - `read`: Data access only. - `trade`: Data and trading access. - `trade-if-available`: Attempts to establish a trading connection if the brokerage supports it, otherwise falls back to read-only access automatically.
  - `showCloseButton` boolean — Controls whether the close (X) button is displayed in the connection portal. When false, you control closing behavior from your app. Defaults to true.
  - `darkMode` boolean — Enable dark mode for the connection portal. Defaults to false.
  - `locale` string — Language the connection portal renders in. `en` and `pt-BR` are the languages we ship; any other language is rejected with a 400. Matching is case- and separator-insensitive, so `pt-br`, `pt-BR` and `pt_BR` are equivalent, and a regional tag resolves to the language when we ship it, so `en-US` renders `en`. Deliberately not an enum: those equivalent spellings are all accepted by the API, and an enum would have generated SDKs reject them before the request is sent. Screens without translated copy fall back to English individually. Defaults to `en`.
  - `connectionPortalVersion` 'v4' | 'v3' | 'v2' — Sets the connection portal version to render. Currently only `v4` is supported and is the default. All other versions are deprecated and will automatically be set to v4.

## Response `200`

OK

- union
  - LoginRedirectURI — Redirect uri upon successful login
    - `redirectURI` string — Connection Portal link to redirect user to connect a brokerage account.
    - `sessionId` string — ID to identify the connection portal session.
  - EncryptedResponse — This response consists of 2 different components that must be decrypted to obtain the decrypted message * Decrypting the encryptedSharedKey The encrypted shared key is a shared key that was randomly generated by SnapTrade and encrypted using the users SSH public key provided when registering the user It is needed to decrypt the message in step 2. To decrypt the shared key, the user should have access to their SSH private key stored locally in their device An example Python code on how to decrypt the shared key is shown below ``` def decrypt_rsa_message(self, encrypted_message): from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA from base64 import b64decode f = open('private.pem', 'r') private_key = RSA.import_key(f.read()) cipher = PKCS1_OAEP.new(private_key) return cipher.decrypt(b64decode(encrypted_message.encode())).decode() ``` * Decrypting the encryptedMessageData The data meant to be returned by an endpoint can be obtained by decrypting the encrypted message An encrypted message is a message that is encrypted using AES - MODE OCB with the shared key obtained in step one An example code to decrypt the encrypted message is shown below ``` def decrypt_aes_message(self, shared_key, encrypted_message): from Crypto.Cipher import AES from base64 import b64decode encrypted_msg = b64decode(encrypted_message["encryptedMessage"].encode()) tag = b64decode(encrypted_message["tag"].encode()) nonce = b64decode(encrypted_message["nonce"].encode()) cipher = AES.new(shared_key.encode(), AES.MODE_OCB, nonce=nonce) return cipher.decrypt_and_verify(encrypted_msg, tag).decode() ```
    - `encryptedSharedKey` string
    - `encryptedMessageData` object
      - `encryptedMessage` string
      - `tag` string
      - `nonce` string

## Other responses

- `400` — Bad Request
- `403` — Forbidden
- `404` — Not Found
- `500` — Unexpected Error

---

[API](https://skmtc.net/passiv/apis/snaptrade.md) · [All operations](https://skmtc.net/passiv/apis/snaptrade/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/passiv/snaptrade/revisions/259274f1e845/schema)
