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

# Refiner API reference

> API reference for the Refiner plugin in Corsair: every `refiner.api.*` operation with its input and output types, taken from the plugin's Zod schemas.

> [!NOTE]
>
> **New to Corsair?** See [API access](https://docs.corsair.dev/concepts/api.md), [authentication](https://docs.corsair.dev/concepts/auth.md), and [error handling](https://docs.corsair.dev/concepts/error-handling).

## Account

### get

`account.get`

Read the subscription plan, monthly usage against each limit, and the environments in the account

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.account.get({});
```

**Input:** *empty object*

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `subscription` | `object \| null` | No | — |
| `environments` | `object[] \| null` | No | — |

> [accordion] subscription full type
>
> ```ts theme={null}
> {
>   plan?: string | null,
>   mtu_count?: number | null,
>   mtu_limit?: number | null,
>   mte_count?: number | null,
>   mpv_count?: number | null,
>   mpv_limit?: number | null,
>   msr_count?: number | null,
>   msr_limit?: number | null
> } | null
> ```

> [accordion] environments full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   name?: string | null,
>   mtu?: number | null,
>   mte?: number | null,
>   mpv?: number | null,
>   msr?: number | null
> }[] | null
> ```

***

## Contacts

### delete

`contacts.delete`

Delete a contact and all their survey responses; overwrite traits with users.identify instead when the responses must survive

**Risk:** `destructive`

```ts theme={null}
await corsair.refiner.api.contacts.delete({ id: 'user-1' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `id` | `string` | No | Your user ID, or an email address. |
| `email` | `string` | No | — |
| `uuid` | `string` | No | A Refiner contact UUID. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |

***

### get

`contacts.get`

Read one contact and everything on record for them by user ID, email or Refiner UUID

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.contacts.get({ id: 'user-1' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `id` | `string` | No | Your user ID, or an email address. |
| `email` | `string` | No | — |
| `uuid` | `string` | No | A Refiner contact UUID. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `uuid` | `string \| null` | No | — |
| `remote_id` | `string \| null` | No | Your own user ID. |
| `email` | `string \| null` | No | — |
| `display_name` | `string \| null` | No | — |
| `first_seen_at` | `string \| null` | No | — |
| `last_seen_at` | `string \| null` | No | — |
| `attributes` | `Record<string, string \| number \| boolean \| null> \| null` | No | Every trait on record: the ones you sent, merged with this contact's survey answers. |
| `segments` | `object[] \| null` | No | — |
| `account` | `object \| null` | No | — |

> [accordion] segments full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   name?: string | null,
>   is_manual?: boolean | null
> }[] | null
> ```

> [accordion] account full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   remote_id?: string | null,
>   domain?: string | null,
>   display_name?: string | null,
>   first_seen_at?: string | null,
>   last_seen_at?: string | null,
>   attributes?: Record<string, string | number | boolean | null> | never[] | null
> } | null
> ```

***

### list

`contacts.list`

List contacts with their traits, segments and account, filtered by survey or segment

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.contacts.list({ order_by: 'last_seen_at', page_length: 100 });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `page` | `number` | No | 1-based. Defaults to 1. |
| `page_cursor` | `string` | No | The next\_page\_cursor from the previous page. Faster than numeric paging on a large set. |
| `page_length` | `number` | No | Defaults to 100, maximum 1,000. |
| `order_by` | `display_name \| email \| first_seen_at \| last_seen_at \| last_form_submission_at` | No | Defaults to first\_seen\_at. |
| `form_uuid` | `string` | No | Only contacts linked to this survey. |
| `segment_uuid` | `string` | No | — |
| `search` | `string` | No | Match email, ID or name. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `items` | `object[] \| null` | No | — |
| `pagination` | `object \| null` | No | — |

> [accordion] items full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   remote_id?: string | null,
>   email?: string | null,
>   display_name?: string | null,
>   first_seen_at?: string | null,
>   last_seen_at?: string | null,
>   attributes?: Record<string, string | number | boolean | null> | null,
>   segments?: {
>     uuid?: string | null,
>     name?: string | null,
>     is_manual?: boolean | null
>   }[] | null,
>   account?: {
>     uuid?: string | null,
>     remote_id?: string | null,
>     domain?: string | null,
>     display_name?: string | null,
>     first_seen_at?: string | null,
>     last_seen_at?: string | null,
>     attributes?: Record<string, string | number | boolean | null> | never[] | null
>   } | null
> }[] | null
> ```

