# Gusto

Gusto is a cloud-based payroll, benefits, and HR platform for small and medium businesses. The Sling Gusto connector extracts data from the Gusto REST API, supporting company details, employees, jobs, compensations, departments, payroll data, benefits, time-off activities, and contractor payments.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials and inputs are accepted:

**Secrets:**

* `client_id` **(required)** -> Your Gusto OAuth2 application Client ID
* `client_secret` **(required)** -> Your Gusto OAuth2 application Client Secret

**Inputs:**

* `company_id` **(required)** -> The UUID of your Gusto company. Find it via `GET /v1/token_info`
* `anchor_date` (optional) -> The starting date for historical data extraction (default: 1 year ago). Format: `YYYY-MM-DD`

### Authentication

Gusto uses **OAuth2 Authorization Code** flow. Sling handles the entire flow automatically — on first run, it opens your browser for authorization and stores tokens for future use.

1. Go to the [Gusto Developer Portal](https://dev.gusto.com/) and create an account
2. Create a new **Organization** and then a new **Application**
3. Note your **Client ID** and **Client Secret**
4. Set the **Redirect URI** to `http://localhost:4589/callback`
5. Configure the connection using the Client ID and Client Secret (see examples below)

**On first run**, Sling will:

* Open your browser to the Gusto authorization page
* You authorize the application and are redirected back to `localhost:4589`
* Sling exchanges the code for access and refresh tokens, stored locally

**On subsequent runs**, Sling automatically refreshes the access token using the stored refresh token — no browser interaction needed.

{% hint style="info" %}
**Sandbox vs Production:** By default, the connector uses the Gusto demo/sandbox environment (`api.gusto-demo.com`). For production, override `base_url`, `token_url`, and `authorize_url` in secrets to point to `api.gusto.com`.
{% endhint %}

### Finding Your Company ID

After your first successful authorization, find your company UUID:

```bash
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -H "X-Gusto-API-Version: 2025-06-15" \
     https://api.gusto.com/v1/token_info
```

The response includes a `resource.uuid` field — that is your `company_id`.

### Using `sling conns`

{% code overflow="wrap" %}

```bash
sling conns set GUSTO type=api spec=gusto secrets='{ client_id: your_client_id, client_secret: your_client_secret }' inputs='{ company_id: your_company_uuid }'
```

{% endcode %}

### Environment Variable

See [here](https://docs.slingdata.io/sling-cli/environment#dot-env-file-.env.sling) to learn more about the `.env.sling` file.

{% code overflow="wrap" %}

```bash
export GUSTO='{ type: api, spec: gusto, secrets: { client_id: "your_client_id", client_secret: "your_client_secret" }, inputs: { company_id: "your_company_uuid" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  GUSTO:
    type: api
    spec: gusto
    secrets:
      client_id: "your_client_id"
      client_secret: "your_client_secret"
    inputs:
      company_id: "your_company_uuid"
```

**With anchor date for historical data:**

```yaml
connections:
  GUSTO:
    type: api
    spec: gusto
    secrets:
      client_id: "your_client_id"
      client_secret: "your_client_secret"
    inputs:
      company_id: "your_company_uuid"
      anchor_date: "2023-01-01"
```

## Replication

Here's an example replication configuration to sync Gusto data to a PostgreSQL database:

```yaml
source: GUSTO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: gusto.{stream_name}

streams:
  # Company and org structure
  companies:
  locations:
  departments:
  employees:

  # Jobs and compensation
  jobs:
  compensations:

  # Payroll data (incremental)
  pay_schedules:
  pay_periods:
    mode: incremental
  payrolls:
    mode: incremental

  # Benefits
  company_benefits:
  employee_benefits:

  # Time off
  time_off_activities_vacation:
  time_off_activities_sick:

  # Contractor payments (incremental)
  contractor_payments:
    mode: incremental
```

## Endpoints

### Company & Organization

| Endpoint      | Description                                 | Incremental |
| ------------- | ------------------------------------------- | ----------- |
| `companies`   | Company details, settings, and entity info  | No          |
| `locations`   | Company office locations and addresses      | No          |
| `departments` | Company departments with assigned employees | No          |

### Employees & Jobs

| Endpoint        | Description                                    | Incremental |
| --------------- | ---------------------------------------------- | ----------- |
| `employees`     | All employees (active, onboarding, terminated) | No          |
| `jobs`          | Employee job records (title, hire date)        | No          |
| `compensations` | Compensation records (pay rate, FLSA status)   | No          |

### Payroll

| Endpoint        | Description                                           | Incremental |
| --------------- | ----------------------------------------------------- | ----------- |
| `pay_schedules` | Pay schedule configurations (frequency, anchor dates) | No          |
| `pay_periods`   | Pay periods with payroll association                  | Yes         |
| `payrolls`      | Processed payrolls with compensation totals           | Yes         |

### Benefits & Time Off

| Endpoint                       | Description                                     | Incremental |
| ------------------------------ | ----------------------------------------------- | ----------- |
| `company_benefits`             | Benefits configured for the company             | No          |
| `employee_benefits`            | Individual employee benefit enrollments         | No          |
| `time_off_activities_vacation` | Vacation time-off balances and activity history | No          |
| `time_off_activities_sick`     | Sick time-off balances and activity history     | No          |

### Contractors

| Endpoint              | Description                | Incremental |
| --------------------- | -------------------------- | ----------- |
| `contractor_payments` | Contractor payment records | Yes         |

To discover available endpoints:

```bash
sling conns discover GUSTO
```

## Incremental Sync

The Gusto connector uses date-range-based incremental sync for supported endpoints:

* **First run:** Fetches records from `anchor_date` (default: 1 year ago) to present
* **Subsequent runs:** Only fetches records after the last sync checkpoint

Incremental sync is supported for:

* `pay_periods` — syncs by end date
* `payrolls` — syncs by check date
* `contractor_payments` — syncs by check date

## Parent-Child Endpoints

Several endpoints use a queue-based pattern where parent records feed child endpoint iteration:

1. **`employees`** populates `employee_ids` queue, used by:
   * `jobs` — fetches jobs per employee
   * `employee_benefits` — fetches benefits per employee
   * `time_off_activities_vacation` — fetches vacation activity per employee
   * `time_off_activities_sick` — fetches sick activity per employee
2. **`jobs`** populates `job_ids` queue, used by:
   * `compensations` — fetches compensations per job

Ensure parent endpoints run before their children in your replication configuration.

## API Versioning

The connector uses Gusto API version `2025-06-15`. Gusto uses date-based API versioning via the `X-Gusto-API-Version` header.

## Rate Limiting

The connector automatically handles Gusto's rate limits:

* Uses conservative rate limiting (3 requests/second)
* Retries with exponential backoff on 429 (rate limit) responses
* Maximum 5 retry attempts

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).
