# Requests

## Request Object

Requests are represented as JSON objects with the following properties

<table data-full-width="true"><thead><tr><th width="200">Name</th><th width="96.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>integer</td><td>The ID of the request</td></tr><tr><td><code>title</code></td><td>string</td><td>The title of the request</td></tr><tr><td><code>state</code></td><td>string</td><td><p>The state of the request. Allowed values :</p><p><code>open</code>, <code>in_progress</code>, <code>pending</code>, <code>on_hold</code>, <code>solved</code>, <code>closed</code>, <em><code>null</code></em></p></td></tr><tr><td><code>not_a_request_state</code></td><td>string</td><td><code>temporary</code> - marked as not-a-request <strong>temporarily</strong>, there is a possibility of re-opening the request<br><code>permanent</code> - marked as not-a-request <strong>permanently</strong><br><em><code>null</code></em> - All the requests that were created and were never marked as <strong>not a request</strong></td></tr><tr><td><code>priority</code></td><td>string</td><td><p>The priority of the request.</p><p>Allowed values : <code>low</code>, <code>normal</code>, <code>high</code>, <code>urgent</code></p></td></tr><tr><td><code>author</code></td><td>object</td><td>An object containing details of the request author.</td></tr><tr><td><code>author_email</code></td><td>string</td><td>The email id of the request author.</td></tr><tr><td><code>customer_id</code></td><td>number</td><td>The ID of the customer associated with the request</td></tr><tr><td><code>assignee</code></td><td>object</td><td>The id of the request assignee. Details about the object can be found <a href="#assignee-object">here</a>.</td></tr><tr><td><code>assigned_team</code></td><td>object</td><td>The assigned team for this request, if any. This field will be <code>null</code> if no team is assigned. For more details, see <a href="#assigned-team-object">here</a>.</td></tr><tr><td><code>tickets</code></td><td>array</td><td>An array of ticket objects linked to the request. Details about the object can be found <a href="#ticket-object">here</a>.</td></tr><tr><td><code>csat_survey</code></td><td>object</td><td>An object containing information related to the csat_survey response of the request. Details about the object can be found <a href="#csat-survey-response-object">here</a>.</td></tr><tr><td><code>channel</code></td><td>object</td><td>An object containing channel information where the request was sent.<br>Details about the object can be found <a href="#channel-object">here</a>.</td></tr><tr><td><code>collection</code></td><td>object</td><td>An object containing collection information to which the above channel belongs where the request was sent.<br>Details about the object can be found <a href="/pages/z5lBsXxhowmqfAsvO90c">here</a>.</td></tr><tr><td><code>custom_field_values</code></td><td>object</td><td>An object containing custom field values<br>The object will have custom field ids as keys and the values of the custom fields as values of the object.<br>Note: Values will be ids in case of <code>select</code> and <code>multi_select</code> type custom fields.</td></tr><tr><td><code>ai_field_values</code></td><td>object</td><td><p>An Object that denotes the values of the fields (i.e - <strong>Auto-Category</strong>, <strong>Auto-Emotion</strong> and <strong>Auto-CSAT</strong>) of a Request auto populated by AI<br><br><code>Category</code> : A List of values to categorize the type of request, it is <strong>auto updated</strong> every time the request is updated with a Public Comment<br><code>Sentiment</code> : Customer Satisfaction as analyzed by the AI, It is updated when the request is updated by the Customer<br><code>Emotion</code> : Detected sentiment of a Customer based on the Overall discussions in the request<br><br>Ex :-</p><pre class="language-json"><code class="lang-json">"ai_field_values": {
"category": [
                "problem_report",
                "bug"
],
"sentiment": "neutral",
"emotion": "negative"
}
</code></pre></td></tr><tr><td><code>request_thread</code></td><td>object</td><td><p>An object containing information related to the thread corresponding to the request.</p><p>Details about the object can be found <a href="#thread-object">here</a>.</p></td></tr><tr><td><code>triage_thread</code></td><td>object</td><td>An object containing information related to the triage thread corresponding to the request.<br>Details about the object can be found <a href="#thread-object">here</a>.</td></tr><tr><td><code>sla_metrics</code></td><td>object</td><td><p>An object containing SLA metrics information</p><p>Details about the object can be found <a href="#sla-metrics-object">here</a>.</p></td></tr><tr><td><code>created_at</code></td><td>string</td><td>The creation timestamp of the request</td></tr><tr><td><code>updated_at</code></td><td>string</td><td>The update timestamp of the request</td></tr><tr><td><code>last_message_time</code></td><td>string</td><td>Timestamp of when customer was last active</td></tr></tbody></table>

## Assignee Object

Assignee of the request is represented as a JSON object with the following property

