> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to Refiner

The Refiner connector lets your AI agent act in each user's Refiner account. Each user connects their own Refiner access token once, and Scalekit sends it with every call, so your agent never handles credentials. It comes with 19 tools.

**Authentication:** Bearer Token
**Categories:** Customer Support, Analytics
**Tools:** 19: 9 read, 8 write, 2 destructive
**Users sign in with:** Access token
**Built by:** Scalekit connector
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=REFINER)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the Refiner connection

   In **AgentKit > Connections**, create a Refiner connection. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

4. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'refiner'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize Refiner:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'refiner_get_account_info',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "refiner"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize Refiner:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="refiner_get_account_info",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user opens the link once and enters their Refiner credentials there. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'refiner_get_account_info',
  toolInput: {},
  connector: 'refiner',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="refiner_get_account_info",
    tool_input={},
    connection_name="refiner",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `refiner_get_account_info`

Get Account Info · Read-only

Get the Refiner account's subscription plan, usage counters and environments.
Returns plan, monthly tracked users, events, page views and survey responses with their limits, plus each environment's uuid, name and usage.
Use for usage and limit checks. Use refiner_get_environment to identify the environment of the API key.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `refiner_get_contact`

Get Contact · Read-only

Get everything Refiner stores about one contact.
Returns uuid, remote_id, email, display_name, first and last seen, attributes, segments and account.
Use when you know the contact's ID, email or Refiner UUID. Use refiner_list_contacts to search.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123
- `uuid` (`string`, optional): Refiner-generated contact UUID returned by identify user. Example: 15cce3d0-ed5d-11ea-aaef-e58a2a43e996

Example input: `{}`

### `refiner_get_environment`

Get Environment · Read-only

Verify the API key and return the Refiner environment it belongs to.
Returns project_uuid, project_name and an authentication message.
Use to confirm the connection works. Use refiner_get_account_info for plan and usage.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `refiner_get_form_history`

Get Form History · Read-only

List previous versions of a survey.
Returns an items array of versions with uuid, action, created_at and a snapshot of name, config, channels and question elements, plus a pagination object.
Use refiner_list_forms to find the form_uuid.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `form_uuid` (`string`, required): UUID of the survey. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae
- `page` (`integer`, optional): Page number for numeric pagination, starting at 1. Example: 2
- `page_length` (`integer`, optional): Number of items per page, up to 1000 (server default 100). Example: 50

Example input: `{"form_uuid":"<form_uuid>"}`

### `refiner_get_reporting`

Get Reporting · Read-only

Get aggregated survey reporting for a date range.
Returns figures for the chosen type: nps (detractors, passives, promoters, nps score), csat (distribution and csat score), ratings (distribution, sum, average), distribution (value counts) or count (views and responses), plus the date range used.
Use for summary metrics. Use refiner_list_responses for individual answers.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `type` (`string`, required): Report type to compute. Example: nps. One of: `nps`, `csat`, `ratings`, `distribution`, `count`.
- `date_range_end` (`string`, optional): End of the range, ISO 8601 (server default end of today). Example: 2025-04-18
- `date_range_start` (`string`, optional): Start of the range, ISO 8601 (server default 7 days ago). Example: 2024-12-12
- `form_uuids` (`array`, optional): UUIDs of surveys to include; omit for all. Example: ["3894dc20-8fe9-11ea-892e-d13af52e06ae"]
- `question_identifiers` (`array`, optional): Only count data points for these question identifiers (slugs); omit for all matching questions. Example: ["nps"]
- `segment_uuids` (`array`, optional): Only count users in these segment UUIDs. Example: ["0ff87720-9ae5-11ea-bce5-65a395204572"]
- `tag_uuids` (`array`, optional): Only count responses carrying one of these tag UUIDs. Example: ["4f5637d0-3d0d-11ea-b965-614418dec30c"]

Example input: `{"type":"nps"}`

### `refiner_list_contacts`

List Contacts · Read-only

List contacts (users) tracked in Refiner.
Returns an items array of contacts with uuid, remote_id, email, display_name, first and last seen, attributes, segments and account, plus a pagination object.
Use to browse or search contacts. Use refiner_get_contact for one known contact.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `form_uuid` (`string`, optional): Only contacts linked to this survey UUID. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae
- `order_by` (`string`, optional): Field to sort by (server default first_seen_at). Example: last_seen_at. One of: `display_name`, `email`, `first_seen_at`, `last_seen_at`, `last_form_submission_at`. Default: `first_seen_at`.
- `page` (`integer`, optional): Page number for numeric pagination, starting at 1. Example: 2
- `page_cursor` (`string`, optional): Cursor from the previous response's pagination.next_page_cursor. Faster than page numbers for large result sets. Example: eyJpdiI6ImpCMlY3cERCbEo0Qk1Ge
- `page_length` (`integer`, optional): Number of items per page, up to 1000 (server default 100). Example: 50
- `search` (`string`, optional): Only contacts whose email, ID or name matches. Example: jane
- `segment_uuid` (`string`, optional): Only contacts in this segment UUID. Example: 0ff87720-9ae5-11ea-bce5-65a395204572

