> For AI agents: the complete documentation index is available at [llms.txt](https://docs.snaptrade.com/llms.txt). Markdown versions of documentation pages are available by appending .md to the URL path.

# Generate Connection Portal URL

POST https://api.snaptrade.com/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.


Reference: https://docs.snaptrade.com/reference/Authentication/Authentication_loginSnapTradeUser

## Code Examples

### TypeScript

```typescript

import { Snaptrade } from "snaptrade-typescript-sdk";

const snaptrade = new Snaptrade({
  clientId: "PARTNER_CLIENT_ID",
  consumerKey: "CONSUMER_KEY",
});

const response =
  await snaptrade.authentication.loginSnapTradeUser(
    {
      userId: "snaptrade-user-123",
      userSecret:
        "adf2aa34-8219-40f7-a6b3-60156985cc61",
      broker: "ALPACA",
      immediateRedirect: true,
      customRedirect: "https://snaptrade.com",
      reconnect:
        "8b5f262d-4bb9-365d-888a-202bd3b15fa1",
      showCloseButton: true,
      darkMode: true,
      connectionPortalVersion: "v4",
    },
  );
console.log(response.data);

```

### Python

```python

from pprint import pprint
from snaptrade_client import SnapTrade

snaptrade = SnapTrade(
    client_id="PARTNER_CLIENT_ID",
    consumer_key="CONSUMER_KEY"
)

response = snaptrade.authentication.login_snap_trade_user(
    user_id="snaptrade-user-123",
    user_secret="adf2aa34-8219-40f7-a6b3-60156985cc61",
    broker="ALPACA",
    immediate_redirect=True,
    custom_redirect="https://snaptrade.com",
    reconnect="8b5f262d-4bb9-365d-888a-202bd3b15fa1",
    show_close_button=True,
    dark_mode=True,
    connection_portal_version="v4"
)
pprint(response.body)

```

## OpenAPI Specification

```yaml

openapi: 3.0.0
info:
  description: Connect brokerage accounts to your app for live positions and trading
  version: 1.0.0
  title: SnapTrade
  termsOfService: N/A
  contact:
    email: api@snaptrade.com
  x-konfig-ignore:
    potential-incorrect-type: true
  x-readme:
    explorer-enabled: false
paths:
  /snapTrade/login:
    post:
      tags:
        - Authentication
      summary: Generate Connection Portal URL
      operationId: Authentication_loginSnapTradeUser
      description: >
        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.
      parameters:
        - in: query
          required: true
          name: userId
          schema:
            description: >-
              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.
            type: string
            example: snaptrade-user-123
        - in: query
          required: true
          name: userSecret
          schema:
            description: >-
              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).
            type: string
            example: adf2aa34-8219-40f7-a6b3-60156985cc61
      requestBody:
        content:
          application/json:
            schema:
              description: Data to login a user via SnapTrade Partner
              type: object
              properties:
                broker:
                  description: >-
                    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.
                  type: string
                  example: ALPACA
                immediateRedirect:
                  description: >-
                    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.
                  type: boolean
                  example: true
                customRedirect:
                  description: >-
                    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.
                  type: string
                  example: https://snaptrade.com
                reconnect:
                  description: >-
                    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.
                  type: string
                  example: 8b5f262d-4bb9-365d-888a-202bd3b15fa1
                connectionType:
                  description: >
                    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.
                  type: string
                  enum:
                    - read
                    - trade
                    - trade-if-available
                  default: read
                showCloseButton:
                  description: >-
                    Controls whether the close (X) button is displayed in the
                    connection portal. When false, you control closing behavior
                    from your app. Defaults to true.
                  type: boolean
                  example: true
                darkMode:
                  description: >-
                    Enable dark mode for the connection portal. Defaults to
                    false.
                  type: boolean
                  example: true
                connectionPortalVersion:
                  description: >-
                    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.
                  type: string
                  example: v4
                  enum:
                    - v4
                    - v3
                    - v2
                  default: v4
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                oneOf:
                  - description: Redirect uri upon successful login
                    type: object
                    properties:
                      redirectURI:
                        description: >-
                          Connection Portal link to redirect user to connect a
                          brokerage account.
                        type: string
                        example: >-
                          https://app.snaptrade.com/snapTrade/redeemToken?token=npVKchZrL0MYIHTusGfADT74r4xXpHkmbxbQDmt0RINLXbQ5cWsvGkPSgMQRxz8/cnxjzL9T2NWLuHuDyidHiCNeXXTb/tVhzC2olSyfxWW6DRrkUppArGCdmkIHyBMzog6C55P8yoqzcGer5Hml0Q%3D%3D&clientId=WEALTHLY&broker=ROBINHOOD&connectionPortalVersion=v4&sessionId=cf371bb4-a475-4f17-ab94-d0fee699960d
                      sessionId:
                        description: ID to identify the connection portal session.
                        type: string
                        example: cf371bb4-a475-4f17-ab94-d0fee699960d
                  - description: >
                      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()
                        ```
                    type: object
                    additionalProperties: false
                    properties:
                      encryptedSharedKey:
                        type: string
                        example: 5UEaY9QGzcNTr8y2jGDUI79jY1OdfK9x
                      encryptedMessageData:
                        type: object
                        properties:
                          encryptedMessage:
                            type: string
                            example: 9Xy05vqZOfp0OpW5fLAaDw==
                          tag:
                            type: string
                            example: mWZPkpQh5ktbcz6N7cTRmQ==
                          nonce:
                            type: string
                            example: None
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                description: Example for failed request response
                type: object
                properties:
                  default_detail:
                    example: Unable to verify data sent
                  default_code:
                    example: 1076
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                description: Example for failed request response
                type: object
                properties:
                  default_detail:
                    example: User does not have permission to access this resource
                  default_code:
                    example: 1066
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                description: Example for failed request response
                type: object
                properties:
                  default_detail:
                    example: The requested resource does not exist.
                  default_code:
                    example: 1011
        '500':
          description: Unexpected Error

```