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

# Create IM Integration

> Connects a DingTalk, WeCom, Feishu or Slack bot to an agent

```
POST /openapi/memorylake/admin/v1/integrations
```

Connects a DingTalk, WeCom, Feishu or Slack bot to an agent. The integration is enabled at once and starts in status pending. DingTalk, Feishu and Slack credentials are verified with the platform before anything is saved (an access-token exchange or auth.test — no message is sent); WeCom credentials are checked by connecting, so follow status with [Get IM Integration](/features/memorylake/api-reference/integrations/get-integration). A bot can be connected only once. You also need write access to read\_write\_project\_id and search access to each read-only project.

<Note>
  **Permission required:** `workspace:integration_manage` on `workspace_id`

  * When you set `read_write_project_id`: `project:mem_add` on `read_write_project_id`
  * When you set `read_only_project_ids`: `project:mem_search` on `read_only_project_ids`
</Note>

### Headers

<ParamField header="Idempotency-Key" type="string">
  Optional. Retrying with the same value replays the first result instead of creating a second integration. Credential values are not compared.
</ParamField>

### Request Body

<ParamField body="agent_id" type="string" required>
  Agent that answers messages sent to the bot
</ParamField>

<ParamField body="channel" type="string" required>
  IM platform. Must be enabled on this deployment. One of: `dingtalk`, `wecom`, `feishu`, `slack`.
</ParamField>

<ParamField body="credentials" type="object" required>
  Write-only. dingtalk: appKey + appSecret; feishu: appId + appSecret; slack: botToken + appToken; wecom: botId + secret. DingTalk, Feishu and Slack credentials are verified with the platform before saving.

  <Expandable title="Integration Credentials object">
    <ParamField body="credentials.appId" type="string">Feishu: App ID. Identifies the bot; cannot change after creation.</ParamField>
    <ParamField body="credentials.appKey" type="string">DingTalk: Client ID (AppKey). Identifies the bot; cannot change after creation.</ParamField>
    <ParamField body="credentials.appSecret" type="string">DingTalk: Client Secret (AppSecret). Feishu: App Secret.</ParamField>
    <ParamField body="credentials.appToken" type="string">Slack: App-Level Token (xapp-…) with connections:write.</ParamField>
    <ParamField body="credentials.botId" type="string">WeCom: Bot ID of the intelligent robot. Identifies the bot; cannot change after creation.</ParamField>
    <ParamField body="credentials.botToken" type="string">Slack: Bot User OAuth Token (xoxb-…). Apps with token rotation enabled are not supported.</ParamField>
    <ParamField body="credentials.secret" type="string">WeCom: Secret of the intelligent robot.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="name" type="string" required>
  Display name
</ParamField>

<ParamField body="read_write_project_id" type="string" required>
  Project that memories extracted from IM conversations are written to. Anyone who can message the bot can add to it.
</ParamField>

<ParamField body="workspace_id" type="string" required>
  Workspace the integration belongs to. Cannot change later.
</ParamField>

<ParamField body="daily_message_limit" type="integer">
  Maximum messages handled per day; omit or 0 = unlimited
</ParamField>

<ParamField body="dataset_ids" type="array">
  Open-data datasets the agent may use
</ParamField>

<ParamField body="read_only_project_ids" type="array">
  Additional projects searched (read only). Must not repeat read\_write\_project\_id.
</ParamField>

