C cenaly.com
無料で始める

パブリックAPIとWebhook

権限付きキー、リード・プロパティ・イベント・チャット・セグメント用REST API、新規リードとイベントのWebhook — curlサンプル付き

3 min read 管理画面のデモ
On this page 9

公開APIとウェブフック

REST APIを使うと、お使いのCRM、サイトのバックエンド、独自のボットが、管理画面と同じようにcenaly.comのリードと会話を操作できます。カードの読み取り、プロパティの変更、イベントの送信、会話への返信が可能です。一方ウェブフックは、新しいリード、イベント、メッセージをサーバーへ自動的に通知します。

始めるために必要なもの#

項目 場所
ロール アカウントのオーナー — キーはオーナーの名義で動作します。従業員はキーを表示できません
セクション 有効なチャット(リードと会話はその中に存在します)
キー インテグレーション → APIとウェブフック → キー → キーを作成
APIアドレス https://api.cenaly.com/public-api/v1
メソッドリファレンス api.cenaly.com/public-api/v1/docs
OpenAPI 3.1 api.cenaly.com/public-api/v1/openapi.json

ステップ1. キーと権限#

  1. インテグレーションを開き、ページ上部のAPIとウェブフックをクリックします。
  2. キータブでキーを作成をクリックし、名前を入力します(「CRM」「サイトのバックエンド」「Telegramボット」)。
  3. 権限セットを選択するか、権限を個別にチェックします。複数の店舗がある場合はキーが許可される店舗と有効期限を指定します。
  4. シークレットcnk_…をコピーします。表示されるのは一度だけです。当社にはそのフィンガープリント(SHA-256)のみが保存されます。
権限 できること
contacts:read リードの一覧、検索、カード、プロパティ
contacts:write プロパティとタグの変更、統合、データ主体の請求に基づく削除
events:read リードのイベントフィード
events:write イベントの送信(購入、登録、任意の独自イベント)
conversations:read 会話とメッセージ
conversations:write オペレーターの返信、メモ、ステータス、担当者、ラベル
messages:send リードの最後の会話へのメッセージ送信
segments:read 保存済みセグメントとそのメンバー

セット: CRM / バックエンド(リード、プロパティ、イベント、会話とセグメントの読み取り)、独自ボット(リードの読み取り、会話への返信、リードへの書き込み)、読み取り専用、すべて。

  • 権限はキーの権限と店舗をオンザフライで変更します — インテグレーションは動作を続けます。
  • 再発行は新しいシークレットを発行します。古いシークレットは即座に動作しなくなり、権限とジャーナルは保持されます。
  • 取り消しは即座かつ永久です。次のリクエストは401を受け取ります。

キーはAuthorization: Bearer cnk_…ヘッダー(またはX-Api-Key: cnk_…)で送信します。ブラウザやモバイルアプリではなく、サーバー上でのみ保管してください。

ステップ2. 最初のリクエスト#

KEY=cnk_ваш_ключ
API=https://api.cenaly.com/public-api/v1

# что умеет ключ: права, точки, лимит
curl -H "Authorization: Bearer $KEY" "$API/me"

# лиды, свежие сверху (20 на страницу)
curl -H "Authorization: Bearer $KEY" "$API/contacts?limit=20"

# поиск по имени, почте или телефону
curl -H "Authorization: Bearer $KEY" "$API/contacts?q=anna"

レスポンスは常にエンベロープ形式です:

{
  "meta": { "status": 200, "requestId": "…", "nextCursor": "WyIyMDI2LTEwLTA0…" },
  "data": { "total": 128, "contacts": [ { "id": "…", "status": "lead", "name": "Анна", "updatedAt": "2026-10-04T09:12:00Z" } ] }
}

次のページは同じリクエストにcursor=<meta.nextCursor>を付けて取得します。nextCursorがなければページはそれ以上ありません。エラーは{"meta": {...}, "error": {"code": "…"}}です。

店舗。 キーが1つの店舗のみにアクセスできる場合、指定は不要です。複数の場合はlocation=<id точки>を追加します(一覧はGET /v1/locations)。指定しない場合、レスポンスは400 location_requiredです。

user_idによるプロパティとイベント。 当社のリードIDを保存する必要はありません。?by=user_idを追加すると、アドレスがお客様のユーザー識別子になります。そのuser_idのリードがまだ存在しない場合は、当社が作成します。

# свойства: операции update_or_create, set_once, add, delete, append, union, exclude
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"ops":[{"op":"update_or_create","key":"$email","value":"anna@example.com"},
              {"op":"add","key":"orders","value":1},
              {"op":"union","key":"interests","value":"yoga"}]}' \
  "$API/contacts/u-1001/props?by=user_id"

# события пачкой (до 100), повтор с тем же id засчитывается один раз
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"events":[{"id":"ord-5531","userId":"u-1001","name":"order_paid","props":{"sum":45,"currency":"GEL"}}]}' \
  "$API/events"

# ответ в диалоге и смена статуса
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"text":"Здравствуйте! Заказ передан курьеру."}' "$API/conversations/<id>/reply"
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"status":"resolved"}' "$API/conversations/<id>/status"

書き込みは管理画面からの編集と同じキューを経由します。変更は数秒で適用され、user_idによる書き込みへの応答はpending付きの202です。リードのカードでは、編集者は「API: <キー名>」として表示されます。

メソッド#