<table data-full-width="true"><thead><tr><th width="130">Name</th><th width="85">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>string</td><td>Slack/MS Teams User ID of the assignee for the request</td></tr></tbody></table>

## Assigned Team Object

The assigned team for a request is represented as a JSON object with the following property:

<table data-full-width="true"><thead><tr><th width="130">Name</th><th width="85">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>number</td><td>The numeric ID of the assigned team for the request</td></tr></tbody></table>

## Ticket Object

Tickets are represented as JSON objects with the following properties

<table data-full-width="true"><thead><tr><th width="130">Name</th><th width="85">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>integer</td><td>The ID of the ticket</td></tr><tr><td>type</td><td>string</td><td><p>Type of the ticket</p><p>Allowed values : <code>zendesk</code>, <code>jira</code>, <code>jsm</code>, <code>salesforce</code>, <code>freshdesk</code>, <code>hubspot</code>, <code>clearfeed</code>, <code>github</code>, <code>intercom</code>, <code>linear</code></p></td></tr><tr><td>key</td><td>string</td><td>The key used for the ticket id.</td></tr><tr><td>url</td><td>string</td><td>The url of the ticket.</td></tr><tr><td>created_at</td><td>string</td><td>The creation timestamp of the ticket</td></tr><tr><td>form_id</td><td>integer</td><td>The ID of the form used to create this ticket, if one was used. Use the <a href="/pages/tw0atbV3hMtJh424Kw5n#get-ticket-form-by-id">Get Ticket Form</a> endpoint to retrieve full form details.</td></tr></tbody></table>

## CSAT Survey Response Object

CSAT survey responses are represented as JSON objects with the following properties

<table data-full-width="true"><thead><tr><th width="119">Name</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td>status</td><td>string</td><td><p>Status of the csat_survey.</p><p>Allowed values:</p><p><code>pending</code>, <code>received</code></p></td></tr><tr><td>response</td><td>object</td><td>This object will only be present if the status of the csat survey is <code>received</code></td></tr><tr><td>survey_type</td><td>string</td><td><p>Type of the the cast survey.</p><p>Allowed Values: <code>five_point_rating</code></p></td></tr><tr><td>value</td><td>number</td><td>Points given in the CSAT survey response.</td></tr><tr><td>max_value</td><td>number</td><td>Maximum possible value of the response.</td></tr></tbody></table>

## Thread Object

Thread are represented as JSON objects with the following properties

<table data-full-width="true"><thead><tr><th width="141">Name</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td>channel_id</td><td>string</td><td>id of the channel where the thread exists.</td></tr><tr><td>thread_ts</td><td>string</td><td>id of the thread</td></tr><tr><td>team_id</td><td>string</td><td>team_id of the workspace where channel containing this thread exists.</td></tr><tr><td>url</td><td>string</td><td>URL of the thread</td></tr></tbody></table>

## SLA Metrics Object

SLA Metrics are represented as JSON objects with the following properties

<table data-full-width="true"><thead><tr><th width="198">Name</th><th width="85">Type</th><th>Description</th></tr></thead><tbody><tr><td>resolution_time</td><td>object</td><td>This field will hold <code>null</code> if the request is currently not in <code>solved</code> or <code>closed</code> state.</td></tr><tr><td>first_response_time</td><td>object</td><td>This field will hold <code>null</code> if currently, the request hasn't had a first response in some way or the other.</td></tr><tr><td>first_resolution_time</td><td>object</td><td>This field will hold <code>null</code> if the request has not been marked as <code>solved</code> at least once.</td></tr></tbody></table>

## Collection Object

The collection of a request is represented as a JSON object with the following properties:

<table data-full-width="true"><thead><tr><th width="100">Name</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>string</td><td>Id of the collection</td></tr><tr><td>name</td><td>string</td><td>name of the collection</td></tr></tbody></table>

## Channel Object

Channel of a request is represented as JSON object with the following properties:

<table data-full-width="true"><thead><tr><th width="100">Name</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>string</td><td>Id of the channel</td></tr><tr><td>name</td><td>string</td><td>name of the channel</td></tr><tr><td>owner</td><td>string</td><td>id of the channel owner</td></tr></tbody></table>

## Message Object

The message of a request is represented as a JSON object with the following properties. It is included in the API when the `include` query parameter is passed with the value `messages`.

<table data-full-width="true"><thead><tr><th width="150">Name</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td>text</td><td>string</td><td>Text content of the message</td></tr><tr><td>author</td><td>string</td><td>Author of the message</td></tr><tr><td>ts</td><td>string</td><td>Id of the message</td></tr><tr><td>thread_ts</td><td>string</td><td>Id of the thread where the message was sent</td></tr><tr><td>is_responder</td><td>boolean</td><td>Indicates whether the message was sent by a responder.</td></tr></tbody></table>

