---
updatedAt: 2026-08-03T15:56:04.000Z
---

Fetch the complete documentation index at: https://apidocs.hibob.com/llms.txt. Use this file to discover all available pages before exploring further.

# Managing customer installations

Multi-tenant install scenarios for Marketplace partners — linking Bob companies to your customers, handling callbacks, and detecting uninstalls

<Callout icon="🚧" theme="warn">
  **Partner OAuth integrations only**

  This guide is for **approved HiBob Marketplace partners** with Developer Portal access. Bob customers integrating with their own account should use [Service Users](/docs/api-service-users) instead of OAuth.
</Callout>

The [OAuth 2.0](/reference/oauth-20) reference covers HiBob's authorization protocol (consent, callback, token exchange, refresh). **This guide explains what you must build on your side** so your app can serve many Bob customers safely.

# Overview

After a customer installs your app, you need to know which Bob company the installation belongs to so you can store the connection, route webhooks, and avoid mixing data between companies. The primary tenant identifier is `companyId`, which stays stable across re-installs.

This article covers the main scenarios your app must support when customers install, reconnect, or uninstall your app. For token expiry, refresh rotation, and long-running jobs, see the [OAuth FAQ](/reference/oauth-20#faq).

# Installation entry points

When you add an app in the Developer Portal, you choose the **installation mode**: **Install from Bob Marketplace** or **Install from your landing page**. See [Installation modes](/reference/oauth-20#installation-modes) in the OAuth guide.

**Both modes start on your Bob Marketplace listing.** The customer always clicks **Install** there first. The mode only changes what happens **immediately after** that click — either consent starts in Bob, or Bob sends them to your landing page for onboarding before OAuth.

No matter which mode you use, the customer eventually sees Bob's **consent screen**. What happens **after** they click **Allow** depends on the installation mode and on whether the user is already known to your app.

Your callback URL (`redirect_uri`) must handle the relevant outcomes, including cases where the user is not logged in or does not yet have an account in your app.

# Installation flows

```mermaid
flowchart TB
    subgraph flow1 [Install from Bob Marketplace]
        A1[Customer clicks Install in Bob] --> A2[Consent in Bob]
        A2 --> A3[Redirect to your callback with code]
        A3 --> A4[Exchange code for tokens]
        A4 --> A5[Read companyId from access token]
        A5 --> A6[Link to customer account]
    end

    subgraph flow2 [Install from your landing page]
        B0[Customer clicks Install in Bob] --> B1[Bob sends user to your landing page]
        B1 --> B2[Onboarding + create setup session with state]
        B2 --> B3[You redirect to App Installation URL]
        B3 --> B4[Consent in Bob; Redirect to your callback with code and state]
        B4 --> B5[Validate state; read companyId from access token; exchange code]
        B5 --> B6[Link to customer account]
    end

    A6 --> C[Configure]
    B6 --> C
    C --> D[Active installation]
```

# Scenarios your app must support

| Scenario                                                 | What can happen                                                                           | Your app must support                                                                |
| :------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- |
| Install from Bob Marketplace                             | The customer may approve access before they are known to your app.                        | Handle a callback before login, signup, or customer-account linking.                 |
| Install from your landing page                           | After **Install** in Bob, the customer lands on your onboarding or website first.         | Start OAuth from your site with `state`, then match the callback to that setup flow. |
| Customer is not logged in (typical for Marketplace mode) | Authorization succeeds, but your app does not yet know which customer account to connect. | Continue setup after sign-in or sign-up.                                             |
| Bob company was previously connected                     | The same Bob company installs again after uninstalling or reconnecting.                   | Recognize the same `companyId` and update the existing connection.                   |
| Customer uninstalls in Bob                               | HiBob revokes access and does not send an uninstall webhook.                              | Treat refresh `401` as a disconnected or revoked installation.                       |
| Customer changes scopes or audience                      | Scopes and audience are selected during authorization.                                    | Require uninstall and reinstall to change them.                                      |

Token expiry and refresh-token rotation are part of normal operation for every installation — see [Token management best practices](/reference/oauth-20#token-management-best-practices) and the [OAuth FAQ](/reference/oauth-20#faq).

# Identifying the Bob company

Each installation belongs to a Bob company. Use `companyId` as the tenant identifier for the Bob company that installed your app. It is different from `app_id`, which identifies your application and is used only when starting the OAuth installation flow.

HiBob includes `companyId` as a claim inside the `access_token` and in webhook payloads. Use it to keep each company's authorization, webhooks, and synced data separate.

Do **not** use the installer's email alone as the tenant key — the admin who installs may not be the person who uses your product later.

See also [Getting started with partner webhooks](/docs/getting-started-with-partner-webhooks).

# Linking the installation to your customer

A successful Bob authorization does not always mean the installation can immediately be linked to a customer account in your system.

* **Install from Bob Marketplace:** The customer may reach your callback before they have signed in or signed up. Exchange the code, store tokens against `companyId`, then complete association after login or signup. In this mode Bob starts OAuth for you — there is no `state` on the callback.
* **Install from your landing page:** Create a setup session tied to your customer **before** redirecting to Bob, pass its ID as `state`, and on callback validate `state` and attach the tokens. `state` is only available in this mode, because that is when you initiate the redirect to Bob.

# What to persist per installation

At minimum, store for each Bob company (per environment):

* `companyId` — primary tenant key
* **Access and refresh tokens**, encrypted at rest, plus access-token expiry
* **Your customer/account ID**, once known
* **Connection state** — for example pending association, active, or disconnected

One record per Bob company per app per environment — a re-install should update the existing record rather than create a duplicate.

# Uninstall and reinstall

Uninstall always happens in Bob, regardless of installation mode. HiBob does not send a separate uninstall webhook or notification.

When a customer uninstalls your app, HiBob revokes that company's OAuth access. If token refresh returns `401`, treat the installation as disconnected or revoked. The customer must reinstall and approve access again before your app can reconnect.

Customers must also uninstall and reinstall if they want to change scopes or audience selection, because those are locked at authorization time. See [Known limitations](/reference/oauth-20#known-limitations).

# FAQs

For token expiry during long jobs, in-flight refresh behavior, and refresh-token rotation, see the [OAuth FAQ](/reference/oauth-20#faq).

**Does the&#x20;**`state`**&#x20;parameter work when using Install from Bob Marketplace?**<br />No. In that mode Bob starts the OAuth flow directly — you never send the initial authorization request, so there is nothing to attach `state` to and none is returned on your callback. Use `state` only for **Install from your landing page**. For Marketplace mode, bind the install to your customer after login or signup on your side.

**The user reached my callback but is not logged in. What should I do?**<br />Exchange the authorization code immediately (it expires in 5 minutes), persist the tokens against `companyId`, then prompt the user to sign in or sign up and attach the installation to their account afterward.

**Will I receive a webhook when a customer uninstalls my app?**<br />No. Detect uninstalls indirectly, typically when token refresh fails with `401`. See [Uninstall and reinstall](#uninstall-and-reinstall).

<br />