<ParamField body="settings" type="object">
  Channel-specific settings

  <Expandable title="Integration Settings object">
    <ParamField body="settings.card_template_id" type="string">DingTalk only: AI card template id. Set it to stream replies into an interactive card; omit or send "" to reply with plain messages.</ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://app.memorylake.ai/openapi/memorylake/admin/v1/integrations' \
    -H 'Authorization: Bearer sk_xxxxxx' \
    -H 'Idempotency-Key: 7c1d2e3f-0a9b-4c8d-b7e6-f5a4d3c2b1a0' \
    -H 'Content-Type: application/json' \
    -d '{
      "agent_id": "010480e33a3f952c9d61c9f8d39bb410",
      "channel": "dingtalk",
      "credentials": {
        "appId": "example",
        "appKey": "example",
        "appSecret": "example",
        "appToken": "example",
        "botId": "example",
        "botToken": "example",
        "secret": "example"
      },
      "name": "Example name",
      "read_write_project_id": "b60e42e8ed8f4c1a4eca1eaa53ad7c90",
      "workspace_id": "9c542f78770f7e85ff018ddfc2c63541",
      "daily_message_limit": 1,
      "dataset_ids": [
        "3748f84ef0d2e877c0097b8f32d45cf0"
      ],
      "read_only_project_ids": [
        "5af1515af082229ccfd68f981a6cf886"
      ],
      "settings": {
        "card_template_id": "870213bad9d43369a8af134b1b482d6e"
      }
    }'
  ```
</RequestExample>

### Response

<ResponseField name="data" type="object">
  <Expandable title="Integration object">
    <ResponseField name="agent_id" type="string">Agent that answers messages sent to the bot</ResponseField>
    <ResponseField name="channel" type="string">IM platform. One of: `dingtalk`, `wecom`, `feishu`, `slack`.</ResponseField>
    <ResponseField name="created_at" type="integer">Creation time, Unix seconds</ResponseField>
    <ResponseField name="credentials_configured" type="boolean">Whether credentials are stored. Credentials themselves are write-only and never returned.</ResponseField>
    <ResponseField name="daily_message_limit" type="integer">Maximum messages this integration handles per day; 0 = unlimited</ResponseField>
    <ResponseField name="dataset_ids" type="array">Open-data datasets the agent may use</ResponseField>
    <ResponseField name="enabled" type="boolean">Whether the integration should be connected</ResponseField>
    <ResponseField name="external_app_id" type="string">The bot's identifier on the IM platform (DingTalk Client ID, Feishu App ID, WeCom Bot ID, Slack team:bot-user). Not a secret.</ResponseField>
    <ResponseField name="id" type="string">Identifier of the integration</ResponseField>
    <ResponseField name="name" type="string">Display name</ResponseField>
    <ResponseField name="read_only_project_ids" type="array">Additional projects searched (read only)</ResponseField>
    <ResponseField name="read_write_project_id" type="string">Project that memories extracted from IM conversations are written to</ResponseField>

    <ResponseField name="settings" type="object">
      Channel-specific settings

      <Expandable title="Integration Settings object">
        <ResponseField name="card_template_id" type="string">DingTalk only: AI card template id. Set it to stream replies into an interactive card; omit or send "" to reply with plain messages.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="status" type="string">Connection state. pending right after a create or a credential change until the first connection attempt; poll [Get IM Integration](/features/memorylake/api-reference/integrations/get-integration) to follow it. One of: `pending`, `connected`, `error`, `disabled`.</ResponseField>
    <ResponseField name="updated_at" type="integer">Last update time, Unix seconds</ResponseField>
    <ResponseField name="workspace_id" type="string">Workspace the integration belongs to. Fixed at creation.</ResponseField>
    <ResponseField name="status_error" type="string">Short normalized reason when status is error, for display (Chinese, the console's wording; it may change). Never contains the platform's raw response. Use status\_error\_code in programs.</ResponseField>
    <ResponseField name="status_error_code" type="string">Stable reason code, present whenever status\_error is. credentials\_invalid: the platform rejected the credentials (fix them); subscribe\_rejected: WeCom refused the subscription — wrong credentials or the platform's rate limit, retried automatically; preempted: another connection took over the bot, usually the same bot connected from another environment; timeout / disconnected / connection\_aborted / connection\_failed: connection problems, retried automatically; dependency\_unavailable: a service this deployment depends on is down, retried automatically; dependency\_misconfigured: this deployment lacks something the channel needs (WeCom needs Redis) — contact the operator; internal\_error: a fault on our side; unknown: the reason was recorded before codes existed, and is replaced on the next connection attempt. New codes may be added; treat an unrecognised one like connection\_failed.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json Success (201) theme={null}
  {
    "success": true,
    "message": "Operation completed successfully",
    "data": {
      "agent_id": "9926a90400d85f0a54e9e195e915db44",
      "channel": "dingtalk",
      "created_at": 1760000000,
      "credentials_configured": false,
      "daily_message_limit": 1,
      "dataset_ids": [
        "3748f84ef0d2e877c0097b8f32d45cf0"
      ],
      "enabled": true,
      "external_app_id": "524832f3cb1ba8ef33208d0692b8d565",
      "id": "f58008acc066bab6dfb73de8efde8905",
      "name": "Example name",
      "read_only_project_ids": [
        "5af1515af082229ccfd68f981a6cf886"
      ],
      "read_write_project_id": "aed31b20113b86ecc2587aa0cbc0eb2f",
      "settings": {
        "card_template_id": "870213bad9d43369a8af134b1b482d6e"
      },
      "status": "pending",
      "updated_at": 1760000000,
      "workspace_id": "ce55865bcc4c12c26161d24b238a888e",
      "status_error": "example",
      "status_error_code": "credentials_invalid"
    }
  }
  ```
</ResponseExample>

### Errors

Errors answer with `success: false`, a `message` and an `error_code`. See [Error Codes](/features/memorylake/api-reference/errors) for every code.

| Status | Meaning |
| - | - |
| `400` | A parameter or the body is invalid |
| `401` | The API key is missing, invalid, disabled or expired |
| `403` | The key is not allowed to do this |
| `404` | The resource does not exist |
| `409` | The request conflicts with the current state, e.g. a duplicate or a limit reached |
| `422` | The body or a parameter failed validation |
| `429` | Too many requests. Wait for the time in `Retry-After` |
| `500` | Server-side error |
| `503` | Temporarily unavailable. Retry later |


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