## Create Request

<mark style="color:blue;">`POST`</mark> `https://api.clearfeed.app/v1/rest/requests`

Create a new request in ClearFeed.

### Request Body

| Name                                          | Type   | Description                                                                                                                                   |
| --------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| description<mark style="color:red;">\*</mark> | string | The description of the request in HTML format. **Max Length:** 4000 characters.                                                               |
| title                                         | string | (Optional) The title of the request as plain text. If omitted, a title will be generated using AI. **Max Length:** 300 characters.            |
| requester\_email                              | string | (Optional) The email of the requester. If omitted, the request will be created on behalf of the user associated with the provided token.      |
| priority                                      | string | (Optional) The priority of the request. If omitted, a priority will be generated using AI. Allowed values: `low`, `normal`, `high`, `urgent`. |
| attachments                                   | file   | (Optional) A list of file attachments. Each file must not exceed **100MB** in size, and a maximum of **5 files** can be uploaded.             |

### Example cURL Request

```bash
curl --location 'https://api.clearfeed.app/v1/rest/requests' \
--form 'description="<p>Hi there\!</p>"' \
--form 'title="REQUEST FROM API"' \
--form 'requester_email="deepak@gmail.com"' \
--form 'priority="high"' \
--form 'attachments=@path/to/file1' \
--form 'attachments=@path/to/file2'
```

### Response

| Name    | Type   | Description                         |
| ------- | ------ | ----------------------------------- |
| request | object | Contains the request details        |
| id      | string | The ID of the newly created request |

#### Example Response

```json
{
  "request": {
    "id": "12345"
  }
}
```

### Notes

* **Description** must be provided in HTML format and should not exceed 4000 characters.
* **Title** and **Priority** are optional. If not provided, AI will generate them.
* If **requester\_email** is not provided, the request will be created on behalf of the authenticated user.
* **Attachments** must adhere to the following constraints:
  * Maximum file size per attachment: **100MB**.
  * Maximum number of files: **5**.

## Add Message to an Existing Request

<mark style="color:blue;">`POST`</mark> `https://api.clearfeed.app/v1/rest/requests/:id/message`

Post a reply message to an existing request. This endpoint allows you to send messages to request threads, either as a bot or as yourself.

#### Path Parameters

| Name                                 | Type   | Description |
| ------------------------------------ | ------ | ----------- |
| id<mark style="color:red;">\*</mark> | Number | Request Id  |

### Request Body

| Name          | Type    | Description                                                                                                                                                                                                                                                    |
| ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `html_body`   | string  | <p>The message content in HTML/string format.<br>Posts the Message as the Actual User</p>                                                                                                                                                                      |
| `thread_ts`   | string  | Thread timestamp for posting the message to a specific thread.                                                                                                                                                                                                 |
| `is_private`  | boolean | If `true`, posts the message as a private internal note that is only visible to members of your support team and others with access to the triage channel or ClearFeed web app; it is not shown to the requester or other external users. Defaults to `false`. |
| `post_as_bot` | boolean | <p>If <code>true</code>, posts the message as a bot with the Users creds (i.e - ClearFeed Logo visible on User Profile).<br>Defaults to <code>false</code></p>                                                                                                 |
| `attachments` | file    | A list of file attachments. Each file must not exceed **100MB** in size, and a maximum of **5 files** can be uploaded.                                                                                                                                         |

**NOTE** : We cannot post an **Empty Message,** either the `html_body` or atleast **one** `attachments` is required

### Example cURL Request

```bash
curl --location 'https://api.clearfeed.app/v1/rest/requests/123/message' \
--form 'html_body="Thank you for your request. We are looking into this issue."' \
--form 'is_private="false"' \
--form 'post_as_bot="true"' \
--form 'attachments=@path/to/file1'
```

### Response

Returns 201 on Successfully posting the Message.

### NOTES

* Data to the Endpoint needs to be sent via **form-data** from Request Body and not as Query/URL Parameters
* `html_body` should be provided in HTML/string format and must have at least 1 character if specified.
* **Attachments** must adhere to the following constraints:
  * Maximum file size per attachment: **100MB**.
  * Maximum number of files: **5**.

## Get Requests

<mark style="color:blue;">`GET`</mark> `https://api.clearfeed.app/v1/rest/requests`

Get all requests in an account

#### Query Parameters