> [accordion] pagination full type
>
> ```ts theme={null}
> {
>   items_count?: number | null,
>   current_page?: number | null,
>   last_page?: number | null,
>   page_length?: number | null,
>   next_page_cursor?: string | null
> } | null
> ```

***

## Forms

### archive

`forms.archive`

Archive a survey; Refiner archives rather than deletes, and an archived survey still appears under all\_with\_archived

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.forms.archive({ form_uuid: '4f5637d0-3d0d-11ea-b965-614418dec30c' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `form_uuid` | `string` | Yes | The survey to archive. Refiner archives rather than deletes. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |

***

### duplicate

`forms.duplicate`

Duplicate a survey into a new draft under a new name

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.forms.duplicate({ form_uuid: '4f5637d0-3d0d-11ea-b965-614418dec30c', name: 'Copy of my survey' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `form_uuid` | `string` | Yes | The survey to duplicate. |
| `name` | `string` | Yes | The new survey's name. The copy is created as a draft. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |
| `source_form_uuid` | `string \| null` | No | — |
| `new_form_uuid` | `string \| null` | No | — |

***

### history

`forms.history`

List the previous versions of a survey, each with its full configuration and question set

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.forms.history({ form_uuid: '4f5637d0-3d0d-11ea-b965-614418dec30c' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `form_uuid` | `string` | Yes | The survey whose history to read. |
| `page` | `number` | No | — |
| `page_length` | `number` | No | — |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `items` | `object[] \| null` | No | — |
| `pagination` | `object \| null` | No | — |

> [accordion] items full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   action?: string | null,
>   snapshot?: Record<string, JsonValue> | null,
>   created_at?: string | null
> }[] | null
> ```

> [accordion] pagination full type
>
> ```ts theme={null}
> {
>   items_count?: number | null,
>   current_page?: number | null,
>   last_page?: number | null,
>   page_length?: number | null,
>   next_page_cursor?: string | null
> } | null
> ```

***

### list

`forms.list`

List surveys by state, optionally with their configuration and response and view counts

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.forms.list({ list: 'published', include_info: true });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `list` | `all \| published \| drafts \| archived \| all_with_archived` | No | Which surveys to include. Defaults to all. |
| `page` | `number` | No | — |
| `page_length` | `number` | No | — |
| `include_config` | `boolean` | No | The survey configuration and each element's. Its format may change as features are added. |
| `include_info` | `boolean` | No | Creation and publishing dates, response and view counts, and the folder. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `items` | `object[] \| null` | No | — |
| `pagination` | `object \| null` | No | — |

> [accordion] items full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   name?: string | null,
>   channels?: string[] | null,
>   published_at?: string | null,
>   archived_at?: string | null,
>   created_at?: string | null,
>   updated_at?: string | null,
>   responses_count?: number | null,
>   views_count?: number | null,
>   first_form_view_at?: string | null,
>   last_form_view_at?: string | null,
>   folder?: string | Record<string, never> | null,
>   page_url?: string | null,
>   config?: Record<string, JsonValue> | null
> }[] | null
> ```

> [accordion] pagination full type
>
> ```ts theme={null}
> {
>   items_count?: number | null,
>   current_page?: number | null,
>   last_page?: number | null,
>   page_length?: number | null,
>   next_page_cursor?: string | null
> } | null
> ```

***

### publish

`forms.publish`

Publish a survey, or unpublish it with published: false so it stops collecting

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.forms.publish({ form_uuid: '4f5637d0-3d0d-11ea-b965-614418dec30c' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `form_uuid` | `string` | Yes | The survey to publish or unpublish. |
| `published` | `boolean` | No | False unpublishes the survey. Defaults to true. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |

***

## Reporting

### get

`reporting.get`

Compute an NPS, CSAT, ratings, distribution or count report over a date range and any filters

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.reporting.get({ type: 'nps', form_uuids: ['3894dc20-8fe9-11ea-892e-d13af52e06ae'], date_range_start: '2024-12-12', date_range_end: '2025-04-18' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `type` | `nps \| csat \| ratings \| distribution \| count` | Yes | Which report to compute. |
| `question_identifiers` | `string[]` | No | Only count data points for these questions. Omitted means every question matching the type. |
| `tag_uuids` | `string[]` | No | — |
| `form_uuids` | `string[]` | No | — |
| `segment_uuids` | `string[]` | No | — |
| `date_range_start` | `string` | No | ISO 8601. Defaults to seven days ago. |
| `date_range_end` | `string` | No | ISO 8601. Defaults to the end of today. |
| `response_data` | `Record<string, string \| number \| boolean>` | No | Survey answers to match, keyed by question identifier. Every key must match. |
| `contact_data` | `Record<string, string \| number \| boolean>` | No | Contact traits to match, keyed by trait slug. |
| `account_data` | `Record<string, string \| number \| boolean>` | No | Account traits to match, keyed by trait slug. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `data` | `Record<string, number> \| null` | No | A bucket label to count, such as \{"detractors": 5, "promoters": 40}. |
| `count` | `number \| null` | No | — |
| `nps` | `number \| null` | No | — |
| `csat` | `number \| null` | No | — |
| `sum` | `number \| null` | No | — |
| `average` | `number \| null` | No | — |
| `responses` | `number \| null` | No | — |
| `datapoints` | `number \| null` | No | — |
| `views` | `number \| null` | No | — |
| `date_range_start` | `string \| null` | No | — |
| `date_range_end` | `string \| null` | No | — |

***

## Responses

### list

`responses.list`

List survey responses and views, filtered by survey, segment, tag, date, answers or contact traits

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.responses.list({ form_uuid: '3894dc20-8fe9-11ea-892e-d13af52e06ae', page_length: 50, include: 'partials' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `page` | `number` | No | 1-based. Defaults to 1. |
| `page_cursor` | `string` | No | The next\_page\_cursor from the previous page. Faster than numeric paging on a large set. |
| `page_length` | `number` | No | Defaults to 100, maximum 1,000. |
| `form_uuid` | `string` | No | Only this survey. |
| `form_uuids` | `string[]` | No | Only these surveys. |
| `segment_uuid` | `string` | No | — |
| `segment_uuids` | `string[]` | No | — |
| `tag_uuid` | `string` | No | — |
| `tag_uuids` | `string[]` | No | — |
| `date_range_start` | `string` | No | ISO 8601, such as 2024-01-01 or 2024-01-01 00:00:00. |
| `date_range_end` | `string` | No | ISO 8601. |
| `include` | `completed \| partials \| all` | No | completed is the default; partials adds incomplete ones; all adds dismissed survey views. |
| `search` | `string` | No | Match the contact ID, Refiner UUID, email or name. |
| `with_attributes` | `boolean` | No | Include every attribute on record for each contact. |
| `response_data` | `Record<string, string \| number \| boolean>` | No | Survey answers to match, keyed by question identifier. Every key must match. |
| `contact_data` | `Record<string, string \| number \| boolean>` | No | Contact traits to match, keyed by trait slug. |
| `account_data` | `Record<string, string \| number \| boolean>` | No | Account traits to match, keyed by trait slug. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `items` | `object[] \| null` | No | — |
| `pagination` | `object \| null` | No | — |

> [accordion] items full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   first_shown_at?: string | null,
>   last_shown_at?: string | null,
>   show_counter?: number | null,
>   first_data_reception_at?: string | null,
>   last_data_reception_at?: string | null,
>   completed_at?: string | null,
>   received_at?: string | null,
>   dismissed_at?: string | null,
>   form?: {
>     uuid?: string | null,
>     name?: string | null
>   } | null,
>   data?: Record<string, string | number | boolean | null> | null,
>   contact?: {
>     uuid?: string | null,
>     remote_id?: string | null,
>     email?: string | null,
>     display_name?: string | null,
>     attributes?: Record<string, string | number | boolean | null> | never[] | null,
>     account?: {
>       uuid?: string | null,
>       remote_id?: string | null,
>       domain?: string | null,
>       display_name?: string | null,
>       first_seen_at?: string | null,
>       last_seen_at?: string | null,
>       attributes?: Record<string, string | number | boolean | null> | never[] | null
>     } | null
>   } | null
> }[] | null
> ```

> [accordion] pagination full type
>
> ```ts theme={null}
> {
>   items_count?: number | null,
>   current_page?: number | null,
>   last_page?: number | null,
>   page_length?: number | null,
>   next_page_cursor?: string | null
> } | null
> ```

***

### store

`responses.store`

Store a survey response for a user on an existing survey, to import history or feed a custom survey UI. Answers go in as top-level keys named by question identifier, such as \{ id: 'user-1', form\_uuid, nps: 9, feedback: 'Fast setup' }

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.responses.store({ id: 'user-1', form_uuid: '3894dc20-8fe9-11ea-892e-d13af52e06ae', nps_question: 9, date: '2024-01-15T10:30:00Z' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `id` | `string` | No | Your user ID. |
| `email` | `string` | No | Instead of an id. |
| `uuid` | `string` | No | A Refiner contact UUID. |
| `form_uuid` | `string` | Yes | The survey the response belongs to. It may be empty and unpublished, as long as it exists. |
| `date` | `string` | No | ISO 8601, when the response was recorded. Defaults to now, so set it on a historical import. |
| `prevent_duplicates` | `boolean` | No | Refiner detects duplicates by default; false turns that off. |
| `tags` | `string[]` | No | Up to 20 tags for the response. |
| `account` | `Record<string, string \| number \| boolean>` | No | A nested account object, with at least an id, to group the contact under one account. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |
| `uuid` | `string \| null` | No | The new response UUID. |

***

### tag

`responses.tag`

Add tags to an existing survey response, up to 20

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.responses.tag({ uuid: 'cb47c260-ed64-11ea-8187-a7fc8351fba4', tags: ['onboarding', 'promoter'] });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `uuid` | `string` | Yes | The survey response to tag. |
| `tags` | `string[]` | Yes | Up to 20 tags. Tags already on the response are kept. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |

***

## Segments

### list

`segments.list`

List segments, reporting whether each is hand-curated or computed

**Risk:** `read`

```ts theme={null}
await corsair.refiner.api.segments.list({});
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `page` | `number` | No | — |
| `page_length` | `number` | No | — |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `items` | `object[] \| null` | No | — |
| `pagination` | `object \| null` | No | — |

> [accordion] items full type
>
> ```ts theme={null}
> {
>   uuid?: string | null,
>   name?: string | null,
>   is_manual?: boolean | null
> }[] | null
> ```

> [accordion] pagination full type
>
> ```ts theme={null}
> {
>   items_count?: number | null,
>   current_page?: number | null,
>   last_page?: number | null,
>   page_length?: number | null,
>   next_page_cursor?: string | null
> } | null
> ```

***

### sync

`segments.sync`

Add a user to a manual segment, or remove them, creating the contact when no match exists

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.segments.sync({ id: 'user-1', segment_uuid: '0ff87720-9ae5-11ea-bce5-65a395204572' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `id` | `string` | No | Your user ID. |
| `email` | `string` | No | Instead of an id. |
| `segment_uuid` | `string` | Yes | The manual segment. A computed segment cannot be edited this way. |
| `remove` | `boolean` | No | True removes the user instead of adding them. Refiner exposes both through one route, so the plugin picks DELETE for removal. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |
| `contact_uuid` | `string \| null` | No | — |
| `segment_uuid` | `string \| null` | No | — |

***

## Users

### identify

`users.identify`

Identify a user by ID or email, creating the contact on first sight. Every other top-level key is saved as a trait, such as \{ id: 'user-1', plan: 'pro', signed\_up\_at: '2024-01-15' }

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.users.identify({ id: 'user-1', email: 'jane@example.com', some_attribute: 'Manager', created_at: '2020-08-20T14:48:00.000Z', account: { id: 'acme-1', name: 'Acme Inc.' } });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `id` | `string` | No | Your user ID. One of id, email is required. |
| `email` | `string` | No | Instead of an id. |
| `account` | `Record<string, string \| number \| boolean>` | No | A nested account object, with at least an id, to group users under one account. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |
| `contact_uuid` | `string \| null` | No | — |

***

### track

`users.track`

Track a named event for a user, creating the contact when no match exists

**Risk:** `write`

```ts theme={null}
await corsair.refiner.api.users.track({ id: 'user-1', event: 'completed_onboarding' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `id` | `string` | No | Your user ID. |
| `email` | `string` | No | Instead of an id. |
| `event` | `string` | Yes | The event name. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `message` | `string \| null` | No | — |

***


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.