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

# Interactions

> Send events from your own integrations to Assembly. This is a great way to track how your customers are interacting with your product. 

#### API Key

You must first create an API Key in Assembly. It is located under "Manage Integrations", then scroll to the bottom and click "Manage API Keys".

Here, you can see your existing keys, their names and expiration. You can delete existing ones.

When creating a new API key, the name must be unique in your organization. Once the key has been created, you will be shown a one-time dialog box with your new API key. You should copy this down somewhere safe -- we will not show this again.

If you lose your API key, you will need to make a new one.

For these endpoints, set the `Authorization` header to your API key value directly (for example `Authorization: <API_KEY>`). Do **not** add a `Bearer` prefix; the full header value is validated as the key.

#### Sending Events

Here is the API endpoint for sending events to Assembly. The only required field is <b>query</b>:

```bash theme={null}
curl -X \
 POST https://api.wavelength.cx/interactions \
 -F "query=Sample query text" \
 -H "Authorization: <API_KEY>" \
 -H "Content-Type: multipart/form-data" 
```

If you want to specify who is sending/creating the ticket, include a user. The user must have at least one of these fields: `email`, `source_specific_id`, or `id` (the Assembly ID). We will match the user to an existing Assembly customer/contact based on these fields. If no matching Assembly user exists, the user will be created. Other optional fields include `name`, `username`, `image_url`.
If you want to match the interaction to a specific company account, please include the `company_source_specific_id` or the `company_id` (the company's Assembly ID).
You can also pass in other optional fields like the title, original timestamp, and additional attributes.

#### Source Specific ID

You can include a `source_specific_id` to give the ticket a unique identifier. This is useful for:

* **Deduplication**: Prevent duplicate tickets from being created
* **Replying**: Use this ID later to add replies to the ticket via the `/interactions/reply` endpoint

```bash theme={null}
curl -X \
 POST https://api.wavelength.cx/interactions \
 -F "title=Sample title" \
 -F "query=Sample query text" \
 -F "source_specific_id=my_ticket_123" \
 -F "user={\"email\": \"user@example.com\", \"name\": \"John Doe\"}" \
 -F "original_timestamp=2024-06-10T18:34:00Z" \
 -H "Authorization: <API_KEY>" \
 -H "Content-Type: multipart/form-data"
```

You can then reply to this ticket using the `source_specific_id`:

```bash theme={null}
curl -X POST "https://api.wavelength.cx/interactions/reply?source_specific_id=my_ticket_123" \
  -H "Authorization: <API_KEY>" \
  -F "content=This is a reply to the ticket" \
  -F 'user={"email":"agent@example.com","name":"Support Agent"}'
```

#### Full Example with All Fields

```bash theme={null}
curl -X \
 POST https://api.wavelength.cx/interactions \
 -F "title=Sample title" \
 -F "query=Sample query text" \
 -F "source_specific_id=unique_ticket_id" \
 -F "user={\"email\": \"user@example.com\", \"name\": \"John Doe\", \"source_specific_id\": \"userSSID\"}" \
 -F "company_source_specific_id=companySSID" \
 -F "additional_properties={\"key1\": \"value1\", \"key2\": 123, \"key3\": \"value3\"}" \
 -F "original_timestamp=2024-06-10T18:34:00Z" \
 -H "Authorization: <API_KEY>" \
 -H "Content-Type: multipart/form-data"
```

```bash theme={null}
curl -X \
 POST https://api.wavelength.cx/interactions \
 -F "title=Sample title" \
 -F "query=Sample query text" \
 -F "user={\"email\": \"user@example.com\", \"name\": \"John Doe\"}" \
 -F "company_id=01945162-52fc-739b-98de-e2ac9f2eec49" \
 -F "additional_properties={\"key1\": \"value1\", \"key2\": 123, \"key3\": \"value3\"}" \
 -F "original_timestamp=2024-06-10T18:34:00Z" \
 -H "Authorization: <API_KEY>" \
 -H "Content-Type: multipart/form-data"
```

You can also pass in a base64 encoded image if you prefer, or an image URL:

```bash theme={null}
curl -X POST https://api.wavelength.cx/interactions \
-F "query=Sample query text" \
-F "files_base64=<base64 encoded image>" \
-H "Authorization: <API_KEY>" \
-H "Content-Type: multipart/form-data"
```

```bash theme={null}
curl -X POST https://api.wavelength.cx/interactions \
-F "query=Sample query text" \
-F "files_image_url=https://example.com/img.jpg" \
-H "Authorization: <API_KEY>" \
-H "Content-Type: multipart/form-data"
```

You can attach multiple images by passing in multiple files.

```bash theme={null}
curl -X POST https://api.wavelength.cx/interactions \
-F "query=Sample query text" \
-F "files_base64=<base64 encoded image_1>" \
-F "files_base64=<base64 encoded image_2>" \
-H "Authorization: <API_KEY>" \
-H "Content-Type: multipart/form-data"
```

The files field is used to send images to Assembly. You can currently send JPG and PNG images up to 4MB in size.

Here are some of the errors that may be returned:

* 400: Invalid request - missing title, file too large, couldn't be opened, etc.
* 401: Invalid API Key or expired API Key
* 503: Assembly server error has been logged and our team has been notified

Errors take on the following format in JSON:

```json theme={null}
{"error": "message"}
```

Successful responses take on the following format in JSON:

```json theme={null}
{"created_ticket_number": "ASM-111"}
```

#### Rate Limiting

There is a rate limit of 30 events per second. If you exceed this, you will receive a 429 response code.

If you need a higher rate, please let us know.

#### Create Interaction Reply

## POST /interactions/reply

Creates a new reply/message for an existing ticket. Supports multiple ticket identification methods and file attachments.

### Query Parameters

Exactly one of the following is required:

| Parameter            | Type   | Description                                  |
| -------------------- | ------ | -------------------------------------------- |
| `id`                 | string | Assembly ULID of the ticket to reply to      |
| `source_specific_id` | string | Source-specific ID of the ticket to reply to |

### Headers

* `Content-Type: multipart/form-data` (required for file uploads)
* `Authorization: <API_KEY>` (required; raw key, no `Bearer` prefix)

### Request Body (multipart/form-data)

| Field                | Type    | Required | Description                                          |
| -------------------- | ------- | -------- | ---------------------------------------------------- |
| `content`            | string  | Yes      | The reply message content                            |
| `source_specific_id` | string  | No       | Unique identifier for this reply (for deduplication) |
| `original_timestamp` | string  | No       | Original timestamp in RFC3339 format                 |
| `user`               | object  | Yes      | User information object                              |
| `files`              | file\[] | No       | File attachments (multipart)                         |
| `files_image_url`    | string  | No       | Comma-separated URLs of images to attach             |

#### User Object

| Field                | Type   | Required | Description               |
| -------------------- | ------ | -------- | ------------------------- |
| `id`                 | string | No\*     | User ID                   |
| `name`               | string | No       | User name                 |
| `email`              | string | No\*     | User email                |
| `source_specific_id` | string | No       | User's source-specific ID |

\*At least one of `id` or `email` is required. If only `email` is provided, it will be used as the user identifier.

### Ticket Identification

The endpoint requires exactly one query parameter for ticket identification:

* **`id`** - Assembly ULID of the ticket
* **`source_specific_id`** - Source-specific ID of the ticket

Both parameters cannot be provided simultaneously, and at least one is required.

### Example Request (with Assembly ULID)

```bash theme={null}
curl -X POST "https://api.wavelength.cx/interactions/reply?id=01KKXRZM9PJRKJ488ZK3PB6JPX" \
  -H "Authorization: <API_KEY>" \
  -F "content=This is my reply to the ticket" \
  -F 'user={"name":"John Doe","email":"john@example.com"}' \
  -F "source_specific_id=reply_12345"
```

### Example Request (with source\_specific\_id)

```bash theme={null}
curl -X POST "https://api.wavelength.cx/interactions/reply?source_specific_id=ticket_ss_123" \
  -H "Authorization: <API_KEY>" \
  -F "content=Reply via source specific ID" \
  -F "files=@attachment.pdf" \
  -F 'user={"name":"Jane Doe","email":"jane@example.com"}'
```

### Example Request (with file uploads)

```bash theme={null}
curl -X POST "https://api.wavelength.cx/interactions/reply?source_specific_id=ticket_abc123" \
  -H "Authorization: <API_KEY>" \
  -F "content=Here are the files you requested" \
  -F "files=@document1.pdf" \
  -F "files=@image.png" \
  -F "files_image_url=https://example.com/image1.jpg,https://example.com/image2.jpg" \
  -F 'user={"name":"Alice","email":"alice@example.com"}'
```

### Response

```json theme={null}
{
  "created_history_id": "01H8X9Z7Y2W3R4T5U6V7W8X9Y"
}
```

| Field                | Type   | Description                        |
| -------------------- | ------ | ---------------------------------- |
| `created_history_id` | string | ULID of the created history record |

### Error Responses

#### 400 Bad Request

```json theme={null}
{
  "error": "content is required"
}
```

```json theme={null}
{
  "error": "user is required"
}
```

```json theme={null}
{
  "error": "user.id or user.email is required"
}
```

```json theme={null}
{
  "error": "exactly one of id or source_specific_id must be provided"
}
```

```json theme={null}
{
  "error": "invalid ULID format for id parameter"
}
```

#### 404 Not Found

```json theme={null}
{
  "error": "ticket not found for identifier: ticket_abc123"
}
```

#### 409 Conflict (Duplicate)

```json theme={null}
{
  "error": "source specific id already exists"
}
```

#### 413 Payload Too Large

```json theme={null}
{
  "error": "File size exceeds 32MB"
}
```

### Important Notes

* **File Size Limit**: 32MB per file
* **Supported File Types**: Any file type can be uploaded
* **Deduplication**: Duplicate `source_specific_id` values are rejected for Slack/Community Slack sources
* **User Requirement**: User object with `user.id` is now mandatory (no anonymous users)
* **Query Parameter Exclusivity**: Exactly one of `id` or `source_specific_id` must be provided, not both
* **Rate Limiting**: Subject to rate limiting (60 requests per minute per API key/IP)
