> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect your Backend with StackOne

> Generate connect session tokens from your backend to securely link customer accounts through the Integration Hub

Connect sessions are short-lived tokens your backend generates to open the Integration Hub for a specific end user. Because they're generated server-side using your API key, your key is never exposed to the frontend.

You'll need a StackOne API key to call the [Connect Sessions endpoint](/platform/api-reference/connect-sessions/).

## Required fields

| Field               | Description                                                                        |
| ------------------- | ---------------------------------------------------------------------------------- |
| `origin_owner_id`   | The ID of the organization in your system (e.g. your customer's org ID)            |
| `origin_owner_name` | A human-readable name for the organization, stored against the account in StackOne |

These two fields combined with `provider` determine whether a new account is created or an existing one is updated. If the same combination has been used before, the existing account opens in edit mode. If not, a new account is created.

<Warning>
  Always set `origin_owner_id` server-side. Never pass it through from a client-side request.
</Warning>

## Optional fields

| Field             | Description                                                                                                                                                                            |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `origin_username` | Identifier for the user initiating the connection (e.g. `jane@company.com`)                                                                                                            |
| `provider`        | Opens the Hub directly at the credential entry step for this provider. Without it, the Hub shows the full provider selection screen.                                                   |
| `categories`      | Array of category keys to open the Hub at the category selection step (e.g. `["hris", "ats"]`). Use when you want the user to pick a provider themselves.                              |
| `account_id`      | If an existing account ID is passed, the Hub opens in edit mode for that account so credentials can be updated.                                                                        |
| `integration_id`  | Routes the session to a specific [auth configuration](/guides/auth-configurations). Use this to target a non-default auth config, for example after a connector major version upgrade. |
| `label`           | Arbitrary string stored against the account.                                                                                                                                           |
| `multiple`        | Set to `true` to create a new account even when an existing one with the same `origin_owner_id` and `origin_owner_name` exists for this provider.                                      |

<Note>
  If no `integration_id` is passed, the connect session is created against the default auth config for the given provider. You can set the default auth config from the [Auth Configs page](https://app.stackone.com/auth_configs).
</Note>

<Warning>
  `provider_version` is deprecated. Passing it no longer selects a connector version and can cause session creation to fail. Remove it from your requests. To target a specific auth configuration, use `integration_id` instead.
</Warning>

## Basic implementation

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { StackOne } from "@stackone/stackone-client-ts";

  const stackOne = new StackOne({
    security: {
      username: process.env.STACKONE_API_KEY,
      password: "",
    },
  });

  app.post('/stackone_connect_sessions', async (req, res) => {
    const { originUsername, provider } = req.body;

    try {
      const result = await stackOne.connectSessions.createConnectSession({
        originOwnerId: "customer-123",
        originOwnerName: "Acme Inc",
        originUsername: originUsername,
        provider,
      });

      res.send({ token: result.connectSessionTokenAuthLink?.token });
    } catch (e) {
      res.status(500).send('error when trying to fetch session');
    }
  });
  ```

  ```python Python theme={null}
  from flask import Flask, request, jsonify
  import requests
  import base64

  app = Flask(__name__)

  @app.route('/stackone_connect_sessions', methods=['POST'])
  def stackone_connect_sessions():
      STACKONE_API_KEY = 'YOUR_STACKONE_API_KEY'
      headers = {
          'Authorization': 'Basic ' + base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode(),
          'Content-Type': 'application/json',
      }
      req_data = request.json

      payload = {
          'origin_owner_id': 'customer-123',
          'origin_owner_name': 'Acme Inc',
          'origin_username': req_data.get('originUsername'),
          'provider': req_data.get('provider'),
      }

      try:
          response = requests.post(
              'https://api.stackone.com/connect_sessions',
              headers=headers,
              json=payload
          )
          token = response.json().get('token')
          return jsonify({'token': token})
      except Exception as e:
          return ('error when trying to fetch session', 500)
  ```

  ```csharp C# theme={null}
  using Newtonsoft.Json;
  using Microsoft.AspNetCore.Mvc;
  using System;
  using System.Net.Http;
  using System.Text;
  using System.Threading.Tasks;

  [ApiController]
  [Route("[controller]")]
  public class StackOneConnectSessionsController : ControllerBase
  {
      [HttpPost]
      public async Task<IActionResult> Post([FromBody] dynamic reqBody)
      {
          string STACKONE_API_KEY = "YOUR_STACKONE_API_KEY";
          string authHeader = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{STACKONE_API_KEY}:"));

          HttpClient client = new HttpClient();
          client.DefaultRequestHeaders.Add("Authorization", $"Basic {authHeader}");

          dynamic payload = new
          {
              origin_owner_id = "customer-123",
              origin_owner_name = "Acme Inc",
              origin_username = reqBody.originUsername,
              provider = reqBody.provider,
          };

          try
          {
              var response = await client.PostAsync(
                  "https://api.stackone.com/connect_sessions",
                  new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json")
              );
              dynamic data = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
              return Ok(new { token = data.token });
          }
          catch (Exception)
          {
              return StatusCode(500, "error when trying to fetch session");
          }
      }
  }
  ```
</CodeGroup>

## Account behavior

| `origin_owner_id` + `origin_owner_name` + `provider` seen before? | Result                                          |
| ----------------------------------------------------------------- | ----------------------------------------------- |
| No                                                                | New account created                             |
| Yes                                                               | Existing account opened in edit mode            |
| — with `account_id`                                               | That specific account opened in edit mode       |
| — with `multiple: true` (no `account_id`)                         | New account created regardless of existing ones |

## Multiple accounts for the same provider

By default, creating a connect session with an `origin_owner_id` and `origin_owner_name` combination that already exists for a given provider will open that existing account in edit mode rather than create a new one.

If you need multiple linked accounts for the same provider under the same `origin_owner_id` — for example if a single customer connects several separate instances of the same tool — pass `multiple: true`. This creates a new account each time regardless of any existing ones with matching details.

<Note>
  `multiple` has no effect when `account_id` is set. When `account_id` is present the session always opens that specific account in edit mode.
</Note>

## Targeting a specific auth config

Passing `provider` alone creates a session using the project's default auth configuration for that provider. This is the right choice for most cases — if you only have one auth config per provider, or want users going through the standard flow, you don't need anything else.

Each auth config has a version pin controlling which connector version its linked accounts use. When you issue a connect session, the linked account that results from it is tied to the auth config the session was created against — and inherits that config's version pin. This is how connector version migration works in practice: you create a new auth config pinned to the new version, then issue connect sessions with that `integration_id` so users authenticate against the new config. When they reconnect, their account moves to the new version.

To route a session to a specific auth config — for example when you have multiple configs for the same provider, or you're migrating end users to a new connector version — pass its `integration_id`.

Get the `integration_id` by calling `GET /auth_configs` and using the `id` field from the auth config you want to target:

```bash theme={null}
curl https://api.stackone.com/auth_configs \
  -H "Authorization: Basic <base64(api_key:)>"
```

Then pass it in the session request:

```bash theme={null}
curl -X POST https://api.stackone.com/connect_sessions \
  -H "Authorization: Basic <base64(api_key:)>" \
  -H "Content-Type: application/json" \
  -d '{
    "origin_owner_id": "customer-123",
    "origin_owner_name": "Acme Inc",
    "provider": "bamboohr",
    "integration_id": "auth_cfg_01J..."
  }'
```

This is most commonly used when migrating end users to a new connector major version that requires reauthentication. See [Connector Version Management](/guides/connector-versioning) for the full migration flow.

### Customizing the Hub Behavior

<Snippet file="guides/hub-customization.mdx" />
