# Finch

> Read employment data from any payroll or HR system through one connection - the company, the employee directory, individual and employment records, payroll runs and pay statements, pay groups and the benefits an employer offers.

App · Jobs & Hiring · 18 actions. Web page: https://docs.lodol.com/docs/integrations/finch

## Actions

### Get benefit

Read one company benefit, with its contribution rule - a fixed amount, a percentage, or a tiered schedule.

**Inputs**

- Benefit (`benefit_id`, text, required): The benefit to read. Pick one, or paste a Finch benefit ID.

**Outputs**

- `benefit_id` (text)
- `company_contribution` (object)
- `description` (text)
- `frequency` (text)
- `type` (text)

**Example output**

```json
{
  "benefit_id": "f1b6a0d5-2c48-49ab-9e73-0a5d3c81b6f4",
  "company_contribution": {
    "amount": 400,
    "type": "percent"
  },
  "description": "Company 401(k)",
  "frequency": "every_paycheck",
  "type": "401k"
}
```

### Get benefit enrollments

Read each person's own settings for one benefit - how much they contribute, the company's match, any annual maximum, and whether catch-up contributions apply. Leave the individual IDs empty to read everyone enrolled.

**Inputs**

- Benefit (`benefit_id`, text, required): The benefit to read. Pick one, or paste a Finch benefit ID.
- Individual IDs (`individual_ids`, list): Only read these people's settings. Leave empty for everyone enrolled in the benefit.

**Outputs**

- `benefit_id` (text): The benefit these settings are for
- `count` (number): Records returned
- `enrollments` (list): Each person's settings for this benefit
- `error_count` (number): How many IDs failed
- `errors` (list): IDs Finch could not answer for, with its reason
- `requested_count` (number): IDs asked for

**Example output**

```json
{
  "benefit_id": "f1b6a0d5-2c48-49ab-9e73-0a5d3c81b6f4",
  "count": 1,
  "enrollments": [
    {
      "annual_maximum": 2350000,
      "catch_up": false,
      "company_contribution": {
        "amount": 400,
        "type": "percent"
      },
      "employee_deduction": {
        "amount": 500,
        "type": "percent"
      },
      "individual_id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77"
    }
  ],
  "error_count": 0,
  "errors": [],
  "requested_count": 0
}
```

### Get company

Read the employer's own record: legal name, EIN, entity type and subtype, departments, work locations, and the bank accounts payroll is funded from. Takes no input - it describes whichever employer this connection is for.

**Inputs**: None.

**Outputs**

- `accounts` (list)
- `departments` (list)
- `ein` (text)
- `entity` (object)
- `id` (text)
- `legal_name` (text)
- `locations` (list)
- `primary_email` (text)
- `primary_phone_number` (text)

**Example output**

```json
{
  "accounts": [
    {
      "account_name": "Payroll operating",
      "account_number": "****4417",
      "account_type": "checking",
      "institution_name": "Puget Sound Bank",
      "routing_number": "125000024"
    }
  ],
  "departments": [
    {
      "name": "Roastery",
      "parent": null
    },
    {
      "name": "Retail",
      "parent": {
        "name": "Operations"
      }
    }
  ],
  "ein": "84-3927115",
  "entity": {
    "subtype": "s_corporation",
    "type": "corporation"
  },
  "id": "d7c1f0aa-4b52-4c9e-8a31-6e2b5d9c7f10",
  "legal_name": "Sterling Wharf Coffee Roasters, Inc.",
  "locations": [
    {
      "city": "Seattle",
      "country": "US",
      "line1": "1420 Alaskan Way",
      "line2": "Suite 300",
      "postal_code": "98101",
      "state": "WA"
    }
  ],
  "primary_email": "people@sterlingwharf.example",
  "primary_phone_number": "+1-206-555-0142"
}
```

### Get connection details

Read what this connection actually is: which employer and payroll provider it points at, and which products it was authorised for. Start here when another step fails with a permission error - 'products' is the authoritative list of what this token may read.

**Inputs**: None.

**Outputs**

- `authentication_methods` (list)
- `client_id` (text)
- `client_type` (text)
- `company_id` (text)
- `connection_id` (text)
- `connection_type` (text)
- `id` (text)
- `payroll_provider_id` (text)
- `products` (list)
- `provider_id` (text)
- `username` (text)