| Name           | Type     | Description                                                                                                                                                                                                                          |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| collection\_id | Number   | Use the `collection_id` parameter to filter requests for a specific collection. Provide the collection's unique identifier to narrow down the results to that collection's requests.                                                 |
| sort\_order    | String   | The `sort_order` parameter lets you set the result sorting order. Use 'asc' for ascending and 'desc' for descending. By default, results are sorted in 'desc' order, arranging them from newest to oldest based on creation time.    |
| next\_cursor   | String   | Utilize the `next_cursor` parameter to access the next batch of results when paginating. This field will be present under `response_metadata` in the previous API response.                                                          |
| limit          | Number   | Specify the number of results per response (1-100), defaulting to 50.                                                                                                                                                                |
| filter\_by     | String   | Specify which field to use for sorting and filtering. Allowed values: `created_at`, `updated_at`. Defaults to `created_at` if not specified. When set to `updated_at`, requests are sorted and paginated by their last updated time. |
| after          | ISO Date | Employ the `after` parameter to fetch entities created after the provided ISO8601 date. The default value is None.                                                                                                                   |
| before         | ISO Date | Use the `before` parameter to retrieve entities created before the provided ISO8601 date. The default value is None.                                                                                                                 |
| include        | String   | Must be set to the exact value `messages` to include the list of associated messages (`messages` array) within the response object.                                                                                                  |
| state          | String   | Fetches Request's based on their State (`open`, `on_hold`, `in_progress`, `solved`, `pending`, `closed`, `none`)                                                                                                                     |
| channel\_id    | String   | Fetch all requests created in a specific **Request Channel**, using the channel\_id (ex :- `CABC1234`)                                                                                                                               |
| author\_emails | String   | Fetch all Requests created by an User via their **email** (ex :- `xyz@gmail.com`)                                                                                                                                                    |

**IMPORTANT POINTS :**\
\
1\) When using `filter_by = updated_at`, due to the dynamic nature of updated records, paginating through API responses may occasionally lead to repeated or missing entries if changes occur between requests. For consistent pagination results, consider using `filter_by=created_at` (default behavior).

2\) To fetch conversations that were marked as "**not a request**" or were never converted into requests, use `state = none` query parameter. Refer to the `not_a_request_state` field description in [request object definition](#request-object).\
\
i) When `state = none` is **included** in the GET call, then `not_a_request_state` will always return `null` in the **Response Object**\
ii) When `state = none` is **not included** in the GET call, then `not_a_request_state` can return any of the 3 values (i.e - `temporary`, `permanent` and `null`)

3\) If you want to search for requests in **multiple states**, you need to add the **`state`** parameter **once for each state** in the URL.\
\
ex :- To get all requests that are in **OPEN** and **PENDING** state\
Request URL : `https://api.clearfeed.app/v1/rest/requests?state=open&state=pending`

{% tabs %}
{% tab title="200 " %}

```javascript
{
  "requests": [
    {
      "id": 1,
      "title": "Can you check this out?",
      "state": "open",
      "priority": "normal",
      "author": "UXYZ123",
      "customer_id": 456,
      "assignee": {
        "id": "UABC123"
      },
      "assigned_team": {
        "id": 1
      },
      "tickets": [
        {
          "id": "12345",
          "type": "jira",
          "key": "CLRF-2",
          "created_at": "2023-01-01T00:00:00.000Z",
          "url": "https://clearfeed.atlassian.net/browse/CLRF-2",
          "form_id": 789
        }
      ],
      "csat_survey": {},
      "channel": {
        "id": "CABC1234",
        "name": "ClearFeed-Nexova",
        "owner": "UABC1234"
      },
      "collection": {
        "id": 1,
        "name": "enterprise-customers"
      },
      "custom_field_values": {},
      "request_thread": {
        "channel_id": "CABC1234",
        "thread_ts": "1692781448.777319",
        "team_id": "T024NBB217Z",
        "url": "https://clearfeed.slack.com/archives/CABC1234/p1692781448777319?thread_ts=1692781448.777319"
      },
      "triage_thread": {
        "channel_id": "CTRIAG1235",
        "thread_ts": "1692781449.545479",
        "team_id": "T024NBB217Z",
        "url": "https://clearfeed.slack.com/archives/CTRIAG1235/p1692781449545479?thread_ts=1692781449.545479"
      },
      "sla_metrics": {
        "resolution_time": null,
        "first_response_time": null,
        "first_resolution_time": null
      },
      "messages": [
        {
          "text": "I need some help with this issue.",
          "author": "UABC1234",
          "ts": "1670011050.128179",
          "thread_ts": null,
          "is_responder": true
        }
      ],
      "created_at": "2023-01-01T00:00:00.000Z",
      "updated_at": "2023-01-01T00:00:00.000Z"
    }
  ],
  "response_metadata": {
    "next_cursor": "NjM4OQ==",
    "count": "number"
  }
}
```

{% endtab %}
{% endtabs %}

## Get Request by ID

<mark style="color:blue;">`GET`</mark> `https://api.clearfeed.app/v1/rest/requests/:id`

#### Path Parameters

