Your AI Connector Docs

Contacts API

コンタクトとは、メッセージをやり取りする個人のことで、名前、電話番号、メールアドレス、チャネル、タグ、カスタムフィールド、およびそのコンタクトが属するリストやキャンペーンなどが含まれます。Contacts APIを使用すると、ダッシュボードを使わずに、コンタクトの作成、検索、更新、タグ付け、一括インポート、削除を行うことができます。

このページのすべてのパスは、ベースURLからの相対パスです:

https://api.youraiconnector.com/v1

したがって、/contacts は https://api.youraiconnector.com/v1/contacts を意味します。

APIを初めてお使いですか? まずAPIアクセスをお読みください。APIキーの生成方法、3つの認証方法、レート制限、エラー形式について説明しています。このページのすべての内容は、すでに有効なAPIキーをお持ちであることを前提としています。


コンタクトIDについて

すべてのコンタクトには一意のIDがあります。コンタクトを作成した際(data.contactId)に返されるIDは、他のすべての場所(コンタクトの取得、更新、タグ付け、メッセージ送信、削除など)で使用するIDと同じです。一度保存すれば、再利用可能です。

IDを取得するためにコンタクトを作成する必要はありません。電話番号やメールアドレスで検索する(コンタクトの取得を参照)、またはすべてのコンタクトをページ送りで確認する(コンタクトの一覧表示を参照)こともできます。いずれの場合も、同じIDが返されます。


コンタクトの作成

POST /contacts

アカウントに新しいコンタクトを追加します。国番号を含む電話番号が必須であり、メールアドレスのみでは不十分です。それ以外の項目はすべて任意です。

オプションとして、listId(単一のリスト)または listIds(配列)を使用して、新しいコンタクトを1つ以上のリストに直接追加できます。両方が送信された場合は、listIds が優先されます。

以下の連絡先の作成フィールドテーブルに記載されている標準的な作成フィールド(phoneNumber、firstName、lastName、email、channel、is_bot_active、is_private、lead_profile、listId、listIds、custom_fields)以外のフィールドを送信した場合、そのフィールドは自動的にカスタムフィールドとして保存されます。そのため、MakeやZapierのようなツールからのフラットなペイロードをネストせずにそのまま使用できます。明示的な custom_fields オブジェクトを渡すことも可能です。

フィールド 必須 説明
phoneNumber はい 国番号を含む連絡先の電話番号(例: +15551234567)。
firstName いいえ 名。
lastName いいえ 姓。
email いいえ メールアドレス。
channel いいえ メッセージングチャネル。whatsapp、sms、whatsapp_webのいずれか。デフォルトはwhatsapp。
is_bot_active いいえ AIアシスタントがこの連絡先に返信するかどうか。デフォルトはtrue。
is_private いいえ 連絡先をプライベートとしてマークします。trueの場合、AIアシスタントはその連絡先に対してオフになります。デフォルトはfalse。
lead_profile いいえ リードに関する自由記述のメモ。
listId いいえ 連絡先を追加する単一のリストID。
listIds いいえ 連絡先を追加するリストIDの配列(listIdよりも優先されます)。
custom_fields いいえ 独自のキー/値フィールドのオブジェクト。これらをトップレベルのキーとして渡すこともできます。型(日付、数値、ドロップダウン、チェックボックス)を持つフィールドは検証されます。詳細はカスタムフィールドの型を参照してください。

標準的な名称がない場合は、一般的な代替名称が受け入れられます。番号には phone または phone_number、名前には first_name および last_name、そして姓と名に分割される full_name または name が使用されます。したがって、Missing required fields: phoneNumber エラーはキーの綴りが異なっていたということではなく、電話番号の値がまったく届かなかったことを意味します。

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+15551234567",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "is_bot_active": true,
    "listIds": ["list123", "list456"]
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/contacts", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+15551234567",
    firstName: "Jane",
    lastName: "Smith",
    email: "jane@example.com",
    is_bot_active: true,
    listIds: ["list123", "list456"],
  }),
});
const data = await res.json();
console.log(data.data.contactId);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+15551234567",
        "firstName": "Jane",
        "lastName": "Smith",
        "email": "jane@example.com",
        "is_bot_active": True,
        "listIds": ["list123", "list456"],
    },
)
print(res.json()["data"]["contactId"])

レスポンス

{
  "success": true,
  "data": {
    "message": "Successfully created new contact",
    "contactId": "contact_abc123",
    "listsAdded": ["list123", "list456"]
  }
}

新しい連絡先のIDは data.contactId にあります。追加されたリストは data.listsAdded にエコーバックされます。

重複は作成されません。 作成先のチャネルに同じ電話番号を持つ連絡先が既に存在する場合、作成呼び出しによって2つ目が作成されることはありません。レスポンスはHTTPステータス 200 と本文内の error_code が 409 として返されるため、HTTPステータスではなく error_code で分岐してください。既存の連絡先のIDは contactId (および data.contactId )として返されるため、そのまま処理を続行できます。