Example input: `{}`

### `refiner_list_forms`

List Forms · Read-only

List surveys (forms) in the Refiner environment, ordered by name.
Returns an items array of surveys with uuid and name, and a pagination object. With include_info it adds channels, publish and archive dates, response and view counts, folder and page_url.
Use to find a form_uuid for responses, reports and publishing. Use refiner_get_form_history for a survey's past versions.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `include_config` (`integer`, optional): Set to 1 to include each survey's configuration and question elements (server default 0). Can be large. Example: 0. One of: `0`, `1`. Default: `0`.
- `include_info` (`integer`, optional): Set to 1 to add metadata such as creation and publish dates, response and view counts, and folder (server default 0). Example: 1. One of: `0`, `1`. Default: `0`.
- `list` (`string`, optional): Which surveys to return by state (server default all). Example: published. One of: `all`, `published`, `drafts`, `archived`, `all_with_archived`.
- `page` (`integer`, optional): Page number for numeric pagination, starting at 1. Example: 2
- `page_length` (`integer`, optional): Number of items per page, up to 1000 (server default 100). Example: 50

Example input: `{}`

### `refiner_list_responses`

List Responses · Read-only

List survey responses collected in Refiner, newest first.
Returns an items array where each item has uuid, timestamps, the survey (uuid, name), the answers in data and the responding contact with account, plus a pagination object with next_page_cursor.
Use to read raw answers. Use refiner_get_reporting for aggregated NPS, CSAT or rating figures.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `date_range_end` (`string`, optional): Only responses before this time, ISO 8601 (YYYY-MM-DD or YYYY-MM-DD hh:mm:ss). Example: 2024-12-31
- `date_range_start` (`string`, optional): Only responses at or after this time, ISO 8601 (YYYY-MM-DD or YYYY-MM-DD hh:mm:ss). Based on last_data_reception_at, or last_shown_at when include is all. Example: 2024-01-01
- `form_uuid` (`string`, optional): UUID of a survey; only responses to that survey are returned. Find it with list forms. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae
- `include` (`string`, optional): Which responses to return (server default completed): completed, partials (partial plus completed) or all (also dismissed views). Example: partials. One of: `completed`, `partials`, `all`. Default: `completed`.
- `page` (`integer`, optional): Page number for numeric pagination, starting at 1. Example: 2
- `page_cursor` (`string`, optional): Cursor from the previous response's pagination.next_page_cursor. Faster than page numbers for large result sets. Example: eyJpdiI6ImpCMlY3cERCbEo0Qk1Ge
- `page_length` (`integer`, optional): Number of items per page, up to 1000 (server default 100). Example: 50
- `search` (`string`, optional): Return only responses whose contact user ID, Refiner UUID, email or name matches. Example: jane@awesome.com
- `segment_uuid` (`string`, optional): UUID of a segment; only responses from users in that segment are returned. Example: 0ff87720-9ae5-11ea-bce5-65a395204572
- `tag_uuid` (`string`, optional): UUID of a response tag; only responses with that tag are returned. Example: 4f5637d0-3d0d-11ea-b965-614418dec30c
- `with_attributes` (`integer`, optional): Set to 1 to include all stored attributes on each response's contact. Example: 1. One of: `0`, `1`.

Example input: `{}`

### `refiner_list_segments`

List Segments · Read-only

List user segments in Refiner, ordered by name.
Returns an items array of segments with uuid, name and is_manual, plus a pagination object.
Use to find a segment_uuid for filtering or for add and remove segment calls.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `page` (`integer`, optional): Page number for numeric pagination, starting at 1. Example: 2
- `page_length` (`integer`, optional): Number of items per page, up to 1000 (server default 100). Example: 50

Example input: `{}`

### `refiner_add_contact_to_segment`

Add Contact To Segment · Write

Add a user to a manual segment.
Returns message, contact_uuid and segment_uuid. Creates the user if no match exists.
Use refiner_list_segments to find manual segments. Use refiner_remove_contact_from_segment to undo.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `segment_uuid` (`string`, required): UUID of the manual segment. Example: 4f5637d0-3d0d-11ea-b965-614418dec30c
- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123

Example input: `{"segment_uuid":"<segment_uuid>"}`

### `refiner_duplicate_form`

Duplicate Form · Write

Duplicate a survey into a new draft.
Returns message, source_form_uuid and new_form_uuid.
Use refiner_publish_form to publish the copy.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `form_uuid` (`string`, required): UUID of the survey to copy. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae
- `name` (`string`, required): Name of the new survey. Example: NPS survey copy

Example input: `{"form_uuid":"<form_uuid>","name":"<name>"}`

### `refiner_identify_user`