| Name                                 | Type   | Description |
| ------------------------------------ | ------ | ----------- |
| id<mark style="color:red;">\*</mark> | Number | Request Id  |

#### Query Parameters

| Name      | Type   | Description                                                                                                                                    |
| --------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `include` | string | (Optional) Must be set to the exact value `messages` to include the list of associated messages (`messages` array) within the response object. |

{% tabs %}
{% tab title="200 OK (Without Messages)" %}

```json
{
  "request": {
    "id": 1,
    "title": "Can you check this out?",
    "state": "open",
    "priority": "normal",
    "author": "UXYZ123",
    "customer_id": 456,
    "assignee": {
      "id": "UABC123"
    },
    "assigned_team": {
      "id": 1
    },
    "tickets": [
      {
        "id": "12345",
        "type": "jira",
        "key": "CLRF-2",
        "created_at": "2023-01-01T00:00:00.000Z",
        "url": "https://clearfeed.atlassian.net/browse/CLRF-2",
        "form_id": 789
      }
    ],
    "csat_survey": {},
    "channel": {
      "id": "CABC1234",
      "name": "ClearFeed-Nexova",
      "owner": "UABC1234"
    },
    "collection": {
      "id": 1,
      "name": "enterprise-customers"
    },
    "custom_field_values": {},
    "request_thread": {
      "channel_id": "CABC1234",
      "thread_ts": "1692781448.777319",
      "team_id": "T024NBB217Z",
      "url": "https://clearfeed.slack.com/archives/CABC1234/p1692781448777319?thread_ts=1692781448.777319"
    },
    "triage_thread": {
      "channel_id": "CTRIAG1235",
      "thread_ts": "1692781449.545479",
      "team_id": "T024NBB217Z",
      "url": "https://clearfeed.slack.com/archives/CTRIAG1235/p1692781449545479?thread_ts=1692781449.545479"
    },
    "sla_metrics": {
      "resolution_time": null,
      "first_response_time": null,
      "first_resolution_time": null
    },
    "created_at": "2023-01-01T00:00:00.000Z",
    "updated_at": "2023-01-01T00:00:00.000Z"
  }
}
```

{% endtab %}

{% tab title="200 OK (With Messages)" %}

```json
{
  "request": {
    "id": 255,
    "title": "I need help",
    "state": "pending",
    "priority": "normal",
    "author": "U02PKBD0RSB",
    "customer_id": 789,
    "assignee": {
      "id": "U087T6WGBPB"
    },
    "assigned_team": null,
    "tickets": [
      {
        "id": "255",
        "type": "clearfeed",
        "key": "CF-255",
        "created_at": "2025-02-28T12:27:51.551Z",
        "url": "https://cf-john.slack.com/archives/C08BH222DGT/p1740745641520939"
      }
    ],
    "csat_survey": null,
    "channel": {
      "id": "C08BH222DGT",
      "name": "req8",
      "owner": "U087T6WGBPB"
    },
    "collection": {
      "id": 11,
      "name": "new8"
    },
    "custom_field_values": {},
    "request_thread": {
      "channel_id": "C08BH222DGT",
      "thread_ts": "1740745641.520939",
      "team_id": "T087GJ1FMN0",
      "url": "https://cf-john.slack.com/archives/C08BH222DGT/p1740745641520939"
    },
    "triage_thread": {
      "channel_id": "C08B2JGF163",
      "thread_ts": "1740745671.420209",
      "team_id": "T087GJ1FMN0",
      "url": "https://cf-john.slack.com/archives/C08B2JGF163/p1740745671420209"
    },
    "sla_metrics": {
      "first_response_time": {
        "value": 0,
        "is_breached": null
      },
      "resolution_time": null,
      "first_resolution_time": null
    },
    "created_at": "2025-02-28T12:27:21.520Z",
    "updated_at": "2025-02-28T12:55:00.346Z",
    "messages": [
      {
        "text": "hi i need help",
        "author": "U02PKBD0RSB",
        "ts": "1740745641.520939",
        "thread_ts": null,
        "is_responder": false
      },
      {
        "text": "okay",
        "author": "U087T6WGBPB",
        "ts": "1740745683.751609",
        "thread_ts": "1740745641.520939",
        "is_responder": true
      },
      {
        "text": "test",
        "author": "U087T6WGBPB",
        "ts": "1740747010.696119",
        "thread_ts": "1740745641.520939",
        "is_responder": true
      },
      {
        "text": "test again",
        "author": "U087T6WGBPB",
        "ts": "1740747300.346039",
        "thread_ts": "1740745641.520939",
        "is_responder": true
      }
    ]
  }
}
```

{% endtab %}

{% tab title="404: Not Found Request Not Found" %}
// Occurs if no request exists with the specified id for the account