{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user.", "contactId": "abc123", "data": { "contactId": "abc123" } }

これは、メールチャネルにおける重複するメールアドレスにも同様に適用されます。チームのシートから自身の連絡先のみが閲覧可能で、既存の連絡先がその中に含まれていない場合、IDは省略されます。その場合は、代わりに 電話番号またはメールアドレスで連絡先を取得 して検索してください。

WhatsAppの同等な表記は同一の番号としてカウントされます。 一部の国では、同じモバイル回線に対して2つの有効な表記が存在し、WhatsAppはいずれか一方を報告する場合があります。メキシコ(+52…およびレガシーな+521…)、ブラジル(9桁目の有無)、アルゼンチン(+54の後の9の有無)などがこれに該当します。作成時の重複チェックおよびGET /contacts?phoneNumber=は両方の表記で照合されるため、どちらの形式で送信しても既存の連絡先が返されます。連絡先に保存されているphone_numberが書き換えられることはありません。


電話番号またはメールアドレスによる連絡先の取得

GET /contacts?phoneNumber=... または GET /contacts?email=...

単一の連絡先を検索し、完全で詳細な連絡先オブジェクトを返します。これには、{ id, name } ペアに解決されたリスト、タグ、キャンペーン、および最後に行われたメッセージのやり取りが含まれます。

phoneNumber(国際形式)または email のいずれかを渡してください。どちらも渡さない場合、このエンドポイントは 連絡先リストの取得 モードに切り替わります。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?phoneNumber=%2B15551234567&apiKey=YOUR_API_KEY"

JavaScript

const phone = encodeURIComponent("+15551234567");
const res = await fetch(`https://api.youraiconnector.com/v1/contacts?phoneNumber=${phone}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"phoneNumber": "+15551234567"},
)
print(res.json()["contact"])

レスポンス

{
  "success": true,
  "contactId": "contact_abc123",
  "contact": {
    "id": "contact_abc123",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "phoneNumber": "+15551234567",
    "channel": "whatsapp",
    "isBotActive": true,
    "isPrivate": false,
    "doNotDisturb": false,
    "lead_profile": null,
    "avatarUrl": "https://example.com/photo.jpg",
    "customFields": {},
    "lists": [{ "id": "list123", "name": "VIP customers" }],
    "tags": [{ "id": "tagHotLead", "name": "Hot lead" }],
    "campaigns": [{ "id": "campaign789", "name": "Spring promo" }],
    "currentCampaign": { "id": "campaign789", "name": "Spring promo" },
    "lastMessage": {
      "direction": "inbound",
      "body": "Sounds good, thanks!",
      "status": "received",
      "timestamp": "2026-06-09T10:21:00.000Z"
    },
    "adAttribution": {
      "visit_at": "2026-06-09T10:14:02.000Z",
      "matched_at": "2026-06-09T10:14:20.000Z",
      "match_method": "reference",
      "reference": "4827",
      "fbc": "fb.1.1749463000000.IwAR...",
      "fbp": "fb.1.1749000000000.123456789",
      "fbclid": "IwAR...",
      "gclid": null,
      "gbraid": null,
      "wbraid": null,
      "utm_source": "facebook",
      "utm_medium": "paid",
      "utm_campaign": "spring-promo",
      "utm_content": null,
      "utm_term": null,
      "landing_url": "https://yoursite.com/quiz?utm_source=facebook&utm_campaign=spring-promo",
      "referrer": "https://l.facebook.com/",
      "client_ip": "203.0.113.7",
      "user_agent": "Mozilla/5.0 (iPhone; ...)",
      "site_key": "YOUR_SITE_KEY",
      "visit_id": "visit_abc123"
    }
  }
}

adAttribution は、広告クリックスクリプトによってこの連絡先に紐付けられた、あなたのウェブサイトへの誘導元となった広告のクリックです。該当するものがない場合は null となります。各フィールドについては WhatsApp の広告クリック属性 で説明されています。

連絡先IDは、トップレベル (contactId) とオブジェクト内 (contact.id) の両方で返されます。一致するものがない場合は、{ "success": false, "message": "Contact not found" } を含む 404 が返されます。

avatarUrl は、連絡先がWhatsAppやMetaからメッセージを送信した際に取得されるプロフィール写真です。これは読み取り専用であり、設定することはできません。また、写真が設定されていない連絡先や、写真を共有しないチャネル経由で連絡してきた連絡先の場合は null となります。これらの写真リンクの一部は期限切れとなり自動的に更新されるため、リンクを保存するのではなく、一時的なものとして扱ってください。(以下のリストエンドポイントでは、同じ値が avatar_url と呼ばれます。)

URL内の電話番号について。 クエリ文字列内の + 記号は %2B としてURLエンコードする必要があります。そうしないとスペースとして読み取られます。上記の例ではこれを行っています。


番号が非表示の連絡先

WhatsApp Webの連絡先は、WhatsAppがリンクされたデバイスに対して電話番号を非表示にしている場合、電話番号なしで届くことがあります(番号が非表示の連絡先を参照)。読み込まれるすべての連絡先には、これに対応する2つの追加フィールドが含まれています。number_hidden(単一の連絡先シェイプではnumberHidden)およびwhatsapp_lid(whatsappLid)です。

  • 番号が非表示の連絡先の場合、phone_numberはnull、number_hiddenはtrueとなり、whatsapp_lidには153055538446346@lid形式のWhatsApp内部IDが保持されます。これはダイヤル可能な番号ではありません。そのIDに基づいて独自のシステムで連絡先を照合し、このルックアップにphoneNumberとして渡すことで、再度連絡先を見つけることができます。
  • その他のすべての連絡先の場合、number_hiddenはfalseとなり、whatsapp_lidはWhatsAppが報告した連絡先のID、またはnullとなります。

連絡先を含むアウトバウンドWebhookや自動化ペイロードにも同じ3つのフィールドが含まれており、連絡先のCSVエクスポートには「電話番号」の横に「番号非表示」および「WhatsApp LID」列があります。WhatsAppが実際の番号を共有すると、連絡先は自動的に更新され、phone_numberが入力されます。

IDで連絡先を取得する

GET /contacts/{contactId}

連絡先のIDがすでにわかっている場合は、直接取得できます。レスポンスの形式は上記の検索と同じです。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["contact"])

アカウントに存在しない連絡先IDを指定すると、404が返されます。


コンタクトの統計を取得する

GET /contacts/{contactId}/stats

特定のコンタクトのメッセージ統計(合計、AI対人間の返信数、消費クレジット、最初/最後のメッセージのタイムスタンプ)を集計して返します。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.totalMessages, data.creditsUsed);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["totalMessages"], data["creditsUsed"])

レスポンス

{
  "success": true,
  "totalMessages": 48,
  "sent": 21,
  "received": 27,
  "aiReplies": 18,
  "humanReplies": 3,
  "creditsUsed": 34,
  "botMessageCount": 18,
  "firstMessageAt": "2026-05-01T09:00:00.000Z",
  "lastMessageAt": "2026-06-09T10:21:00.000Z"
}

botMessageCount は、アプリ内の「リセット」ボタンでゼロにリセットされるAIメッセージカウンターと同じものです。creditsUsed は、この応答の数値だけでなく、そのコンタクトの累積クレジット合計です。アカウントに存在しないコンタクトIDを指定すると、404 が返されます。


コンタクトのコストを取得する

GET /contacts/{contactId}/cost

1人のコンタクトが使用したクレジットを、会話(チャットセッション)ごと、アクションの種類ごとに分けて返します。また、AIのみが対応した会話と、チームが介入した会話の平均コストも返します。クライアントに会話のコストを提示する際にご利用ください。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.total_credits, data.by_session.length);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["total_credits"], data["summary"]["contained"]["avg_credits"])

レスポンス

{
  "success": true,
  "contact_id": "contact_abc123",
  "total_credits": 23,
  "refunded_credits": 0,
  "unattributed_credits": 0,
  "by_session": [
    {
      "session_id": "hpWKxuTSXIKlylze5Ulx",
      "start": "2026-09-21T00:00:00.000Z",
      "end": "2026-09-24T17:41:52.052Z",
      "status": "ChatSessionClosed",
      "tag": null,
      "credits": 7,
      "actions": 7,
      "outcome": "handed_off"
    },
    {
      "session_id": "5kKnkI3DD4THIh2YVjey",
      "start": "2026-09-09T00:00:00.000Z",
      "end": "2026-09-11T22:42:34.056Z",
      "status": "ChatSessionClosed",
      "tag": null,
      "credits": 13,
      "actions": 14,
      "outcome": "contained"
    }
  ],
  "by_type": [
    { "type": "AI Chat Conclude Evaluation", "credits": 8, "actions": 8 },
    { "type": "AI Tool Use", "credits": 4, "actions": 4 },
    { "type": "AI Message", "credits": 2, "actions": 2 }
  ],
  "summary": {
    "contained": { "sessions": 1, "credits": 13, "avg_credits": 13 },
    "handed_off": { "sessions": 1, "credits": 7, "avg_credits": 7 },
    "no_ai": { "sessions": 0, "credits": 0, "avg_credits": 0 }
  },
  "sessions_truncated": false
}

フィールドに関する注記:

  • total_credits は、コンタクトに対するすべての課金(AIの返信、ツール呼び出し、タグ付け、フォローアップ、要約、バックグラウンド評価ステップ、テンプレートおよび配信手数料)をカウントし、コンタクトへの返金を差し引いたものです。クレジットの付与、チャージ、更新はコンタクトには含まれません。プレイグラウンドでのテスト実行は除外されます。
  • 課金は、その課金が発生した期間の会話に割り当てられます。期間は会話の開始から終了まで、または次の会話が始まるまでとなるため、二重にカウントされることはありません。どの期間にも属さない課金は unattributed_credits に含まれます(合計にも含まれます)。
  • outcome: contained はAIが返信し、チームの誰も介入しなかったことを意味します。handed_off はAIの返信後に誰かがメッセージを送信したか、AIが人間に通知したことを意味します。no_ai はその会話でAIが一度も返信しなかったことを意味します。
  • 最大200件の会話が新しい順にリストされます。sessions_truncated は、それ以上存在する場合に true となります。
  • 代理店クライアントの場合は sub_account_id を渡してください。数値はそのクライアント自身のクレジットで表示されます。
  • コンタクト統計を取得 の creditsUsed は、コンタクト上で保持されている累積カウンターです。このエンドポイントはクレジット元帳から数値を再構築するため、特に古いコンタクトでは両者にわずかな差異が生じることがあります。
  • チームメンバーには請求権限が必要です。アカウントに存在しないコンタクトを指定すると 404 が返されます。503 は現在数値を計算できないことを意味するため、しばらくしてから再試行してください。

連絡先を一覧表示する

GET /contacts

phoneNumberもemailも指定せずにGET /contactsを呼び出すと、すべての連絡先を新しい順にページングして取得できます。各ページには連絡先のコンパクトな概要(リスト、タグ、キャンペーンは完全なオブジェクトではなくID配列として返されます)とnext_cursorが含まれます。

クエリパラメータ 説明
limit ページサイズ。デフォルトは50、最大100です。
cursor 前のページから取得したnext_cursorの値。最初のページでは省略します。
listId オプション。このリストに属する連絡先のみを返します。

すべてのページを順に取得するには、最初の呼び出しをカーソルなしで行い、その後は返されたnext_cursorをcursorとして渡し続けます。next_cursorがnullになったら停止してください。それが結果の終わりを意味します。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&apiKey=YOUR_API_KEY"

# next page:
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&cursor=contact_abc123&apiKey=YOUR_API_KEY"

JavaScript

async function listAllContacts() {
  const all = [];
  let cursor = null;
  do {
    const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts");
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);
    const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
    const data = await res.json();
    all.push(...data.contacts);
    cursor = data.next_cursor;
  } while (cursor);
  return all;
}

Python

import requests

def list_all_contacts():
    all_contacts = []
    cursor = None
    while True:
        params = {"limit": 100}
        if cursor:
            params["cursor"] = cursor
        res = requests.get(
            "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
            headers={"X-API-Key": "YOUR_API_KEY"},
            params=params,
        )
        data = res.json()
        all_contacts.extend(data["contacts"])
        cursor = data["next_cursor"]
        if not cursor:
            break
    return all_contacts

レスポンス

{
  "success": true,
  "contacts": [
    {
      "id": "contact_abc123",
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "phone_number": "+15551234567",
      "number_hidden": false,
      "whatsapp_lid": null,
      "channel": "whatsapp",
      "is_bot_active": true,
      "is_private": false,
      "do_not_disturb": false,
      "avatar_url": "https://example.com/photo.jpg",
      "custom_fields": {},
      "created_at": "2026-06-01T09:00:00.000Z",
      "list_ids": ["list123"],
      "tag_ids": ["tagHotLead"],
      "campaign_ids": ["campaign789"],
      "current_campaign_id": "campaign789",
      "ad_attribution": null
    }
  ],
  "next_cursor": "contact_abc123"
}

各連絡先には ad_attribution が含まれます。これは、あなたのウェブサイトへの誘導元となった広告のクリックであり、連絡先に紐付けられています。フィールドは ID で連絡先を取得 の adAttribution と同じですが、該当するものがない場合は null となります。

注: アカウントに存在しない listId でフィルタリングすると、404 が返されます。無効な cursor は 400 を返します。


コンタクトのカウント

GET /contacts/count

フィルタに一致するコンタクトの数と、チャネルごとの内訳を、ページングなしで取得します。ダッシュボードのタイル、自動化、Champへの問い合わせなど、「いくつあるか」を知りたいあらゆる場面でこの呼び出しを使用してください。すべてのフィルタはオプションであり、複数を組み合わせるとカウントが絞り込まれます(コンタクトは指定したすべての条件に一致する必要があります)。

クエリパラメータ 説明
agentId このAIエージェントに割り当てられたコンタクトのみ。割り当てられたエージェントがいないコンタクト(チャネルのデフォルトエージェントが対応するもの)には none を渡します。
channel このチャネル上のコンタクトのみ(例: whatsapp, messenger, instagram, sms, email, chat_widget)。
tag このタグを持つコンタクトのみ(タグの名前で指定、大文字・小文字は区別されません)。存在しないタグ名を指定すると 404 が返されます。
listId このリスト上のコンタクトのみ。
botActive true または false — AIアシスタントがオン、またはオフになっているコンタクトのみ。
status このステータスのコンタクトのみ(例: Lead)。
rules スマートリストと同じ形式のURLエンコードされたJSONルールオブジェクト(後述の「smart_rulesの形式」を参照)。他のフィルタと組み合わせることはできません。

フィルタを何も送信しない場合、アカウント上のコンタクトの総数が返されます。

cURL

# everything
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?apiKey=YOUR_API_KEY"

# only the contacts one agent handles on Messenger
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?agentId=agent_xyz789&channel=messenger&apiKey=YOUR_API_KEY"

JavaScript

const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count");
url.searchParams.set("agentId", "agent_xyz789");
url.searchParams.set("channel", "messenger");

const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
const data = await res.json();
console.log(data.total);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"agentId": "agent_xyz789", "channel": "messenger"},
)
data = res.json()
print(data["total"])

レスポンス

{
  "success": true,
  "total": 3423,
  "by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
  "filters": { "agentId": "agent_xyz789" }
}

by_channel は同じ合計数をチャネルごとに分割します。どのチャネルにも属さないコンタクトは none にカウントされます。filters は適用されたフィルタをそのまま返すため、呼び出しが意図通りに行われたかを確認できます。

注意: rules を他のフィルタと一緒に送信したり、有効なJSONではない rules 値を送信したりすると、400 が返されます。アカウントに存在しないタグ名やリストIDを指定すると 404 が返されます。


連絡先の更新

PUT /contacts/{contactId}

既存の連絡先を更新します。含めたフィールドのみが変更されます。変更したくないフィールドは除外してください。少なくとも1つのフィールドを送信する必要があります。そうしないと、400(「更新するフィールドがありません」)が返されます。

フィールド 説明
firstName 名。
lastName 姓。
email メールアドレス。
is_bot_active AIアシスタントがこの連絡先に返信するかどうか。
is_private プライベートとしてマークします。これをtrueに設定すると、AIアシスタントもオフになります。
do_not_disturb この連絡先への自動アウトリーチを一時停止します。AIによる返信も停止します。
follow_ups_disabled この連絡先に対するすべての自動フォローアップ(クイック、サイクル、コールドリード)を停止します。AIは送信されたメッセージへの返信を継続します。購入済みの場合などに便利です。falseに戻すまでオフのままになります。
lead_profile リードに関する自由記述のメモ。
custom_fields カスタムフィールドのオブジェクト。キーごとにマージされます。送信したキーのみが書き込まれ、既存のカスタムフィールドの残りは保持されます。カスタムフィールドのキーをトップレベルで渡すこともできます。型指定されたフィールドは検証され、不正な値の場合はfield_errorsでリクエストが拒否されます。詳細はカスタムフィールドの型を参照してください。

cURL

curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "firstName": "Jane", "do_not_disturb": true }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ firstName: "Jane", do_not_disturb: true }),
});
const data = await res.json();
console.log(data.message);

Python

import requests

res = requests.put(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"firstName": "Jane", "do_not_disturb": True},
)
print(res.json()["message"])

レスポンス

{
  "success": true,
  "message": "Contact updated successfully"
}

カスタムフィールドは置換ではなくマージされます。 { "custom_fields": { "tier": "gold" } } を送信すると tier のみが設定され、連絡先の他のカスタムフィールドはそのまま維持されます。すべての連絡先からカスタムフィールドを完全に削除するには、カスタムフィールドの削除を使用してください。


タグの追加または削除

POST /contacts/{contactId}/tags

1回の呼び出しで、単一の連絡先に対してタグの追加や削除を行います。addTagIds と removeTagIds にタグの ID を渡します。両方のうち少なくとも1つは空であってはなりません。

タグはあらかじめアカウントに存在している必要があります。タグエンドポイントから先に作成してください。連絡先または参照されたタグが存在しない場合、404 が返されます。

フィールド 説明
addTagIds コンタクトに追加するタグIDの配列。
removeTagIds コンタクトから削除するタグIDの配列。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"] }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    addTagIds: ["tagHotLead"],
    removeTagIds: ["tagColdLead"],
  }),
});
const data = await res.json();
console.log(data.added, data.removed);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"]},
)
data = res.json()
print(data["added"], data["removed"])

レスポンス

{
  "success": true,
  "contact_id": "contact_abc123",
  "added": 1,
  "removed": 1
}

タグライブラリを管理する

これらのエンドポイントは、連絡先に対してタグを適用または削除する(上記のタグの追加または削除を参照)のではなく、アカウント上のタグそのものを管理(名前の変更や削除)するためのものです。アカウント上のすべてのタグにはID(tagId)があります。これはダッシュボードのタグマネージャーに表示されるIDであり、POST /tagsを使用してJSONボディ{ "name": "..." }(phoneNumber、email、またはcontactIdは含みません)でタグを作成した際に、レスポンスのトップレベルでtag_idとして返されるIDです。

タグを更新する

PUT /tags/{tagId}

変更するフィールドのみを送信してください。

フィールド 説明
name タグの名前。
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagHotLead?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Hot lead (Q3)" }'

レスポンス

{ "success": true, "tag_id": "tagHotLead" }

アカウントに存在しない tagId を指定すると、404 が返されます。

タグを削除する

DELETE /tags/{tagId}

IDを指定してタグを1つ削除します。この操作は取り消せません。そのタグが付与されていたコンタクトからはタグが削除されます。すでに存在しない(または最初から存在しなかった)タグを削除しようとした場合、列挙するものがないため、404 ではなく deleted: 0 を含む 200 が返されます。

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"

レスポンス

{ "success": true, "deleted": 1 }

複数のタグを一度に削除する

DELETE /tags

フィールド 説明
tagIds 削除するタグIDの配列(最大1000個)。
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tagIds": ["tagColdLead", "tagUnsubscribed"] }'

レスポンス

{ "success": true, "deleted": 2 }

存在しないIDや別のアカウントに属するIDは、エラーにならずにスキップされ、deletedにはカウントされません。


フラグの一括設定

POST /contacts/bulk-flag

一度に多数のコンタクトに対して1つのブール値フラグを設定します。リクエストごとに最大500件のコンタクトIDを指定できます。アカウントに存在しないIDはスキップされ、skipped にカウントされます。

フィールド 説明
contactIds 更新するコンタクトIDの配列(最大500件)。
field 設定するフラグ。bot_active(AIアシスタントのオン/オフ)、dnd(自動アウトリーチの一時停止)、spam、private のいずれか。
value フラグに設定するブール値。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contactIds": ["contactId1", "contactId2"],
    "field": "bot_active",
    "value": false
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contactIds: ["contactId1", "contactId2"],
    field: "bot_active",
    value: false,
  }),
});
const data = await res.json();
console.log(data.updated, data.skipped);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contactIds": ["contactId1", "contactId2"],
        "field": "bot_active",
        "value": False,
    },
)
data = res.json()
print(data["updated"], data["skipped"])

レスポンス

{
  "success": true,
  "updated": 2,
  "skipped": 0
}

コンタクトの一括インポート

POST /contacts/import

JSON配列から1回の呼び出しで最大500件の連絡先を作成します。各レコードには国際形式の phone_number が必要です。それ以外の項目は任意です。電話番号が無効なレコードやサポートされていないチャネルのレコードはスキップ(作成されません)されます。スキップされたすべてのレコードは、インデックスと理由とともに報告されるため、失敗したレコードのみを修正して再試行できます。

アカウントに既に存在する電話番号は、デフォルトで duplicate としてスキップされます。しかし、listId を送信すると、既存の連絡先はそのリストに追加され、added_to_list としてカウントされるため、再インポートを行っても連絡先の情報は変更されません。代わりに updateExisting: true を送信して連絡先を 更新 してください。レコード内に存在するフィールドが連絡先の情報を上書きし(first_name、last_name、email、lead_profile、および custom_fields がキーごとにマージされます)、tags が追加され、連絡先が listId に追加されます。チャネル、電話番号、およびボットフラグは、既存の連絡先に対して変更されることはありません。

オプションで、インポート(または更新)されたすべての連絡先を listId を使用してリストに追加したり、指定のないレコードに対して defaultChannel を設定したり、tags を使用してレコードにタグ付けしたりできます(タグ名。存在しないタグは作成され、既存のタグは大文字と小文字を区別せずに照合されます)。

トップレベルフィールド

フィールド 必須 説明
contacts はい 連絡先レコードの配列(最大500件)。
listId いいえ このリクエスト内のすべての連絡先を追加するリスト。作成された連絡先、更新された連絡先、および重複としてスキップされた連絡先のすべてが対象です。アカウント上のリストである必要があります。
defaultChannel いいえ channel を省略したレコードに適用されるチャネル。whatsapp、sms、whatsapp_web のいずれか。デフォルトは whatsapp です。
updateExisting いいえ 電話番号が既に存在する連絡先を duplicate としてスキップする代わりに更新する場合は true を指定します。デフォルトは false です。

レコードごとのフィールド

フィールド 必須 説明
phone_number はい 国際形式の電話番号(不足している場合は先頭に + が追加されます)。
first_name いいえ 名。
last_name いいえ 姓。
email いいえ メールアドレス。
channel いいえ whatsapp、sms、whatsapp_web のいずれか。defaultChannel にフォールバックします。
is_bot_active いいえ AIアシスタントが返信するかどうか。デフォルトは true です。
is_private いいえ 非公開にするかどうか。デフォルトは false です。
lead_profile いいえ フリーテキストのリードメモ。
custom_fields いいえ カスタムフィールドのキーと値のオブジェクト。
tags いいえ タグ名の配列(単一の "a; b" 文字列も使用可能)。存在しないタグは作成され、既存のタグは大文字と小文字を区別せずに照合されます。1レコードにつき最大25個まで。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"] },
      { "phone_number": "+12025551235", "first_name": "Bob" }
    ],
    "listId": "list123",
    "defaultChannel": "whatsapp_web",
    "updateExisting": true
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contacts: [
      { phone_number: "+12025551234", first_name: "Ann", last_name: "Lee", tags: ["vip", "newsletter"] },
      { phone_number: "+12025551235", first_name: "Bob" },
    ],
    listId: "list123",
    defaultChannel: "whatsapp_web",
    updateExisting: true,
  }),
});
const data = await res.json();
console.log(`Imported ${data.imported}, updated ${data.updated}, skipped ${data.skipped.length}`);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contacts": [
            {"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"]},
            {"phone_number": "+12025551235", "first_name": "Bob"},
        ],
        "listId": "list123",
        "defaultChannel": "whatsapp_web",
        "updateExisting": True,
    },
)
data = res.json()
print(f"Imported {data['imported']}, updated {data['updated']}, skipped {len(data['skipped'])}")

レスポンス

{
  "success": true,
  "imported": 2,
  "contact_ids": ["contact_abc123", "contact_def456"],
  "updated": 0,
  "updated_contact_ids": [],
  "added_to_list": 0,
  "added_to_list_contact_ids": [],
  "skipped": []
}

一部のレコードが作成できない場合、その理由とともに skipped に表示されます(ここでは updateExisting がないため、既存の番号はスキップされます)。

{
  "success": true,
  "imported": 1,
  "contact_ids": ["contact_abc123"],
  "updated": 0,
  "updated_contact_ids": [],
  "added_to_list": 1,
  "added_to_list_contact_ids": ["contact_def456"],
  "skipped": [
    { "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
  ]
}

スキップされた行も listId に参加しており、これが added_to_list のカウント対象となります。その連絡先の他の情報は一切変更されません。updateExisting: true を使用した場合、同じリクエストで既存の連絡先は updated / updated_contact_ids として報告されます。

スキップされる理由:invalid_record、missing_phone_number、invalid_phone_number、invalid_channel、duplicate_in_request、duplicate、contact_limit_reached、create_failed。

プランの制限。 プランの連絡先上限によりこれほど多くの新規連絡先を作成できない場合、リクエスト全体が事前に403で拒否されます。途中で上限に達した場合、残りのレコードは理由contact_limit_reachedとしてスキップされた状態で返されます。


CSVファイルから連絡先をインポートする

一括インポートでサポートされている件数(最大約50,000行)を超えるインポートを行う場合は、アカウントのストレージに保存済みのCSVファイルに対して非同期インポートジョブをキューに入れ、完了するまでポーリングしてください。

インポートを開始する

POST /contacts/import-csv

フィールド 必須 説明
csvStoragePath はい users/{your account id}/imports/配下にある、.csvで終わるCSVファイルのストレージパス。
listName はい この名前のリストを作成(または再利用)し、インポートされたすべての連絡先を追加します。
existingListRefs いいえ インポートされたすべての連絡先を追加する既存のリストIDの配列。
defaultChannel いいえ 指定がない行に適用されるチャネル。
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "csvStoragePath": "users/abc123/imports/leads.csv",
    "listName": "Webinar signups"
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    csvStoragePath: "users/abc123/imports/leads.csv",
    listName: "Webinar signups",
  }),
});
const data = await res.json();
console.log(data.job_id);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "csvStoragePath": "users/abc123/imports/leads.csv",
        "listName": "Webinar signups",
    },
)
job_id = res.json()["job_id"]

レスポンス (202 — インポートはキューに入れられましたが、まだ完了していません)

{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "queued"
}

ストレージへのファイル配置について。 このエンドポイントはインポートジョブを開始および追跡するものであり、アップロード自体を受け付けるものではありません。このエンドポイントを呼び出す前に、CSVファイルがすでにcsvStoragePathに配置されている必要があります。ダッシュボードのCSVインポーターは、最初のステップとしてこれを行います。

インポートジョブをポーリングする

GET /contacts/import-csv/{jobId}

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv/csvimp_abc123?apiKey=YOUR_API_KEY"

レスポンス

{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "completed",
  "imported": 812,
  "updated": 0,
  "skipped": 14,
  "errors": [],
  "error_message": null
}

statusは、queued → processing → completedの順に遷移するか、error_messageに理由が示されてfailedとなります。アカウントに存在しないjobIdを指定すると、404が返されます。


連絡先をエクスポートする

連絡先の非同期CSVエクスポートを開始し、完了までポーリングするためのジョブを返します。

エクスポートを開始する

POST /contacts/export

フィールド 必須 説明
listId いいえ このリストに属する連絡先のみをエクスポートします。
contactIds いいえ 指定した特定の連絡先IDのみをエクスポートします。

両方を指定しない場合は、アカウント上のすべての連絡先がエクスポートされます。

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "listId": "list123" }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ listId: "list123" }),
});
const data = await res.json();
console.log(data.job_id);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"listId": "list123"},
)
job_id = res.json()["job_id"]

レスポンス (202 — エクスポートがキューに入れられました)

{
  "success": true,
  "job_id": "export_abc123",
  "status": "queued"
}

エクスポートジョブをポーリングする

GET /contacts/export/{jobId}

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"

レスポンス

{
  "success": true,
  "job_id": "export_abc123",
  "status": "completed",
  "export_id": "exp_xyz789",
  "contact_count": 812,
  "error_message": null
}

status が "completed" になると、export_id と contact_count が送信されます。生成されたCSVファイルのダウンロードは、ダッシュボードの「エクスポート」ページから行います。


連絡先にメッセージを送信する

POST /contacts/{contactId}/send-message

既存の連絡先が現在利用しているチャネルに対してメッセージを送信します。メッセージはキューに入れられ、バックグラウンドで配信されます。レスポンスはメッセージが受け付けられたことを示すものであり、配信が完了したことを示すものではありません。

フィールド 必須 説明
body はい 送信するメッセージのテキスト。
mediaUrl いいえ 添付するメディアファイルのURL。
mediaContentType いいえ 添付メディアのMIMEタイプ(例: image/jpeg)。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Hi! Your appointment is confirmed." }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ body: "Hi! Your appointment is confirmed." }),
});
const data = await res.json();
console.log(data.messageId);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"body": "Hi! Your appointment is confirmed."},
)
print(res.json()["messageId"])

レスポンス

{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact_abc123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}

今すぐ送信できませんか? 連絡先が「おやすみモード」や「プライベートモード」を有効にしている場合、またはアウトバウンドメッセージを受信できないチャネルを使用している場合、リクエストは 422 と説明用の error を伴って拒否されます。

連絡先IDではなく、電話番号、Instagram ID、またはその他のチャネル識別子を使用して送信する場合、およびメッセージング全般の詳細については、Messages API を参照してください。


連絡先にAIフォローアップを送信する

POST /contacts/{contactId}/ai-follow-up

これまでの会話とユーザーが与えた指示に基づき、AIエージェントが独自の口調でメッセージを1通作成し、その連絡先のチャネルに送信します。これはAIフォローアップを送信自動化ステップと同じものであり、AIフォローアップと同じクレジットを消費します。

フィールド 必須 説明
instruction はい メッセージで何を行うべきかを平易な言葉で記述します(最大2,000文字)。例: 「予約リンクが今夜期限切れになることを伝え、確定するかどうか尋ねる」
agentId いいえ メッセージを作成するエージェント。指定しない場合は、現在その連絡先を担当しているエージェントが使用されます。
mustContain いいえ メッセージに一言一句含める必要があるフレーズやリンクのリスト(最大5つ、各500文字まで)。AIがいずれかを含めなかった場合、メッセージは送信されず、skipReason が text_check_failed になります。
respectMessagingWindow いいえ デフォルトは true。WhatsApp Business API、Instagram、Messengerの場合、連絡先からの最後のメッセージが24時間以上経過しているときはスキップします。
skipWhenAiPaused いいえ デフォルトは true。この連絡先に対してAIがオフになっている場合はスキップします。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/ai-follow-up" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "Remind them their reserved link expires tonight and ask if they want to lock it in",
    "mustContain": ["https://example.com/r/abc123"]
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/ai-follow-up", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    instruction: "Remind them their reserved link expires tonight and ask if they want to lock it in",
    mustContain: ["https://example.com/r/abc123"],
  }),
});
const data = await res.json();
if (!data.sent) console.log("Skipped:", data.skipReason);

応答(メッセージが送信された場合):

{
  "sent": true,
  "messageId": "ai-follow-up-aB3dE5fG7hI9jK1l",
  "text": "Hi Ada, quick reminder: your reserved spot is held until 20:00 tonight. Want to lock it in? https://example.com/r/abc123",
  "agentId": "agent_abc123"
}

応答(スキップされた場合):

{
  "sent": false,
  "skipReason": "window_closed"
}

どちらもステータス 200 を返します。skipReason は no_agent(エージェントがコンタクトを処理せず、何も指定されなかった場合)、dnd(おやすみモード)、ai_paused、window_closed(24時間枠外、またはそのチャネルでコンタクトから連絡がなかった場合)、no_credits、text_check_failed(mustContain アイテムが不足している場合)、no_text(AIが使用可能な内容を生成しなかった場合)、または linkedin_gap(LinkedInリードに対して24時間以内に自動メッセージが送信された場合。この場合、回答には次に送信可能になる時刻を示す nextAllowedAt も含まれます)のいずれかです。スキップはエラーではなく通常の回答であるため、メッセージが送信されたと判断する前に sent を確認してください。スキップされた呼び出しではクレジットは消費されません。

instruction が欠落している、またはフィールドの型が間違っているボディには 400 が返されます。アカウント内に存在しない連絡先やエージェントを指定した場合は 404 が返されます。エラーは { "success": false, "error": "..." } として返されます。チームメンバーのキーには、連絡先に対する編集権限が必要です。


AIエージェントを連絡先に割り当てる

POST /contacts/{contactId}/assign-agent

既存の会話を、次のメッセージから別のAIエージェントに移動します。これはチャットメニューのAIエージェントを割り当てると同じ機能であり、オートメーションのAIエージェントを割り当てるアクションで使用されるステップと同じです。

フィールド 必須 説明
agentId はい 引き継ぐAIエージェントのID、または割り当てを解除して会話をチームインボックスに戻すための null を指定します。
triggerAIResponse いいえ true を指定すると、新しく割り当てられたエージェントが、連絡先の未回答の最新メッセージに対して即座に返信します。デフォルトは false です。連絡先がすでにこのエージェントに割り当てられており、最後のメッセージがすでに回答済みである場合、返信は開始されません。その際、レスポンスには aiResponseTriggered: false と、その理由を示す aiTriggerError が含まれます。

triggerAIResponse: true には注意してください — コンタクトに対してその場でメッセージを送信するため、今すぐメッセージを送りたい場合にのみ使用してください。MessengerやInstagramでは、コンタクトからの最後のメッセージから24時間以上経過している場合、メッセージの送信は失敗します。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "agent_xyz789" }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ agentId: "agent_xyz789" }),
});
const data = await res.json();
console.log(data.data.agentId);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"agentId": "agent_xyz789"},
)
print(res.json()["data"]["agentId"])

レスポンス

{
  "success": true,
  "data": {
    "contactId": "contact_abc123",
    "agentId": "agent_xyz789",
    "aiResponseTriggered": false
  }
}

エージェントは連絡先と同じアカウントに属している必要があります。そうでない場合、リクエストは 404 または 403 で拒否されます。エージェントIDは「AIエージェント」ページで確認できます(各エージェントのURLの末尾がIDになっています)。


多数のコンタクトへのAIエージェントの割り当て

POST /contacts/bulk-assign-agent

1回の呼び出しで多数の会話を別のAIエージェントに移動するか、null を使用してすべての割り当てを解除します。これは純粋なルーティングの変更であり、メッセージは送信されず、エージェントが誰かに返信することもありません。各コンタクトは、次にメッセージを送信した際に新しいエージェントが割り当てられます(そのため、ここには triggerAIResponse がありません)。

フィールド 必須 説明
agentId はい 引き継ぐAIエージェント、または割り当てを解除するための null。
contactIds 3つのうち1つ 移動する最大500件のコンタクトID。
filter 3つのうち1つ コンタクトをリストアップする代わりに、サーバー上で新しい順に選択します。カウントエンドポイントのフィルタと同じキーを使用します: agentId (または none), channel, tag, listId, botActive, status。
rules 3つのうち1つ スマートリストのルールオブジェクト — 「smart_rulesの形式」を参照してください。
limit いいえ filter または rules で選択した際に、この呼び出しで移動するコンタクトの数。1〜500で、デフォルトは500です。

contactIds、filter、rules のいずれか1つを正確に送信してください。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agent_xyz789",
    "filter": { "agentId": "agent_abc123", "channel": "messenger" }
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    agentId: "agent_xyz789",
    filter: { agentId: "agent_abc123", channel: "messenger" },
  }),
});
const data = await res.json();
console.log(data.updated, data.remaining);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "agentId": "agent_xyz789",
        "filter": {"agentId": "agent_abc123", "channel": "messenger"},
    },
)
data = res.json()
print(data["updated"], data["remaining"])

レスポンス

{
  "success": true,
  "agentId": "agent_xyz789",
  "matched": 3415,
  "updated": 500,
  "skipped": 0,
  "remaining": 2915,
  "filters": { "agentId": "agent_abc123" }
}

matched は選択によって見つかったコンタクトの総数、updated はこの呼び出しで移動された数、skipped は送信したIDのうちアカウントで見つからなかった数、remaining はこの呼び出し完了時点で条件に一致している残りの数です。

全員の移動について。 1回の呼び出しで移動できるのは最大500件のコンタクトであるため、大規模なグループの場合は数回の呼び出しが必要です。移動したコンタクトが条件に一致しなくなるようなフィルタ(例: agent_xyz789 に割り当てながら filter: { "agentId": "agent_abc123" } を使用するなど)を使用し、remaining が 0 として返されるまで全く同じ呼び出しを繰り返してください。contactIds を渡した場合、remaining は常に 0 になります。


連絡先を部門に割り当てる

POST /contacts/{contactId}/department

「このリードを営業に割り当てる」は、連絡先を指定した部門に登録し、デフォルトではその部門内で現在最も連絡先が少ない担当者に割り当てます。これはAIエージェントの割り当てとは別物です。部門は「どのチームが担当するか」を決定し、エージェントは「どのAIが対応するか」を決定します。一方を設定しても、もう一方がクリアされることはありません。

フィールド 必須 説明
department_id はい 連絡先を登録する部門。クリアするには null を渡します。
hand_to_member いいえ その部門で最も負荷の低い担当者にも連絡先を割り当てます。デフォルトは true です。すでに担当者がいる連絡先を再割り当てすることはありません。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "department_id": "dept_sales" }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ department_id: "dept_sales" }),
});
const data = await res.json();
console.log(data.assigned_to);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"department_id": "dept_sales"},
)
print(res.json()["assigned_to"])

レスポンス

{
  "success": true,
  "department_id": "dept_sales",
  "assigned_to": "member_uid_123"
}

連絡先がすでに誰かに割り当てられている場合、または hand_to_member: false を渡した場合、assigned_to は null になります。


チャネル間で連絡先をリンクする

「WhatsAppで継続」(またはSMS)は、別の電話ベースのチャネルでその人物の連絡先を検索または作成し、両者をリンクします。これにより、アプリの他の部分で同一人物として認識されるようになります。

別のチャネルへのリンク

POST /contacts/{contactId}/link-channel

フィールド 必須 説明
channel はい リンク先のチャネル。whatsapp、whatsapp_web、sms のいずれか。
phoneNumber いいえ 新しいチャネルで使用する電話番号。デフォルトはソース連絡先自身の番号です。
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link-channel?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "sms" }'

レスポンス

{
  "success": true,
  "data": {
    "contact_id": "contact_def456",
    "person_id": "person_xyz789",
    "created": true
  }
}

created は、ターゲットチャネル用に新しい連絡先が作成されたか、既存の連絡先が見つかってリンクされたかを示します。これを2回呼び出しても安全です。重複を作成するのではなく、同じ contact_id を created: false とともに返します。

422 は、現在アカウントがこのリンクを実行できないことを意味します。連絡先がすでにそのチャネルファミリーに存在している、使用する電話番号がない、またはターゲットチャネルに接続された送信者が存在しない場合です。 409 は、2つの連絡先がすでに別々の人物にリンクされていることを意味します。先に一方のリンクを解除してください。

連絡先のリンク済み会話を一覧表示する

GET /contacts/{contactId}/linked

この連絡先と同一人物である他の会話を返します。リンクされていない連絡先は 404 ではなく空の配列を返します。「この人物には他のチャネルがない」というのは正常な状態です。

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"

レスポンス

{
  "success": true,
  "data": [
    {
      "contact_id": "contact_def456",
      "channel": "sms",
      "custom_channel": null,
      "first_name": "Jane",
      "last_name": "Smith",
      "phone_number": "+15551234567",
      "last_message": "Sounds good, thanks!",
      "last_message_timestamp": "2026-06-09T10:21:00.000Z",
      "linked_from": {
        "contact_id": "contact_abc123",
        "channel": "whatsapp",
        "linked_at": "2026-06-01T09:00:00.000Z",
        "reason": "continue_on_channel"
      }
    }
  ]
}

連絡先のリンクを解除する

DELETE /contacts/{contactId}/link

この連絡先をその人物から一方的に削除します。その人物にリンクされている他の連絡先はリンクを維持するため、3つのうち1つのリンクを解除してもグループが解散されることはありません。

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"

レスポンス

{ "success": true }

連絡先のプロフィール画像を取得する

POST /contacts/{contactId}/profile-pic

連絡先のWhatsAppまたはMetaのプロフィール写真をオンデマンドで取得(およびキャッシュ)します。これは連絡先の取得でavatarUrlとして返される写真と同じもので、更新された状態のものです。

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"

レスポンス

{
  "success": true,
  "avatar_url": "https://example.com/photo.jpg",
  "cached": false
}

cached: true は、URLがプロバイダーへの新規ルックアップではなく、最近の取得から得られたものであることを意味します。写真は7日間キャッシュされ、プロバイダーが到達可能な写真がないと報告した連絡先は、24時間「利用不可」としてキャッシュされます。取得する写真がない場合、avatar_url は省略され、message にその理由が説明されます。


AIによる連絡先の自動タグ付け

アカウントのタグ付けルールを1つ以上の連絡先の全会話履歴に対して実行し、ライブチャット中に実行されるリアルタイムのタグ付けとまったく同じようにタグを適用(または削除)します。ルールやタグごとのクレジットコストも同様です。

実行を開始する

POST /contacts/auto-tag

フィールド 必須 説明
scope はい 特定の連絡先にタグを付ける場合は "contacts" を、1つのAIエージェントが現在処理しているすべての会話にタグを付ける場合は "agent" を指定します。
contact_ids scope が "contacts" の場合に必須 連絡先IDの配列(1〜500個)。
agent_id scope が "agent" の場合に必須 タグ付け対象の会話を持つAIエージェント。scope が "contacts" の場合、これはオプションとなり、実行するエージェントのタグ付けルールを絞り込むために使用されます。
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scope": "contacts", "contact_ids": ["contact_abc123", "contact_def456"] }'

単一の連絡先はインラインで実行され、結果がすぐに返されます:

{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }

2つ以上の連絡先(または scope: "agent")はバックグラウンドジョブとして実行され、すぐに 202 が返されます:

{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }

実行状況をポーリングする

GET /contacts/auto-tag/run

アカウントの現在(または最新)の実行状況を返します。これにより、run_id を自分で追跡することなく進捗状況をポーリングできます。

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"

レスポンス

{
  "success": true,
  "run": {
    "run_id": "m1x2y3-a1b2c3d4",
    "status": "running",
    "total": 214,
    "processed": 58,
    "tagged_contacts": 12,
    "tags_applied": 15,
    "tags_removed": 2,
    "credits_charged": 15
  }
}

アカウントで一度も実行が開始されていない場合、run は null になります。status は "running" から "completed" または "failed" へと移行します。

アカウントごとに一度に実行できるバルク実行は1つだけです。別の実行中に2つ目を開始すると、409 とともに error_code: "auto_tag_run_in_progress" が返されます。単一連絡先の実行でクレジットが不足すると、402 とともに error_code: "insufficient_credits" が返されます。一方、バルク実行の場合は途中で停止し、run にどこまで完了したかが報告されます。


連絡先を削除する

DELETE /contacts/{contactId}

IDを指定して連絡先を1件、メッセージ履歴とともに完全に削除します。この操作は取り消せません。 複数の連絡先を1回の呼び出しで削除するには、以下の 連絡先を削除 を使用してください。

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

レスポンス

{
  "success": true
}

アカウントに存在しない、または別のアカウントに属するコンタクトIDは、404を返します。


連絡先の削除

DELETE /contacts

1回の呼び出しで、IDを指定して1つ以上の連絡先を完全に削除します(最大500件まで)。アカウントに存在しないIDはスキップされ、skipped にカウントされます。この操作は元に戻せません。

フィールド 説明
contactIds 削除する連絡先IDの配列(最大500件)。

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contactId1", "contactId2"] }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts", {
  method: "DELETE",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ contactIds: ["contactId1", "contactId2"] }),
});
const data = await res.json();
console.log(`Deleted ${data.deleted}, skipped ${data.skipped}`);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contactId1", "contactId2"]},
)
data = res.json()
print(f"Deleted {data['deleted']}, skipped {data['skipped']}")

レスポンス

{
  "success": true,
  "deleted": 2,
  "skipped": 0
}

カスタムフィールドの一覧

GET /users/me/custom-fields — アカウントに登録されているカスタムフィールドのキー(列や問い合わせフォームに表示されるもの)を返します。これにより、インテグレーション側で推測する代わりに、選択肢として提供できるようになります。

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY"

レスポンス (200)

{ "success": true, "custom_fields": ["tier", "company", "birthday"] }

PUT /users/me/custom-fields を使用して、同じ配列形式でリストを設定します。


カスタムフィールドの削除

DELETE /contacts/custom-fields/{fieldKey}

アカウント内のすべての連絡先から、指定したカスタムフィールドキーを削除します。カスタムフィールドの名前変更や廃止後の整理にご利用ください。キーには英数字、アンダースコア、ハイフンのみを使用できます。更新された連絡先の数が返されます。この操作は取り消せません。

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(`Removed from ${data.updated} contacts`);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(f"Removed from {res.json()['updated']} contacts")

レスポンス

{
  "success": true,
  "updated": 42
}

注: サポートされていない文字を含むフィールドキーは、400 を返します。


カスタムフィールドの型

アカウント上のすべてのカスタムフィールドには型があります。text(デフォルト)、number、date、select(固定オプションを持つドロップダウン)、またはboolean(チェックボックス)です。型指定されたフィールドは、作成、更新、インポート、自動化エンジン、AI自身のフィールド収集など、書き込みのたびに検証されます。その値は標準化された形式で保存されるため、フィルターや自動化条件で値を比較できます。

型 保存形式 入力時に受け入れられる値
text 送信されたものすべて すべて(動作は変更されません)
number JSON数値 42、"42"、"19,99"
date "YYYY-MM-DD" 2026-02-01、ISO日時(日付部分が保持されます)、01/02/2026(アカウントの日付形式に従い、日または月が先頭になります。曖昧さのない値、例えば13/02/2026は常に有効です)、February 1, 2026、1 de febrero de 2026
select フィールドのオプションのいずれか(オプション自体の表記に従う) オプションの大文字小文字を区別しない一致
boolean true / false true/false、yes/no、1/0、si/no、ja/nein …

nullまたは空の文字列を送信すると、型指定されたフィールドがクリアされます。アカウントに登録されていないキーやtextフィールドは、送信された通りに保存されます。

フィールド定義の読み取り

GET /users/me/custom-fields

{
  "success": true,
  "custom_fields": ["company", "birthday", "plan", "vip"],
  "definitions": [
    { "key": "company", "type": "text" },
    { "key": "birthday", "type": "date" },
    { "key": "plan", "type": "select", "options": ["Free", "Pro", "Enterprise"] },
    { "key": "vip", "type": "boolean" }
  ]
}

custom_fieldsはキーの単純なリスト(古いクライアント向けに変更なし)であり、definitionsはキーごとの型を保持します。

フィールド定義の設定

PUT /users/me/custom-fields

リスト全体を置き換えます。各エントリは、単純なキー(フィールドが既に持つ型を保持し、新規の場合はtext)か、key、type、およびselectの場合はoptions(1〜100個のユニークなオプション、各最大64文字)を含むオブジェクトのいずれかです。最大50フィールドまで。キーには小文字、数字、アンダースコアを使用し、文字またはアンダースコアで開始する必要があります。

curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customFields": [
      "company",
      { "key": "birthday", "type": "date" },
      { "key": "plan", "type": "select", "options": ["Free", "Pro", "Enterprise"] },
      { "key": "vip", "type": "boolean" }
    ]
  }'

フィールドの型を変更しても、連絡先に既に保存されている値は書き換えられません。次に書き込まれる際に検証されます。

検証エラー

カスタムフィールドの値が型に適合しない連絡先の作成または更新は、全体として400で拒否されます。

{
  "success": false,
  "error": "Invalid custom field value(s): birthday: \"birthday\" must be a date in YYYY-MM-DD format (for example 1990-02-01).",
  "field_errors": [
    { "key": "birthday", "message": "\"birthday\" must be a date in YYYY-MM-DD format (for example 1990-02-01)." }
  ]
}

一括インポート時に不正な値を持つレコードは同じメッセージで失敗として報告され、バッチの残りのレコードは処理されます。


リスト

リストは連絡先をグループ化するものです。リストには静的(ユーザーがメンバーを決定する)なものと、スマート(ルールに基づいてメンバーが計算され、自動的に最新の状態に保たれるもの。詳細はリストと連絡先の整理を参照)なものがあります。

フィールド 説明
name 作成時に必須。最大100文字。
status live(デフォルト)または draft。小文字。
contact_ids リストに追加する連絡先IDの配列。静的リストのみ。
type static(デフォルト)または smart。
smart_rules ルールセット。type が smart の場合に必須。以下を参照。

リストを作成する

POST /lists

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Hot leads (active)",
        "type": "smart",
        "smart_rules": {
          "match": "all",
          "conditions": [
            { "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
            { "field": "last_activity_at", "op": "within_last", "value": { "amount": 90, "unit": "days" } }
          ]
        }
      }'

レスポンス

{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 3, "removed": 0, "total": 3 }
}

スマートリストは同じリクエスト内でインラインで評価されるため、evaluation によって最終的に誰がリストに含まれたかを正確に把握できます。静的リストの場合、evaluation は null となります。

リストを更新する

PUT /lists/{listId}

変更するフィールドのみを送信してください。smart_rules を変更すると、リストが即座に再評価され、同じ evaluation オブジェクトが返されます。

curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/list_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smart_rules": { "match": "any", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead", "tagWebinar"] } ] } }'

リストの種類は以下のように切り替えることができます:

  • 静的 → スマート: { "type": "smart", "smart_rules": { … } } を送信します。その場でルールが適用されます。
  • スマート → 静的: { "type": "static" } を送信します。ルールは破棄され、その時点でリストに存在するメンバーはそのまま維持されます。

smart_rules の形式

{
  "match": "all",
  "conditions": [
    { "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
    { "field": "channel", "op": "is_any", "value": ["whatsapp", "sms"] },
    { "field": "last_incoming_message_at", "op": "not_within_last", "value": { "amount": 7, "unit": "days" } },
    { "field": "created_at", "op": "after", "value": "2026-01-01" },
    { "field": "is_bot_active", "op": "is", "value": true },
    { "field": "email", "op": "is_set" },
    { "field": "custom_field", "key": "Plan", "op": "eq", "value": "pro" }
  ]
}
  • match — all(すべての条件が真である必要がある)または any(少なくとも1つが真である必要がある)。
  • conditions — 1〜20個の条件。各条件は最大100個の値、文字列は最大200文字まで。
field op value
tags has_any, has_all, has_none タグIDの配列
lists in_any, not_in_any リストIDの配列 (静的リストのみ — スマートリストからスマートリストを作成することはできません)
channel is_any, is_none チャネルの配列
status is_any, is_none コンタクトステータスの配列
created_at, last_activity_at, last_incoming_message_at, last_outgoing_message_at, first_ai_interaction_at, last_ai_interaction_at within_last, not_within_last { "amount": 1–3650, "unit": "hours" | "days" }
同一の日付フィールド before, after ISO日付 ("2026-01-01"、日単位で比較) または完全なISO日時 ("2026-01-01T14:30:00Z"、正確な時刻で比較)
同一の日付フィールド is_set, not_set —
has_interacted_with_ai is true / false — true AIが少なくとも1回(これまでに)メッセージを送信したコンタクトに一致します
is_bot_active, do_not_disturb, is_private, has_ever_responded is true / false
email, phone_number, first_name, last_name is_set, not_set, contains, not_contains contains フォーム用の文字列
current_campaign_id, assigned_agent is_any, is_none, is_set, not_set is_any / is_none フォーム用のID配列
custom_field (および key) eq, neq, contains, not_contains, is_set, not_set 値フォーム用の文字列

not_within_last は、日付が設定されていない連絡先(「N日以上前、または未設定」)にも一致し、テキスト比較では大文字と小文字が区別されません。

AIエンゲージメント。 has_interacted_with_ai はライフタイムフラグです。AIが少なくとも1通のメッセージを送信したすべてのコンタクトには true が、それ以外のすべてのコンタクト(チームのみが対応したコンタクトを含む)には false が付与されます。これはAIがコンタクトに最初のメッセージを送信した時点でスタンプされ、消去されることはありません。そのため、コンタクトのAI返信をオフにしたり、別のキャンペーンに移動したりしてもリセットされません。課金に関する一般的な質問である「今月AIが対応したコンタクト」のような期間については、代わりに last_ai_interaction_at の範囲を使用してください:

{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }

is_bot_active(AIに返信の許可があるかどうか、実際に返信したかどうかではない)や has_ever_responded(コンタクトが誰かに対して返信したかどうか)と混同しないでください。これら2つのスタンプは、すべてのコンタクトに対して first_ai_interaction_at / last_ai_interaction_at として返され、ルールセット全体は GET /contacts?rules= でも機能するため、リストを作成せずに一致数をカウントできます。

ルールセットをプレビューする

POST /lists/preview

ルールセットが一致する連絡先をカウントおよびサンプリングします。何も作成したり変更したりすることはありません。ルールを保存する前に、ルールが正しいか確認するために使用してください。

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/preview?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smart_rules": { "match": "all", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead"] } ] } }'

レスポンス

{
  "success": true,
  "count": 3,
  "sample": [
    {
      "id": "contact_abc123",
      "first_name": "Sofia",
      "last_name": "Martinez",
      "phone_number": "+31600000000",
      "email": "sofia@example.com",
      "channel": "whatsapp"
    }
  ]
}

sample には最大10件の連絡先が保持され、最近アクティブになった順に表示されます。

スマートリストを今すぐ再実行する

POST /lists/{listId}/evaluate

強制的に即時再評価を行います(ダッシュボードの [今すぐ更新] と同じ動作です)。スマートリストは、連絡先が変更された際や、時間ベースのルールの場合は15分ごとに自動的に更新されるため、この操作が必要になるのは、今すぐ結果を確認したい場合のみです。

レスポンス

{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 2, "removed": 1, "total": 4 }
}

evaluation.skipped: true は、同じリストの別の評価がすでに実行中であり、この呼び出しでは何も行われなかったことを意味します。

スマートリストは手動で選択されたメンバーを受け付けません

ターゲットリストがスマートリストである場合、メンバーシップエンドポイントは "This is a smart list — its members are computed from its rules. Edit the rules instead." を伴う 409 を返します。これには POST /contacts/lists、DELETE /contacts/lists、POST /contacts/lists/batch、contact_ids の POST /lists および PUT /lists/{listId}、そしてCSVインポートのターゲットとしてスマートリストを選択することが含まれます。代わりにルールを変更してください。

静的リストに対して POST /lists/{listId}/evaluate を呼び出すことも 409 となります。実行すべきルールが存在しないためです。


連絡先APIエラー

連絡先エンドポイントは、標準のエラーエンベロープを返します。

{
  "success": false,
  "error": "Contact not found"
}

一部のエンドポイントには error_code も含まれており、通常はHTTPステータスと一致します。唯一の例外は以下の連絡先の重複ケースで、HTTPステータスは 200 ですが、error_code のみが 409 を保持します。連絡先エンドポイント固有のコードは以下の通りです:

コード コンタクトエンドポイントで発生する場合
400 不正なリクエスト — フィールドの欠落/無効、空のボディ、不正なカーソル、またはバッチ内で500個を超えるID。
402 1件のコンタクトに対するAIタグ付け実行を完了するためのクレジットが不足しています (error_code: "insufficient_credits")。
404 コンタクト、リスト、またはタグがアカウントで見つかりませんでした。
409 その電話番号を持つコンタクトが既に存在します(作成時)。HTTPステータス200のボディ内でerror_codeとして返されるため、ここでerror_codeに基づいて分岐してください。また、一括自動タグ付けが既に進行中の場合(error_code: "auto_tag_run_in_progress")、またはコンタクトを別のチャネルにリンクすることで、既に異なる2人にリンクされている2つのコンタクトが結合されてしまう場合にも返されます。
422 コンタクトが現在メッセージを受信できません(おやすみモード、非公開、またはサポートされていないチャネル)。チャネルリンクエンドポイントでは、電話番号がない、サポートされていないチャネルの組み合わせ、またはターゲットチャネルに接続された送信者がいない場合も含まれます。

連絡先エンドポイントでの 403 は、プランのアクセス権限ではなく、連絡先制限やリストの権限に関する問題を示している可能性もあります。すべてのエンドポイントが返す共通コード(401、403(プランにAPIアクセスが含まれていない)、429(レート制限)、500)については、再試行のガイダンスとともに エラーとページネーション に記載されています。


次のステップ