メソッド 実行内容 権限
GET /v1/me、GET /v1/locations キー、権限、店舗 —
GET /v1/contacts リード:status(anon、lead、user)、q、limit、cursor contacts:read
GET /v1/contacts/{id} カード:プロパティ、タグ、イベントの概要 contacts:read
POST /v1/contacts/{id}/props 操作によるプロパティ(最大250件)または {"props":{…}} contacts:write
POST / DELETE /v1/contacts/{id}/tags リードのタグ contacts:write
POST /v1/contacts/merge 2つのカードの統合:プレビュー、その後 "apply": true contacts:write
POST /v1/contacts/{id}/erase 本人からの請求による削除("confirm": true) contacts:write
GET /v1/contacts/{id}/events リードのイベントフィード events:read
POST /v1/contacts/{id}/events、POST /v1/events イベント(一度に最大100件) events:write
GET /v1/contacts/{id}/conversations リードの会話 conversations:read
POST /v1/contacts/{id}/messages リードの最新の会話にメッセージを送信 messages:send
GET /v1/conversations、/{id}、/{id}/messages 会話とメッセージ conversations:read
POST /v1/conversations/{id}/reply オペレーターの返信またはメモ("type": "note") conversations:write
POST /v1/conversations/{id}/status、/assign、/tags ステータス、担当者、ラベル conversations:write
GET /v1/segments、GET /v1/segments/{id}/contacts セグメントとその参加者 segments:read

各メソッドのフィールド、例、エラーコードはリファレンスをご覧ください。

ステップ3. ウェブフック#

ウェブフックは店舗ごとに設定します:チャット → 設定 → ウェブフック — https のアドレス、イベント、署名シークレット。会話のイベント(新しい会話、新しいメッセージ、ステータス、評価、ラベル)に加えて、リードのイベントが追加されました:

イベント 送信されるタイミング
lead.created 新しいリードが発生(チャットやフォームで連絡先が残された、または API 経由で登録された)
lead.props_changed リードのプロパティが変更 — キーの一覧は changedProps に含まれます
lead.event_tracked リードにイベントが発生。デフォルトではシステムイベント($…)を除くすべてのイベント。名前の一覧は「どのイベントを送信するか」フィールドで指定します
message.goal_reached リードがメッセージの目標を達成(ポップアップ、配信)
{
  "event": "lead.event_tracked",
  "deliveryId": "WD…",
  "at": "2026-10-04T09:12:03Z",
  "webhookId": "…",
  "locationId": "…",
  "contact": { "id": "…", "status": "user", "userId": "u-1001", "props": { "orders": 3 }, "tags": ["vip"] },
  "leadEvent": { "name": "order_paid", "at": "2026-10-04T09:12:00Z", "props": { "sum": 45 } }
}

リードの名前、メール、電話番号は、ウェブフックで「ゲストの連絡先を送信する」チェックボックスが有効な場合にのみ本文に含まれます。署名の検証は、ウェブフックのシークレットによる本文の HMAC-SHA256 です:

# заголовок X-Meni-Signature: sha256=<hex>
echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET"

5秒以内に 2xx を返してください。そうでない場合、配信は再試行されます。長期間の失敗が続くとウェブフックは無効になり、設定画面で確認できます。重複は deliveryId で排除してください。

制限#

  • キーごとに1分あたり60リクエスト。超過すると Retry-After ヘッダー付きの 429。残数は X-RateLimit-* に含まれます。
  • 1ページあたり最大 200 レコード(デフォルト50)、1バッチあたり最大 100 イベント、1リクエストあたり最大 250 プロパティ操作、一度に最大 30 タグ。
  • アカウントごとに最大 20 の有効なキー。
  • キーの呼び出し履歴は 30日間 保存されます:時刻、メソッド、パスパターン(id と本文を除く)、レスポンスコード、所要時間。
  • API 経由で送信されたイベントはリードのカード(フィード、概要、セグメント)に反映されますが、訪問分析の生ログには入りません。
  • リードへのメッセージ送信は既存の会話に対してのみ可能です。会話がない場合は 409 no_conversation が返ります。

トラブルシューティング#

レスポンス 意味 対処
401 api_key_missing / api_key_invalid リクエストにキーがない、またはキーが無効、失効、期限切れ ヘッダーを確認し、必要に応じてキーを再発行してください
403 scope_required キーに必要な権限がない キーの権限 — 権限を追加してください
400 location_required キーで複数の店舗にアクセスできる location=<id> を追加してください
404 location_not_found キーの店舗の中に該当する店舗がない GET /v1/locations で確認してください
404 not_found リードまたは会話がない 自分の id を使う場合は ?by=user_id を使用してください
429 rate_limited 1分あたり60リクエストを超過 Retry-After 秒待ち、イベントをバッチにまとめてください
502 upstream_error 一時的な障害 しばらくしてからリクエストを再試行してください

各リクエストは呼び出し履歴タブで確認できます — レスポンスコードとキー名が表示されます。

よくある質問#

ブラウザから API を呼び出せますか? いいえ。キーは店舗のすべてのリードへのアクセスを許可します。API はご自身のサーバーから呼び出してください。

user_id とリードの id はどう違いますか? リードの id はカードの当社の識別子です。user_id はお客様のユーザー識別子(CRM の番号、サイトのアカウント id)です。?by=user_id を使うと、その識別子でカードを指定できます。

イベントを再送信するとどうなりますか? 同じ id のイベントは1回だけカウントされます。ネットワークエラー時には安心してリクエストを繰り返せます。

店舗ごとに個別のキーが必要ですか? いいえ。1つのキーで複数の店舗を操作でき、店舗は location パラメータで選択します。

関連セクション#

Was this article helpful?