```json
{
  "statusCode": 404,
  "message": "Request not found."
}
```

{% endtab %}
{% endtabs %}

## Update Request

<mark style="color:purple;">`PATCH`</mark> `https://api.clearfeed.app/v1/rest/requests/:id`

Updates an existing request. Only the specified fields in the request body will be updated.

#### Path Parameters

| Name                                 | Type   | Required | Description |
| ------------------------------------ | ------ | :------: | ----------- |
| id<mark style="color:red;">\*</mark> | Number |    Yes   | Request Id  |

### Request Body

All fields are optional; however, at least one must be provided. If no fields are supplied or if all are empty or invalid, the request will fail with a 400 Bad Request error.

| Name                  | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state`               | String | <p>(Optional) New state of the request.</p><p>Allowed values :</p><p><code>open</code>, <code>in\_progress</code>, <code>pending</code>, <code>on\_hold</code>, <code>solved</code>, <code>closed</code></p><p>If you attempt to set the state to <code>on\_hold</code> but your account disallows it, you will get a <strong>400 Bad Request</strong>.<br>If the existing state is <code>closed</code>, you cannot change it (406 Not Acceptable).</p> |
| `assignee`            | String | (Optional) User ID of the new assignee.                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `title`               | String | (Optional) New title for the request, with a minimum length of 1 character and a maximum of 300 characters.                                                                                                                                                                                                                                                                                                                                             |
| `priority`            | String | <p>(Optional) New priority for the request. Allowed values :</p><p><code>low</code>, <code>normal</code>, <code>high</code>, <code>urgent</code></p>                                                                                                                                                                                                                                                                                                    |
| `custom_field_values` | Object | <p>(Optional) Map of <strong>custom field ID</strong> → <strong>new value</strong>.<br>Setting a value to null deletes the entry.<br>Any invalid field IDs or invalid value formats cause a <strong>400 Bad Request</strong>. Refer <a data-mention href="#custom-field-value-format-guide">#custom-field-value-format-guide</a> for more details.</p>                                                                                                  |

### Example Request Body

```json
{
  "state": "on_hold",
  "assignee": "UABC123",
  "title": "Updated request title",
  "priority": "high",
  "custom_field_values": {
    "1": "some_value",
    "2": null
  }
}
```

#### Custom Field Value Format Guide

The table below outlines the expected value formats when updating custom fields via the `custom_field_values` object. Each field type requires a specific format to ensure successful updates.

| Custom Field Type | Expected Value Format         | Example Value                    |
| ----------------- | ----------------------------- | -------------------------------- |
| Single Select     | String (Option id)            | `"1"`                            |
| Multi Select      | Array of strings (option IDs) | `["1", "2"]`                     |
| Text              | String                        | `"Customer request details"`     |
| Date              | ISO 8601 date string          | `"2024-02-24" (`ISO 8601 Format) |
| Number            | Number (integer or float)     | `42`, `99.99`                    |
| User Type         | String (user ID)              | `"user_12345"`                   |

{% tabs %}
{% tab title="200: OK" %}

{% endtab %}

{% tab title="400: Bad Request" %}

{% endtab %}

{% tab title="404: Not Found" %}

{% endtab %}

{% tab title="406: Not Acceptable" %}

{% endtab %}
{% endtabs %}

## Bulk Import Requests

<mark style="color:blue;">`POST`</mark> `https://api.clearfeed.app/v1/rest/requests/batch`

Import up to **50 historical requests** in a single API call. Each request is created with its full message history, requester, optional assignee, state, and priority. Requests are created in ClearFeed's API collection.

This endpoint is designed for migrating requests from external systems into ClearFeed. All timestamps are historical — messages and requests are stored with their original creation times.

### Request Body

The body must be a JSON object with a single `requests` array.

| Name                                       | Type  | Description                                                                                                                                              |
| ------------------------------------------ | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| requests<mark style="color:red;">\*</mark> | array | Array of request objects to import. Min: **1**, Max: **50** items. Items with the same `external_id` within a single call are rejected (must be unique). |

#### Request Item Object

Each element of the `requests` array is a request item with the following fields:

| Name                                        | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| requester<mark style="color:red;">\*</mark> | object | The user who created the request. See [User Reference Object](#user-reference-object).                                                                                                                                                                                                                                                                                                                                                                                    |
| messages<mark style="color:red;">\*</mark>  | array  | Array of message objects. Min: **1**, Max: **500** messages. The first message (`messages[0]`) is treated as the original request message. Subsequent messages are reply messages, and must not have a `created_at` earlier than `messages[0].created_at`.                                                                                                                                                                                                                |
| title<mark style="color:red;">\*</mark>     | string | Title of the request as plain text. **Max length:** 300 characters.                                                                                                                                                                                                                                                                                                                                                                                                       |
| state                                       | string | (Optional) State of the request. Allowed values: `open`, `in_progress`, `pending`, `on_hold`, `solved`, `closed`. Defaults to `in_progress`.                                                                                                                                                                                                                                                                                                                              |
| priority                                    | string | (Optional) Priority of the request. Allowed values: `low`, `normal`, `high`, `urgent`. Defaults to `normal`.                                                                                                                                                                                                                                                                                                                                                              |
| assignee                                    | object | (Optional) The support agent assigned to the request. Must be a workspace member (Slack user or email). Set to `null` to explicitly leave unassigned. See [Member Reference Object](#member-reference-object).                                                                                                                                                                                                                                                            |
| solved\_at                                  | string | (Optional) ISO 8601 timestamp of when the request was resolved. Only valid when `state` is `solved` or `closed`. Must be >= `messages[0].created_at`. When omitted for solved/closed requests, the last message timestamp is used for resolution-time metrics.                                                                                                                                                                                                            |
| external\_id                                | string | (Optional) Your system's unique identifier for this request. Used for **deduplication** — if a request with this `external_id` was previously imported for the same account, the item is returned as `duplicate` instead of being re-created. Deduplication is maintained for **2 weeks** after import.                                                                                                                                                                   |
| custom\_field\_values                       | object | (Optional) Map of **custom field ID** → **value** to set on the request at creation time. Custom fields must be pre-created before import (see [Custom Fields](/api/reference/api-reference/custom-fields.md)). Setting a value to `null` is a no-op for new requests. Any invalid field IDs or value formats cause the item to be marked as `failed`. See [Custom Field Value Format Guide](#custom-field-value-format-guide) for expected value formats per field type. |

#### User Reference Object

Identifies a user by one or more primary identifiers. At least one of `slack_user_id`, `email`, or `external_id` must be provided. If multiple are provided, resolution follows priority: `slack_user_id` → `email` → `external_id`.

| Name            | Type   | Description                                                                                                                                          |
| --------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| slack\_user\_id | string | The Slack user ID of the user (e.g. `UABC123`). Takes precedence over `email` and `external_id` when present.                                        |
| email           | string | Email address of the user. Required when neither `slack_user_id` nor `external_id` is provided.                                                      |
| external\_id    | string | Your system's opaque identifier for the user. Used when neither `slack_user_id` nor `email` is available. Creates a ClearFeed-internal user profile. |
| name            | string | (Optional) Display name for the user. Used when creating a new user profile.                                                                         |

#### Member Reference Object

Identifies a support team member (for the `assignee` field). Assignees must be workspace members — `external_id` is not supported.

| Name            | Type   | Description                                                                  |
| --------------- | ------ | ---------------------------------------------------------------------------- |
| slack\_user\_id | string | The Slack user ID of the member. Takes precedence over `email` when present. |
| email           | string | Email address of the member. Required when `slack_user_id` is absent.        |
| name            | string | (Optional) Display name for the member.                                      |

#### Message Object (Bulk Import)

| Name                                          | Type    | Description                                                                                                                                                                                                                                               |
| --------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| created\_at<mark style="color:red;">\*</mark> | string  | ISO 8601 timestamp of when the message was sent. Cannot be in the future. For reply messages, must be >= `messages[0].created_at`.                                                                                                                        |
| text                                          | string  | Plain-text content of the message. Required when `html_body` is absent. **Max length:** 4000 characters.                                                                                                                                                  |
| html\_body                                    | string  | HTML content of the message. Required when `text` is absent. Converted to plain text for storage. **Max length:** 4000 characters.                                                                                                                        |
| author<mark style="color:red;">\*</mark>      | object  | Author of this message. See [User Reference Object](#user-reference-object).                                                                                                                                                                              |
| is\_responder                                 | boolean | (Optional) Whether this message was sent by a support responder. When omitted, ClearFeed determines responder status from the collection's responder configuration. The requester's messages are always treated as non-responder regardless of this flag. |
| is\_private                                   | boolean | (Optional) Whether the message is private (internal note). Defaults to `false`.                                                                                                                                                                           |

### Example Request Body

```json
{
  "requests": [
    {
      "external_id": "TICKET-001",
      "title": "Cannot log in to the dashboard",
      "state": "solved",
      "priority": "high",
      "solved_at": "2024-01-15T10:30:00.000Z",
      "requester": {
        "email": "alice@example.com",
        "name": "Alice"
      },
      "assignee": {
        "slack_user_id": "UABC123"
      },
      "custom_field_values": {
        "1": "2",
        "2": 42
      },
      "messages": [
        {
          "text": "I cannot log in to the dashboard since this morning.",
          "author": {
            "email": "alice@example.com"
          },
          "created_at": "2024-01-15T09:00:00.000Z"
        },
        {
          "text": "We are investigating the issue.",
          "author": {
            "slack_user_id": "UABC123"
          },
          "is_responder": true,
          "created_at": "2024-01-15T09:15:00.000Z"
        },
        {
          "text": "The issue has been resolved. Please try again.",
          "author": {
            "slack_user_id": "UABC123"
          },
          "is_responder": true,
          "created_at": "2024-01-15T10:30:00.000Z"
        }
      ]
    }
  ]
}
```

### Response

The response always contains a `results` array (one entry per input item, in order) and a `summary` object.

#### Response Summary Object

| Name      | Type   | Description                                   |
| --------- | ------ | --------------------------------------------- |
| total     | number | Total number of items submitted.              |
| created   | number | Number of requests successfully created.      |
| duplicate | number | Number of items skipped due to deduplication. |
| failed    | number | Number of items that failed to import.        |

#### Response Result Item

Each item in `results` corresponds to the input item at the same `index`.

| Name   | Type   | Description                                                                                                                                                    |
| ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| index  | number | Zero-based position of this item in the input `requests` array.                                                                                                |
| status | string | `created` — request was successfully imported. `duplicate` — skipped because a request with this `external_id` was already imported. `failed` — import failed. |
| id     | number | The ClearFeed request ID. Present when `status` is `created` or `duplicate`.                                                                                   |
| reason | string | Human-readable error message. Present only when `status` is `failed`.                                                                                          |

### HTTP Status Codes

| Status | Meaning                                                                               |
| ------ | ------------------------------------------------------------------------------------- |
| 201    | All items were successfully created.                                                  |
| 207    | Partial success — some items were created or deduplicated, but at least one failed.   |
| 422    | All items failed to import.                                                           |
| 400    | Request body validation failed (e.g. missing required fields, constraint violations). |

{% tabs %}
{% tab title="201: All Created" %}

```json
{
  "results": [
    { "index": 0, "status": "created", "id": 1042 },
    { "index": 1, "status": "created", "id": 1043 }
  ],
  "summary": {
    "total": 2,
    "created": 2,
    "duplicate": 0,
    "failed": 0
  }
}
```

{% endtab %}

{% tab title="207: Partial Success" %}

```json
{
  "results": [
    { "index": 0, "status": "created", "id": 1044 },
    { "index": 1, "status": "duplicate", "id": 987 },
    { "index": 2, "status": "failed", "reason": "solved_at cannot be before request created_at (2024-01-15T09:00:00.000Z)" }
  ],
  "summary": {
    "total": 3,
    "created": 1,
    "duplicate": 1,
    "failed": 1
  }
}
```

{% endtab %}

{% tab title="422: All Failed" %}

```json
{
  "results": [
    { "index": 0, "status": "failed", "reason": "Could not resolve requester" },
    { "index": 1, "status": "failed", "reason": "messages[0].created_at cannot be in the future" }
  ],
  "summary": {
    "total": 2,
    "created": 0,
    "duplicate": 0,
    "failed": 2
  }
}
```

{% endtab %}

{% tab title="400: Validation Error" %}

```json
{
  "statusCode": 400,
  "message": ["requests must contain no more than 50 elements"]
}
```

{% endtab %}
{% endtabs %}

### Notes

* **Content-Type:** The request body must be sent as `application/json`.
* **Ordering:** Items are processed sequentially in the order provided. The `index` field in each result maps back to the zero-based position in the input array.
* **Deduplication:** Provide `external_id` on each request item to enable idempotent imports. Re-submitting the same `external_id` within 2 weeks returns `duplicate` without creating a second request.
* **User resolution:** Users are looked up in order of priority: `slack_user_id` → `email` → `external_id`. If a Slack user ID is not found in the workspace, ClearFeed falls back to `email` if provided, then `external_id`.
* **Assignees:** must be resolvable workspace members (via `slack_user_id` or `email`). Assignees identified only by `external_id` are silently ignored. If the provided `slack_user_id` or `email` cannot be resolved to a workspace member, the assignee is silently ignored and the request is created unassigned.
* **Responder detection:** When `is_responder` is omitted on a message, ClearFeed uses the collection's responder configuration to classify the author. The requester is always treated as a non-responder.
* **Private messages:** Setting `is_private: true` on a reply message always stores it as a responder message (`is_responder = true`), regardless of any explicit `is_responder: false` on the same message.
* **State defaults:** When `state` is omitted, requests are created with state `in_progress`.
* **solved\_at:** Only applicable when `state` is `solved` or `closed`. Must not be in the future and must be >= `messages[0].created_at`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clearfeed.ai/api/reference/api-reference/requests.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
