# Connectors

> Connectors bring data into a Conclude app from outside the chat platform — email, web forms, ticketing systems — or push enrichment data into an agent’s context.

Canonical HTML page: https://conclude.io/doc/reference/connectors/
Last updated: 2026-11-02

---

Connectors bring data into a Conclude app from outside the chat platform —
email, web forms, ticketing systems — or push enrichment data into an
agent's context.

## Email connector

Receives inbound email and turns each message into an activity.

```yaml
emailConnector:
  id: support@acme.io           # the inbound address (assigned on install)
  from: support@acme.io         # optional, sender on outbound replies
  replyTo: support@acme.io      # optional
  primaryLanguage: en
  supportedLanguages: [en, fr]
  attributeMap:
    - external: subject
      internal: title
    - external: body
      internal: body
    - external: from.email
      internal: contactEmail
  preprocess:
    instructions: |
      Extract the customer's intent in one sentence.
    output: summary             # writes the LLM output to this attribute
  summarize:
    instructions: |
      Summarize this thread for the support team.
    output: summary
```

| YAML key | Type | Purpose |
|---|---|---|
| `id` | string | Assigned inbound address (read-only after install) |
| `disabled` | bool | Turn the connector off without removing config |
| `from` | string | Outbound sender address; defaults to `id` |
| `replyTo` | string | Outbound reply-to header |
| `attributeMap` | list | Maps email fields (`subject`, `body`, `from.email`, etc.) to attributes |
| `preprocess` | object | Optional LLM step on each inbound email (instructions, output attribute) |
| `summarize` | object | Optional LLM summary written into an attribute |
| `primaryLanguage` | string | Best-guess for the customer's language |
| `supportedLanguages` | list | Languages the agent can reply in |

The activity's reply-to thread is the email conversation; outbound replies
go to the original sender unless `from`/`replyTo` overrides apply.

## Web connector

Receives inbound HTTP form posts and turns each post into an activity.
Pair with a hosted form or an in-app widget.

```yaml
webConnector:
  id: contact-form              # assigned on install
  domain: acme.com,acme.io      # CORS allowlist (comma-separated)
  attributeMap:
    - external: name
      internal: contactName
    - external: email
      internal: contactEmail
    - external: message
      internal: body
  logMessage: true              # log each accepted submission
  logJunk: false                # log rejected (junk-filtered) submissions
```

| YAML key | Type | Purpose |
|---|---|---|
| `id` | string | Connector identifier; part of the inbound URL |
| `disabled` | bool | Turn off without removing config |
| `domain` | string | Comma-separated CORS-allowed origins |
| `attributeMap` | list | Form field → activity attribute mapping |
| `logMessage` | bool | Log every accepted submission |
| `logJunk` | bool | Log rejected submissions (rate-limited, spam-filtered) |

Use `settings.rateLimit` to throttle inbound traffic per minute.

## Jira connector

Sync activities with a Jira project.

```yaml
jira:
  subdomain: acme               # Jira instance: acme.atlassian.net
  projectKey: SUP
  syncOnlyPinnedComments: false # if true, only pinned comments sync to Jira
```

| YAML key | Type | Required | Purpose |
|---|---|---|---|
| `subdomain` | string | ✓ | Jira instance subdomain |
| `projectKey` | string | ✓ | Project key (e.g. `SUP`) |
| `disabled` | bool | — | Turn off without removing config |
| `syncOnlyPinnedComments` | bool | — | Restrict comment sync to pinned-only |

OAuth for the Jira instance is configured via the integrations UI, not in
the YAML. For how activity states map to Jira status categories, see
[Statuses and states](https://conclude.io/doc/reference/statuses/#jira-mapping).

## Zendesk integration

```yaml
zendesk:
  subdomain: acme               # acme.zendesk.com
  tag: conclude-managed
  triage:
    members: ${owner}
    alert: "#triage"
  attributeMap:
    - external: subject
      internal: title
    - external: description
      internal: body
```

| YAML key | Type | Required | Purpose |
|---|---|---|---|
| `subdomain` | string | ✓ | Zendesk instance subdomain |
| `tag` | string | — | Tag applied to managed Zendesk tickets |
| `triage` | object | — | Routing rules (members + alert) for incoming tickets |
| `attributeMap` | list | — | Zendesk field → attribute mapping |
| `disabled` | bool | — | Turn off without removing config |

For how Conclude statuses map to Zendesk ticket statuses (both directions),
see [Statuses and states](https://conclude.io/doc/reference/statuses/#zendesk-mapping).

## Lookup endpoint

A lookup endpoint enriches an agent's prompt context with external data
(CRM record, customer tier, account history). Conclude POSTs to the URL
with the triggering event and basic activity info, and includes the
response body in the agent's prompt.

```yaml
lookup:
  url: https://crm.example.com/conclude-enrich
  secret: crm_api_token         # references a Secret by name
  on: [onCreate, onComment]     # events that fire the lookup
  timeout: 5s
```

| YAML key | Type | Required | Purpose |
|---|---|---|---|
| `url` | string | ✓ | HTTPS endpoint (HTTP rejected; private IPs rejected) |
| `on` | list | ✓ | Events that trigger the lookup (`onCreate`, `onComment`, `onEdit`, `onConclude`) |
| `secret` | string | — | Name of a Secret holding a bearer token (sent as `Authorization: Bearer <token>`) |
| `timeout` | string | — | Request timeout (`5s`, `10s`...); default 5 s, max 30 s |

**Request body** (JSON):

```json
{"event": "onCreate", "activity": {"title": "...", "email": "..."}}
```

**Response**: any text/JSON, truncated to 4 KB. Returned verbatim as
agent context under a `## Customer context` section.

**Safety:** URL must be HTTPS; the resolved IP must not be loopback,
link-local, or RFC1918 private. Errors and timeouts are logged but never block the
agent's reply.

## Attribute map syntax

All connectors use the same `attributeMap:` shape:

```yaml
attributeMap:
  - external: <inbound field path>  # e.g. "subject", "from.email", "fields.summary"
    internal: <attribute name>      # must exist in the app's attributes
```

The field path interpretation is connector-specific (email field names,
form field names, Jira/Zendesk field paths).

