Разработчикам Кабинет

Сервисы в чате

Формы, подписки, поддержка и запись. Для запросов нужен токен вашего бота.

Идемпотентно отправить текст, карточку, форму или клавиатуруPOST /v1/bot/send

Пример запроса

// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/send", process.env.REG15_API_ROOT);
const response = await fetch(url, {
  method: 'POST',
  headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
  body: JSON.stringify({
  "conversationId": "30000000-0000-4000-8000-000000000003",
  "requestId": "50000000-0000-4000-8000-000000000005",
  "text": "Выберите уведомления",
  "botPayload": {
    "version": 1,
    "revision": "events-1",
    "buttons": [
      {
        "id": "subscribe",
        "text": "Подписаться",
        "subscription": {
          "topic": "events",
          "enabled": true
        }
      }
    ]
  }
}),
  signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.

Основные поля ответа

{
  "message": {
    "id": "40000000-0000-4000-8000-000000000004",
    "conversationId": "30000000-0000-4000-8000-000000000003",
    "sequence": 2,
    "text": "Выберите уведомления"
  }
}
Схема и правила повтора

Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.

Сохраните requestId до отправки. Повтор с тем же содержимым возвращает прежнее сообщение; изменённое содержимое конфликтует. После отзыва прав сохранённый успех не открывает диалог.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "conversationId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "text": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4096
    },
    "requestId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "botPayload": {
      "type": "object",
      "properties": {
        "version": {
          "type": "number",
          "const": 1
        },
        "revision": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        },
        "entities": {
          "maxItems": 100,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "bold",
                  "italic",
                  "underline",
                  "strikethrough",
                  "code",
                  "pre",
                  "text_link"
                ]
              },
              "offset": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "length": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "type",
              "offset",
              "length"
            ],
            "additionalProperties": false
          }
        },
        "expiresAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
        },
        "buttons": {
          "maxItems": 30,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64
              },
              "text": {
                "type": "string",
                "minLength": 1,
                "maxLength": 80
              },
              "subscription": {
                "type": "object",
                "properties": {
                  "topic": {
                    "type": "string",
                    "pattern": "^[a-z0-9_.-]{1,100}$"
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "topic",
                  "enabled"
                ],
                "additionalProperties": false
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "id",
              "text"
            ],
            "additionalProperties": false
          }
        },
        "keyboard": {
          "maxItems": 30,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64
              },
              "text": {
                "type": "string",
                "minLength": 1,
                "maxLength": 80
              },
              "subscription": {
                "type": "object",
                "properties": {
                  "topic": {
                    "type": "string",
                    "pattern": "^[a-z0-9_.-]{1,100}$"
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "topic",
                  "enabled"
                ],
                "additionalProperties": false
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "id",
              "text"
            ],
            "additionalProperties": false
          }
        },
        "card": {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "product",
                "service",
                "event"
              ]
            },
            "title": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "description": {
              "type": "string",
              "maxLength": 3000
            },
            "imageUrl": {
              "type": "string",
              "format": "uri"
            },
            "priceMinor": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000000000
            },
            "currency": {
              "type": "string",
              "const": "RUB"
            },
            "startsAt": {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
            },
            "timeZone": {
              "type": "string",
              "maxLength": 80
            }
          },
          "required": [
            "kind",
            "title"
          ],
          "additionalProperties": false
        },
        "form": {
          "type": "object",
          "properties": {
            "title": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "fields": {
              "minItems": 1,
              "maxItems": 20,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,63}$"
                  },
                  "label": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "text",
                      "number",
                      "select",
                      "date",
                      "time",
                      "file",
                      "consent"
                    ]
                  },
                  "required": {
                    "type": "boolean"
                  },
                  "options": {
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "value": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "label": {
                          "type": "string",
                          "maxLength": 120
                        }
                      },
                      "required": [
                        "value",
                        "label"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "min": {
                    "type": "number"
                  },
                  "max": {
                    "type": "number"
                  }
                },
                "required": [
                  "name",
                  "label",
                  "type"
                ],
                "additionalProperties": false
              }
            }
          },
          "required": [
            "title",
            "fields"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "version",
        "revision"
      ],
      "additionalProperties": false
    },
    "topic": {
      "type": "string",
      "pattern": "^[a-z0-9_.-]{1,100}$"
    }
  },
  "required": [
    "conversationId",
    "text",
    "requestId"
  ],
  "additionalProperties": false
}
Получить и подтвердить собственные события 15RegGET /v1/bot/events

Пример запроса

// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/events", process.env.REG15_API_ROOT);
url.search = new URLSearchParams({"offset":0,"limit":100,"timeout":10}).toString();
const response = await fetch(url, {
  method: 'GET',
  headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN},
  signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.

Основные поля ответа

{
  "items": [],
  "nextOffset": 0
}
Схема и правила повтора

Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.

Чередуйте с getUpdates в одном процессе. offset подтверждает только события этого потока. Сохраняйте offset после обработки; пустой ответ не подтверждает новую работу.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "offset": {
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "limit": {
      "default": 100,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "timeout": {
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 45
    }
  },
  "required": [
    "offset",
    "limit",
    "timeout"
  ],
  "additionalProperties": false
}
Получить UUID доступного диалога по совместимому числовому chat.idGET /v1/bot/chats/{chatId}

Пример запроса

// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/chats/100", process.env.REG15_API_ROOT);
const response = await fetch(url, {
  method: 'GET',
  headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN},
  signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.

Основные поля ответа

{
  "conversationId": "30000000-0000-4000-8000-000000000003"
}
Схема и правила повтора

Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.

Чтение можно повторить; каждый запрос заново проверяет доступ.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "chatId": {
      "type": "string",
      "pattern": "^\\d{1,16}$"
    }
  },
  "required": [
    "chatId"
  ],
  "additionalProperties": false
}
Передать доступный диалог сотруднику приложенияPOST /v1/bot/handoffs

Пример запроса

// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/handoffs", process.env.REG15_API_ROOT);
const response = await fetch(url, {
  method: 'POST',
  headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
  body: JSON.stringify({
  "conversationId": "30000000-0000-4000-8000-000000000003"
}),
  signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.

Основные поля ответа

{
  "caseId": "50000000-0000-4000-8000-000000000005",
  "state": "open"
}
Схема и правила повтора

Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.

Пока прежнее обращение открыто, повтор возвращает его caseId. После закрытия создаётся новое обращение. Ответ сотрудника идёт через его сессию в кабинете.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "conversationId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    }
  },
  "required": [
    "conversationId"
  ],
  "additionalProperties": false
}
Показать подтверждаемое предложение записи с ценой и временемPOST /v1/bot/booking-offers

Пример запроса

// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/booking-offers", process.env.REG15_API_ROOT);
const response = await fetch(url, {
  method: 'POST',
  headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
  body: JSON.stringify({
  "conversationId": "30000000-0000-4000-8000-000000000003",
  "communitySlug": "example",
  "requestId": "50000000-0000-4000-8000-000000000005",
  "booking": {
    "serviceId": "60000000-0000-4000-8000-000000000006",
    "resourceIds": [
      "70000000-0000-4000-8000-000000000007"
    ],
    "guests": 1,
    "startsAt": "2030-01-20T10:00:00+03:00",
    "durationMinutes": 60,
    "requestKey": "50000000-0000-4000-8000-000000000005"
  }
}),
  signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.

Основные поля ответа

{
  "offerId": "50000000-0000-4000-8000-000000000005",
  "messageId": "40000000-0000-4000-8000-000000000004",
  "expiresAt": "2030-01-01T10:15:00Z"
}
Схема и правила повтора

Действующий токен; запущенный доступный диалог; владелец приложения управляет выбранным заведением.

Повторяйте прежний requestId с прежними параметрами. Изменение параметров требует нового запроса и подтверждения. Предложение действует 15 минут; оно ещё не является бронью.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "conversationId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "communitySlug": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "booking": {
      "type": "object",
      "properties": {
        "resourceIds": {
          "minItems": 1,
          "maxItems": 8,
          "type": "array",
          "items": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "startsAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
        },
        "durationMinutes": {
          "type": "integer",
          "minimum": 15,
          "maximum": 720
        },
        "guests": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        },
        "serviceId": {
          "anyOf": [
            {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            {
              "type": "null"
            }
          ]
        },
        "requestKey": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        }
      },
      "required": [
        "resourceIds",
        "startsAt",
        "durationMinutes",
        "guests",
        "serviceId",
        "requestKey"
      ],
      "additionalProperties": false
    },
    "requestId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    }
  },
  "required": [
    "conversationId",
    "communitySlug",
    "booking",
    "requestId"
  ],
  "additionalProperties": false
}
Создать бронь только после действительного согласия пользователяPOST /v1/bot/booking-offers/{offerId}/confirm

Пример запроса

// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/booking-offers/OFFER_ID/confirm", process.env.REG15_API_ROOT);
const response = await fetch(url, {
  method: 'POST',
  headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
  body: JSON.stringify({
  "submissionId": "50000000-0000-4000-8000-000000000005"
}),
  signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.

Основные поля ответа

{
  "bookingId": "80000000-0000-4000-8000-000000000008",
  "requestId": "50000000-0000-4000-8000-000000000005",
  "booking": {
    "state": "pending"
  }
}
Схема и правила повтора

Действующий токен; запущенный доступный диалог; владелец приложения управляет выбранным заведением.

submissionId берите из form.submitted.v1, offerId — из предложения. Сервер повторно проверяет цену, срок и доступность. Повтор завершённой операции возвращает ту же бронь; изменившиеся условия требуют нового предложения.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "submissionId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    }
  },
  "required": [
    "submissionId"
  ],
  "additionalProperties": false
}
Готовые примеры