**Example output**

```json
{
  "client_id": "5c1f0a7d-2b93-4e18-8a6f-71c0d4b39e52",
  "client_type": "sandbox",
  "company_id": "d7c1f0aa-4b52-4c9e-8a31-6e2b5d9c7f10",
  "connection_id": "ec42a7b9-3d15-4c80-9f6a-2b18d0c7e594",
  "connection_type": "provider",
  "id": "b3d81f27-59c4-4a0e-91d7-5f2a6c48e310",
  "products": [
    "company",
    "directory",
    "individual",
    "employment",
    "payment",
    "pay_statement",
    "benefits"
  ],
  "provider_id": "gusto"
}
```

### Get data sync job

Read one data-sync job: whether it is pending, running, complete or failed, and when it ran. Use it to wait for a sync to finish before reading payroll data that depends on it.

**Inputs**

- Job ID (`job_id`, text, required): The job to read, from a 'List data sync jobs' step.

**Outputs**

- `completed_at` (text)
- `created_at` (text)
- `job_id` (text)
- `job_url` (text)
- `params` (object)
- `scheduled_at` (text)
- `started_at` (text)
- `status` (text)
- `type` (text)

**Example output**

```json
{
  "completed_at": "2026-08-30T02:18:41Z",
  "created_at": "2026-08-30T02:15:00Z",
  "job_id": "a0f3c7d1-8b24-4e59-91c6-3d70a5e28b14",
  "status": "complete",
  "type": "data_sync_all"
}
```

### Get employments

Read employment records for the individuals named - job title, employment type and status, start and end dates, manager, department, work location, and current and historical pay rates. IDs Finch cannot resolve come back under 'errors' while the rest still return.

**Inputs**

- Individual IDs (`individual_ids`, list, required): Finch individual IDs to look up. Accepts a list, a single ID, or the records from a 'List directory' step - their 'id' is read for you.

**Outputs**

- `count` (number): Records returned
- `employments` (list): The employment records Finch could resolve
- `error_count` (number): How many IDs failed
- `errors` (list): IDs Finch could not answer for, with its reason
- `requested_count` (number): IDs asked for

**Example output**

```json
{
  "count": 1,
  "employments": [
    {
      "class_code": null,
      "department": {
        "name": "Roastery"
      },
      "employment": {
        "subtype": "full_time",
        "type": "employee"
      },
      "employment_status": "active",
      "end_date": null,
      "first_name": "Dana",
      "flsa_status": "non_exempt",
      "id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77",
      "income": {
        "amount": 7200000,
        "currency": "usd",
        "effective_date": "2025-01-01",
        "unit": "yearly"
      },
      "individual_id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77",
      "is_active": true,
      "last_name": "Okafor",
      "location": {
        "city": "Seattle",
        "country": "US",
        "state": "WA"
      },
      "manager": {
        "id": "1a7d9e30-88bb-4c6f-9a2e-5d40b7c1e982"
      },
      "start_date": "2022-03-14",
      "title": "Lead Roaster"
    }
  ],
  "error_count": 0,
  "errors": [],
  "requested_count": 1
}
```

### Get individuals

Read personal profiles for the individuals named - preferred name, date of birth, home address, emails and phone numbers. Finch answers each ID separately, so IDs it cannot resolve come back under 'errors' while the rest still return.

**Inputs**

- Individual IDs (`individual_ids`, list, required): Finch individual IDs to look up. Accepts a list, a single ID, or the records from a 'List directory' step - their 'id' is read for you.
- Also include (`include`, list): Sensitive fields to include. Finch redacts a social security number unless it is asked for by name, and only returns it if this connection is scoped for it. One or more of: `ssn` (Social security number).

**Outputs**

- `count` (number): Records returned
- `error_count` (number): How many IDs failed
- `errors` (list): IDs Finch could not answer for, with its reason
- `individuals` (list): The profiles Finch could resolve
- `requested_count` (number): IDs asked for

**Example output**

