---
title: Moderation API
slug: moderation-api
icon: ▪️
docTags: 
createdAt: 2026-05-14T08:41:31.979Z
---

# Moderation API

The Moderation API lets you protect a bot from abusive traffic by managing IP-level bans from your own backend.

This functionality is intended for moderation and trust-and-safety workflows. By integrating these endpoints into your admin tools, you can ban the visitor behind a specific chat, lift bans your operators have issued, and audit which bans are actively rejecting traffic all without giving operators direct access to the Kindly dashboard.

## Getting started

The Moderation API uses the same authentication as the Application API, so if you've already set up an application for your bot you're ready to go — skip ahead to **Authorization** below. If not, follow the steps under [Application API](docId\:CgAd_bxmm1-WVggzsMd1k) first to create your application and obtain an API Key.

### Enable IP banning on your bot

Before any of the Moderation API endpoints will respond, the bot itself must have IP banning turned on.

1. From the dashboard of your Kindly bot, go to **Settings → Privacy & Security**.
2. Toggle **IP banning** on.
3. Save your changes.

With the flag on, the chatbubble starts recording the IP address of each visitor against their chat. The ban endpoint uses this history to resolve a chat\_id to the IP it should block, so bans issued before the flag was enabled may not have an IP to act on.

If the feature is off, every Moderation API endpoint rejects with 400 ip\_ban\_enabled is off for this bot.

### Authorization

With the API key in hand, you're ready to start issuing bans. Every request should include the header `Authorization: Bearer {{API_KEY}}`.

## Ban

To ban the visitor behind a chat your service can POST to api/v2/ban. The API resolves the chat's last-seen IP address and creates (or refreshes) a ban keyed on \{bot\_id, ip\_address}, so re-banning the same IP reuses the existing row.

**Example POST to Kindly**

:::BlockQuote
curl --request POST \\
&#x20; \--url https\://bot.kindly.ai/api/v2/ban \\
&#x20; \--header 'Content-Type: application/json' \\
&#x20; \--header 'Authorization: Bearer YOUR\_API\_KEY' \\
&#x20; \--data '\{
&#x20;   "chat\_id": "\<chat\_id>",
&#x20;   "reason": "spam",
&#x20;   "banned\_by\_agent\_id": "\<agent\_id>",
&#x20;   "expires\_at": "2026-06-01T00:00:00.000Z"
&#x20; }'
:::

**Response**

:::BlockQuote
\{
&#x20; "id": "\<ban\_id>",
&#x20; "chat\_id": "\<chat\_id>",
&#x20; "ip\_address": "\<ip\_address>",
&#x20; "reason": "spam",
&#x20; "banned\_by\_agent\_id": "\<agent\_id>",
&#x20; "banned\_at": "2026-05-14T08:30:00.000Z",
&#x20; "expires\_at": "2026-06-01T00:00:00.000Z"
}
:::

Returns 400 Cannot ban this chat: no IP recorded  if the chat has had no activity in the last 24 hours — ban a chat that has recent traffic.

## Unban

To lift a ban your service can POST to `api/v2/unban`  with the `chat_id`  the ban was created from. The API first resolves the chat's last-seen IP and deletes the ban by IP; if that lookup fails it falls back to the legacy `{bot_id, chat_id} ` tag, so unban remains idempotent even if the chat or its IP history is no longer available.

**Example POST to Kindly**

:::BlockQuote
curl --request POST \\
&#x20; \--url https\://bot.kindly.ai/api/v2/unban \\
&#x20; \--header 'Content-Type: application/json' \\
&#x20; \--header 'Authorization: Bearer YOUR\_API\_KEY' \\
&#x20; \--data '\{
&#x20;   "chat\_id": "\<chat\_id>"
&#x20; }'
:::

**Response**

:::BlockQuote
\{
&#x20; "chat\_id": "\<chat\_id>",
&#x20; "unbanned": \{
&#x20;   "ip\_address": "\<ip\_address>"
&#x20; }
}
:::

If no active ban matched the chat, `unbanned` is `null` and the response is still `200` — calling unban repeatedly is safe.

## List bans

To list every active ban for a bot your service can GET `api/v2/chat_bans`. Expired bans are filtered out server-side and results are sorted by `banned_at` descending. Each entry includes `blocked_count` (how many requests the ban has rejected) and `unique_blocked_browsers` (distinct browsers that have hit the ban), so you can see which bans are doing work.

**Example GET to Kindly**

:::BlockQuote
curl --request GET \\
&#x20; \--url https\://bot.kindly.ai/api/v2/chat\_bans \\
&#x20; \--header 'Authorization: Bearer YOUR\_API\_KEY'
:::

**Response**

:::BlockQuote
\{
&#x20; "bans": \[
&#x20;   \{
&#x20;     "id": "\<ban\_id>",
&#x20;     "ip\_address": "\<ip\_address>",
&#x20;     "reason": "spam",
&#x20;     "banned\_by\_agent\_id": "\<agent\_id>",
&#x20;     "banned\_at": "2026-05-14T08:30:00.000Z",
&#x20;     "expires\_at": "2026-06-01T00:00:00.000Z",
&#x20;     "chat\_id": "\<chat\_id>",
&#x20;     "blocked\_count": 17,
&#x20;     "unique\_blocked\_browsers": 3
&#x20;   }
&#x20; ]
}
:::