Identify User · Write

Create or update a contact by user ID or email and attach traits.
Returns message and contact_uuid. Returns 409 if another identify for the same user is in progress.
Use to sync backend user data. Use refiner_track_event to record an event instead.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `account` (`object`, optional): Account to group the user under; must contain id and may include name and other account traits. Example: {"id": "acct_1", "name": "Awesome Inc."}
- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123
- `traits` (`object`, optional): Extra user traits as a flat object of attribute slug to value. Strings up to 4 KB, numbers and booleans are typed automatically, and slugs ending in _at are parsed as dates. Example: {"plan": "pro", "created_at": "2020-08-20T14:48:00.000Z"}

Example input: `{}`

### `refiner_publish_form`

Publish Form · Write

Publish or unpublish a survey.
Returns a confirmation message.
Use refiner_list_forms to find the form_uuid.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `form_uuid` (`string`, required): UUID of the survey. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae
- `published` (`integer`, optional): 1 publishes the survey, 0 unpublishes it (server default 1). Example: 1. One of: `0`, `1`. Default: `1`.

Example input: `{"form_uuid":"<form_uuid>"}`

### `refiner_remove_contact_from_segment`

Remove Contact From Segment · Write

Remove a user from a manual segment.
Returns a confirmation message.
Use refiner_add_contact_to_segment to add users.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `segment_uuid` (`string`, required): UUID of the manual segment. Example: 4f5637d0-3d0d-11ea-b965-614418dec30c
- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123

Example input: `{"segment_uuid":"<segment_uuid>"}`

### `refiner_store_response`

Store Response · Write

Store a survey response for a user, for example to import historical data or collect answers through your own UI.
Returns message and the new response uuid.
Use to create a response. Use refiner_tag_response to tag an existing one.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `answers` (`object`, required): Answers keyed by question identifier (slug). Strings up to 255 characters, numbers and booleans. Example: {"nps": 9, "comment": "Great product"}
- `form_uuid` (`string`, required): UUID of the survey to attach the response to; it may be empty and unpublished. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae
- `account` (`object`, optional): Account to group the user under; needs at least id. Example: {"id": "acct_1"}
- `date` (`string`, optional): When the response was recorded, ISO 8601 (server default now). Example: 2024-06-05T13:02:57Z
- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123
- `prevent_duplicates` (`boolean`, optional): Set false to disable duplicate detection (server default true). Example: false
- `tags` (`array`, optional): Tags to attach, up to 20. Example: ["onboarding"]
- `uuid` (`string`, optional): Refiner contact UUID; alternative to id and email. Example: 15cce3d0-ed5d-11ea-aaef-e58a2a43e996

Example input: `{"answers":{"nps":9,"comment":"Great product"},"form_uuid":"<form_uuid>"}`

### `refiner_tag_response`

Tag Response · Write

Add tags to an existing survey response.
Returns message ok.
Use refiner_list_responses to find the response uuid first.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `tags` (`array`, required): Tags to add, up to 20. Example: ["bug", "pricing"]
- `uuid` (`string`, required): UUID of the survey response to tag. Example: cb47c260-ed64-11ea-8187-a7fc8351fba4

Example input: `{"tags":["bug","pricing"],"uuid":"<uuid>"}`

### `refiner_track_event`

Track Event · Write

Record a named event for a user.
Returns message ok. Creates the user if no match exists.
Use for backend events that trigger surveys. Use refiner_identify_user to update traits.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `event` (`string`, required): Name of the event that occurred. Example: Upgraded plan
- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123

Example input: `{"event":"<event>"}`

### `refiner_archive_form`

Archive Form · Destructive

Archive a survey.
Returns message ok.
Use refiner_list_forms with list set to archived to see archived surveys.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `form_uuid` (`string`, required): UUID of the survey to archive. Example: 3894dc20-8fe9-11ea-892e-d13af52e06ae

Example input: `{"form_uuid":"<form_uuid>"}`

### `refiner_delete_contact`

Delete Contact · Destructive

Permanently delete a contact and their survey responses.
Returns message ok.
Use refiner_identify_user to blank sensitive fields instead if responses must be kept.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `email` (`string`, optional): Email address of the contact; use when you have no user ID. Example: jane@awesome.com
- `id` (`string`, optional): Your own user ID for the contact, the same ID used with identify user. Example: user_123
- `uuid` (`string`, optional): Refiner-generated contact UUID. Example: 15cce3d0-ed5d-11ea-aaef-e58a2a43e996

Example input: `{}`

## Related

Other Customer Support connectors ([all 21](/agentkit/connectors/?category=customer-support)):

- [Crisp](/agentkit/connectors/crisp/): Scalekit connector, API key, 50 tools
- [Intercom](/agentkit/connectors/intercom/): Scalekit connector, OAuth, 113 tools
- [Freshdesk](/agentkit/connectors/freshdesk/): Scalekit connector, Username and password, 34 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