```json
{
  "count": 1,
  "error_count": 0,
  "errors": [],
  "individuals": [
    {
      "dob": "1991-04-17",
      "emails": [
        {
          "data": "dana.okafor@sterlingwharf.example",
          "type": "work"
        }
      ],
      "ethnicity": "decline_to_specify",
      "first_name": "Dana",
      "gender": "female",
      "id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77",
      "individual_id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77",
      "last_name": "Okafor",
      "marital_status": "single",
      "phone_numbers": [
        {
          "data": "+1-206-555-0188",
          "type": "personal"
        }
      ],
      "preferred_name": "Dee",
      "residence": {
        "city": "Seattle",
        "country": "US",
        "line1": "88 Beacon Hill Rd",
        "postal_code": "98109",
        "state": "WA"
      }
    }
  ],
  "requested_count": 1
}
```

### Get pay group

Read one pay group, with the IDs of everyone in it and how often it is paid.

**Inputs**

- Pay group (`pay_group_id`, text, required): The pay group to read. Pick one, or paste a Finch pay group ID.

**Outputs**

- `id` (text)
- `individual_ids` (list)
- `name` (text)
- `pay_frequencies` (list)

**Example output**

```json
{
  "id": "7c9a1b44-0e52-4d18-b6f3-92a4d0e18c55",
  "individual_ids": [
    "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77"
  ],
  "name": "Hourly - Bi-weekly",
  "pay_frequencies": [
    "bi_weekly"
  ]
}
```

### Get pay statements

Read the per-employee pay statements behind one or more payroll runs: every earning, tax, employee deduction and employer contribution, with the employer's own name for each line alongside Finch's normalised type. Amounts are in the currency's minor units, so 276900 is $2,769.00.

**Inputs**

- Payment IDs (`payment_ids`, list, required): Finch payment IDs, from a 'List payments' step. Accepts a list, a single ID, or that step's records.
- Page size (`limit`, number): How many records to return, 1-1000. Defaults to 100. From 1 to 1000. Default: `100`.
- Start at (`offset`, number): How many records to skip before this page. Use the 'next_offset' from a previous run to read the following page. From 0 to 1000000. Default: `0`.

**Outputs**

- `count` (number): Records returned
- `error_count` (number): How many IDs failed
- `errors` (list): IDs Finch could not answer for, with its reason
- `pay_statements` (list): One group of pay statements per payroll run
- `pending` (list): IDs whose data Finch is still fetching from the provider; these usually succeed on a later run
- `pending_count` (number): How many IDs are still syncing
- `requested_count` (number): IDs asked for

**Example output**

```json
{
  "count": 1,
  "error_count": 0,
  "errors": [],
  "pay_statements": [
    {
      "paging": {
        "count": 1,
        "offset": 0
      },
      "pay_statements": [
        {
          "earnings": [
            {
              "amount": 276900,
              "currency": "usd",
              "hours": 80,
              "name": "Regular",
              "type": "salary"
            }
          ],
          "employee_deductions": [
            {
              "amount": 13800,
              "currency": "usd",
              "name": "401(k)",
              "pre_tax": true,
              "type": "401k"
            }
          ],
          "employer_contributions": [
            {
              "amount": 13800,
              "currency": "usd",
              "name": "401(k) match",
              "type": "401k"
            }
          ],
          "gross_pay": {
            "amount": 276900,
            "currency": "usd"
          },
          "individual_id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77",
          "net_pay": {
            "amount": 210400,
            "currency": "usd"
          },
          "payment_method": "direct_deposit",
          "taxes": [
            {
              "amount": 41500,
              "currency": "usd",
              "employer": false,
              "name": "Federal Income Tax",
              "type": "federal"
            }
          ],
          "total_hours": 80,
          "type": "regular_payroll"
        }
      ],
      "payment_id": "9b2e4a11-7c33-4a2f-8d5e-16b0c7a94d21"
    }
  ],
  "requested_count": 1
}
```

### List benefits

List every benefit the employer offers, with its normalised type, the employer's own description of it, how often it is deducted, and the company's contribution rule.

**Inputs**: None.

**Outputs**

- `benefits` (list): The benefits this employer offers
- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "benefits": [
    {
      "benefit_id": "f1b6a0d5-2c48-49ab-9e73-0a5d3c81b6f4",
      "company_contribution": {
        "amount": 400,
        "type": "percent"
      },
      "description": "Company 401(k)",
      "frequency": "every_paycheck",
      "type": "401k"
    }
  ],
  "count": 1,
  "has_more": false
}
```

### List data sync jobs

List the data-sync jobs Finch has run for this connection, most recent first, with the status of each. A 'reauth_error' or 'permissions_error' here is why other steps started returning stale or empty data - both mean the employer has to reconnect.

**Inputs**

- Page size (`limit`, number): How many records to return, 1-1000. Defaults to 100. From 1 to 1000. Default: `100`.
- Start at (`offset`, number): How many records to skip before this page. Use the 'next_offset' from a previous run to read the following page. From 0 to 1000000. Default: `0`.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `jobs` (list): Data sync jobs for this connection
- `next_offset` (number): The 'offset' that reads the next page
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "jobs": [
    {
      "completed_at": "2026-08-30T02:18:41Z",
      "created_at": "2026-08-30T02:15:00Z",
      "job_id": "a0f3c7d1-8b24-4e59-91c6-3d70a5e28b14",
      "scheduled_at": "2026-08-30T02:15:00Z",
      "started_at": "2026-08-30T02:15:07Z",
      "status": "complete",
      "type": "data_sync_all"
    }
  ]
}
```

### List directory

List everyone in the employer's directory - name, department, manager and whether they are currently active - a page at a time. This is the index: use the IDs it returns with 'Get individuals' or 'Get employments' to read someone's detail.

**Inputs**

- Page size (`limit`, number): How many records to return, 1-1000. Defaults to 100. From 1 to 1000. Default: `100`.
- Start at (`offset`, number): How many records to skip before this page. Use the 'next_offset' from a previous run to read the following page. From 0 to 1000000. Default: `0`.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `individuals` (list): Everyone on this page of the directory
- `next_offset` (number): The 'offset' that reads the next page
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 2,
  "has_more": false,
  "individuals": [
    {
      "department": {
        "name": "Roastery"
      },
      "first_name": "Dana",
      "id": "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77",
      "is_active": true,
      "last_name": "Okafor",
      "manager": {
        "id": "1a7d9e30-88bb-4c6f-9a2e-5d40b7c1e982"
      },
      "middle_name": null
    },
    {
      "department": {
        "name": "Operations"
      },
      "first_name": "Priya",
      "id": "1a7d9e30-88bb-4c6f-9a2e-5d40b7c1e982",
      "is_active": true,
      "last_name": "Raman",
      "manager": null,
      "middle_name": "R"
    }
  ],
  "total_count": 2
}
```

### List enrolled individuals

List the IDs of everyone enrolled in one benefit. Pair it with 'Get individuals' to put names to them, or with 'Get benefit enrollments' for each person's own contribution settings.

**Inputs**

- Benefit (`benefit_id`, text, required): The benefit to read. Pick one, or paste a Finch benefit ID.

**Outputs**

- `benefit_id` (text)
- `count` (number): How many people are enrolled
- `individual_ids` (list)

**Example output**

```json
{
  "benefit_id": "f1b6a0d5-2c48-49ab-9e73-0a5d3c81b6f4",
  "count": 1,
  "individual_ids": [
    "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77"
  ]
}
```

### List pay groups

List the employer's pay groups and how often each is paid. Filter to the groups one person belongs to, or to particular pay frequencies. Not every payroll provider reports pay groups; an empty list means this one does not.

**Inputs**

- Individual ID (`individual_id`, text): Only return the pay groups this person belongs to. Leave empty for all of them.
- Pay frequencies (`pay_frequencies`, list): Only return groups paid this often. One or more of: `annually`, `semi_annually` (Semi-annually), `quarterly`, `monthly`, `semi_monthly` (Semi-monthly), `bi_weekly` (Bi-weekly), `weekly`, `daily`, `other`.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `pay_groups` (list): The employer's pay groups
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "pay_groups": [
    {
      "id": "7c9a1b44-0e52-4d18-b6f3-92a4d0e18c55",
      "name": "Hourly - Bi-weekly",
      "pay_frequencies": [
        "bi_weekly"
      ]
    }
  ]
}
```

### List pay statement items

List the distinct earnings, taxes, deductions and employer contributions this employer's payroll actually uses - the catalogue of line items, not any one person's amounts. This is what to read before mapping a payroll into another system.

**Inputs**

- Categories (`categories`, list): Only return items in these categories. One or more of: `earnings`, `taxes`, `employee_deductions` (Employee deductions), `employer_contributions` (Employer contributions).
- From (`start_date`, date): Only include items seen on pay statements from this date onwards.
- To (`end_date`, date): Only include items seen on pay statements up to this date.
- Name (`name`, text): Only return items the employer calls this, such as 'Regular' or '401(k)'.
- Type (`item_type`, text): Only return items of this normalised Finch type, such as 'salary' or '401k'.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `items` (list): The line items this employer's payroll uses
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 2,
  "has_more": false,
  "items": [
    {
      "attributes": {
        "employer": false,
        "metadata": {},
        "pre_tax": false,
        "type": "salary"
      },
      "category": "earnings",
      "name": "Regular"
    },
    {
      "attributes": {
        "employer": false,
        "metadata": {},
        "pre_tax": true,
        "type": "401k"
      },
      "category": "employee_deductions",
      "name": "401(k)"
    }
  ]
}
```

### List payments

List the employer's payroll runs whose pay date falls in a date range, with gross and net pay, employee and employer taxes, the company debit, and the pay period each covers. Both dates are required - Finch refuses an unbounded query. Use the payment IDs with 'Get pay statements' for per-person detail.

**Inputs**

- From (`start_date`, date, required): Earliest pay date to include, inclusive.
- To (`end_date`, date, required): Latest pay date to include, inclusive.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `payments` (list): Payroll runs in the date range
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "payments": [
    {
      "company_debit": {
        "amount": 4182300,
        "currency": "usd"
      },
      "debit_date": "2026-08-12",
      "employee_taxes": {
        "amount": 616100,
        "currency": "usd"
      },
      "employer_taxes": {
        "amount": 261900,
        "currency": "usd"
      },
      "gross_pay": {
        "amount": 3410000,
        "currency": "usd"
      },
      "id": "9b2e4a11-7c33-4a2f-8d5e-16b0c7a94d21",
      "individual_ids": [
        "5cbf7c8c-3f4c-4b1e-9d6b-2f0a1c9d4e77"
      ],
      "net_pay": {
        "amount": 2588400,
        "currency": "usd"
      },
      "pay_date": "2026-08-14",
      "pay_frequencies": [
        "bi_weekly"
      ],
      "pay_group_ids": [
        "7c9a1b44-0e52-4d18-b6f3-92a4d0e18c55"
      ],
      "pay_period": {
        "end_date": "2026-08-09",
        "start_date": "2026-07-27"
      }
    }
  ]
}
```

### List providers

List every payroll and HR system Finch can connect to, with the products each supports and how it authenticates. This is Finch's own catalogue rather than anything about the current connection, so it answers the same whichever employer is connected - useful for checking coverage before asking one to connect.

**Inputs**: None.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `providers` (list): Systems Finch can connect to
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "providers": [
    {
      "beta": false,
      "display_name": "Gusto",
      "id": "gusto",
      "mfa_required": false,
      "products": [
        "company",
        "directory",
        "individual",
        "employment",
        "payment",
        "pay_statement",
        "benefits"
      ]
    }
  ]
}
```

### List supported benefits

List which benefit types this employer's payroll provider supports through Finch, and what may be set on each - the frequencies allowed, the deduction and contribution styles, and whether annual maximums and catch-up contributions apply. Support varies by provider, and this is the only endpoint that says so.

**Inputs**: None.

**Outputs**

- `count` (number): Records on this page
- `has_more` (true/false): Whether a page follows
- `supported_benefits` (list): Benefit types this provider supports
- `total_count` (number): Records matching in total, when Finch reports one

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "supported_benefits": [
    {
      "annual_maximum": true,
      "catch_up": true,
      "company_contribution": [
        "fixed",
        "percent"
      ],
      "description": "401(k)",
      "employee_deduction": [
        "fixed",
        "percent"
      ],
      "frequencies": [
        "every_paycheck"
      ],
      "type": "401k"
    }
  ]
}
```
