「HubSpotのデータを外部システムと連携したい」「定型的な処理をAPIで自動化したい」——こうしたニーズが出てきたとき、最初の一歩となるのがHubSpot APIの理解です。
HubSpot APIとは、HubSpotのCRMデータや各種機能にプログラムからアクセスするためのインターフェースです。RESTful APIとして提供されており、コンタクト・会社・取引などのCRMオブジェクトの作成・取得・更新・削除(CRUD)や、マーケティング・セールス機能の操作が可能です。
この記事では、HubSpot APIの認証方法からコンタクト取得・取引操作の基本まで、実際のコード例付きで解説します。
出典: HubSpot Developers (developers.hubspot.com)
HubSpot APIは、大きく以下のカテゴリに分かれています。
| カテゴリ | 主なAPI | 用途 |
|---|---|---|
| CRM API | Contacts, Companies, Deals, Tickets | CRMオブジェクトのCRUD |
| CMS API | Blog Posts, Pages, Templates | ウェブサイト・ブログ管理 |
| Marketing API | Email, Forms, Campaigns | マーケティング施策管理 |
| Conversations API | Messages, Threads | チャット・メッセージ管理 |
| Automation API | Workflows | ワークフロー操作 |
HubSpot APIの公式ドキュメントは developers.hubspot.com で公開されています。各エンドポイントの仕様、リクエスト例、レスポンス例が記載されていますので、開発時には必ず参照いただくことをおすすめします。
出典: HubSpot Developers (developers.hubspot.com)
HubSpotでは以前「APIキー」による認証方式が提供されていましたが、2022年11月30日をもって廃止されました。現在は以下の2つの方式を使用します。
プライベートアプリは、自社内部での利用に最適な認証方式です。アクセストークンを発行し、APIリクエストのヘッダーに含めるだけで認証が完了します。
設定手順は以下のとおりです。
アクセストークンの使い方は以下のとおりです。
curl --request GET \
--url 'https://api.hubapi[dot]com/crm/v3/objects/contacts?limit=10' \
--header 'authorization: Bearer [YOUR_TOKEN]'
プライベートアプリでは必要最小限のスコープのみを付与いただくのがセキュリティ上のベストプラクティスです。例えばコンタクトの読み取りだけが必要な場合、crm.objects.contacts.readのみを選択します。
OAuthは、外部のサードパーティアプリや公開アプリで使用する認証方式です。ユーザーの同意を得た上でアクセストークンを取得するフローになります。
社内ツールや自社の管理スクリプトであれば、プライベートアプリの方がシンプルでおすすめです。マーケットプレイスに公開するアプリや、複数のHubSpotアカウントに対応する必要がある場合はOAuthを使用します。
| 認証方式 | 適するケース | 複雑さ |
|---|---|---|
| プライベートアプリ | 自社内部ツール、管理スクリプト、データ連携 | シンプル |
| OAuth 2.0 | 公開アプリ、マーケットプレイス、マルチアカウント対応 | やや複雑 |
Salesforceでいう「Connected App」に近い概念ですが、HubSpotのプライベートアプリの方が設定はシンプルかなと思います。
出典: HubSpot Developers (developers.hubspot.com)
コンタクト一覧を取得する基本的なAPIリクエストです。
curl --request GET \
--url 'https://api.hubapi[dot]com/crm/v3/objects/contacts?limit=10&properties=firstname,lastname,email,company' \
--header 'authorization: Bearer [YOUR_TOKEN]'
Pythonでの実装例:
import requests
BASE_URL = "https://api.hubapi[dot]com"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"
headers = {
"authorization": f"Bearer {ACCESS_TOKEN}",
"content-type": "application/json"
}
# コンタクト一覧取得
response = requests.get(
f"{BASE_URL}/crm/v3/objects/contacts",
headers=headers,
params={
"limit": 10,
"properties": "firstname,lastname,email,company"
}
)
data = response.json()
for contact in data.get("results", []):
props = contact.get("properties", {})
print(f"{props.get('firstname')} {props.get('lastname')} - {props.get('email')}")
propertiesパラメータで取得したいプロパティを指定します。指定しない場合はデフォルトのプロパティのみが返されます。
コンタクトIDまたはメールアドレスで特定のコンタクトを取得できます。
# IDで取得
contact_id = "12345"
response = requests.get(
f"{BASE_URL}/crm/v3/objects/contacts/{contact_id}",
headers=headers,
params={"properties": "firstname,lastname,email,phone,company"}
)
# メールアドレスで取得
email = "example@company.com"
response = requests.get(
f"{BASE_URL}/crm/v3/objects/contacts/{email}",
headers=headers,
params={
"idProperty": "email",
"properties": "firstname,lastname,email,company"
}
)
新しいコンタクトを作成するリクエストです。
new_contact = {
"properties": {
"firstname": "太郎",
"lastname": "山田",
"email": "taro.yamada@example.com",
"company": "サンプル株式会社",
"phone": "03-1234-5678"
}
}
response = requests.post(
f"{BASE_URL}/crm/v3/objects/contacts",
headers=headers,
json=new_contact
)
if response.status_code == 201:
print(f"コンタクト作成成功: ID={response.json()['id']}")
既存コンタクトのプロパティを更新します。
contact_id = "12345"
update_data = {
"properties": {
"company": "新会社名株式会社",
"lifecyclestage": "marketingqualifiedlead"
}
}
response = requests.patch(
f"{BASE_URL}/crm/v3/objects/contacts/{contact_id}",
headers=headers,
json=update_data
)
条件を指定してコンタクトを検索できます。
search_body = {
"filterGroups": [{
"filters": [{
"propertyName": "company",
"operator": "EQ",
"value": "サンプル株式会社"
}]
}],
"properties": ["firstname", "lastname", "email", "company"],
"limit": 20
}
response = requests.post(
f"{BASE_URL}/crm/v3/objects/contacts/search",
headers=headers,
json=search_body
)
検索APIには認証トークン1つにつき1秒あたり4リクエストという制限がありますので、大量の検索処理を行う場合はレート制限に注意が必要です。
response = requests.get(
f"{BASE_URL}/crm/v3/objects/deals",
headers=headers,
params={
"limit": 10,
"properties": "dealname,amount,dealstage,closedate,pipeline"
}
)
new_deal = {
"properties": {
"dealname": "サンプル株式会社 - CRM導入案件",
"amount": "1000000",
"dealstage": "appointmentscheduled",
"pipeline": "default",
"closedate": "2026-03-31T00:00:00.000Z"
}
}
response = requests.post(
f"{BASE_URL}/crm/v3/objects/deals",
headers=headers,
json=new_deal
)
HubSpotではオブジェクト間の関連付け(Association)が重要です。取引を作成したら、該当するコンタクトや会社と関連付けることで、データのリレーションが構築されます。
deal_id = "67890"
contact_id = "12345"
response = requests.put(
f"{BASE_URL}/crm/v3/objects/deals/{deal_id}/associations/contacts/{contact_id}/deal_to_contact",
headers=headers
)
複数のレコードを一度に処理する場合、バッチAPIを使用すると効率的です。各カテゴリのAPIには、1回のリクエストで最大10件のCRUD操作が可能なバッチコマンドが用意されています。
# コンタクトの一括作成
batch_contacts = {
"inputs": [
{
"properties": {
"firstname": "太郎",
"lastname": "田中",
"email": "tanaka@example.com"
}
},
{
"properties": {
"firstname": "花子",
"lastname": "鈴木",
"email": "suzuki@example.com"
}
}
]
}
response = requests.post(
f"{BASE_URL}/crm/v3/objects/contacts/batch/create",
headers=headers,
json=batch_contacts
)
大量のデータインポートが必要な場合は、API経由よりもHubSpotのインポート機能(CSVアップロード)を使った方が効率的なケースもあります。数百件程度ならAPI、数千〜数万件ならインポート機能を検討いただくのがいいかなと思います。
HubSpot APIには以下のレート制限があります。
| 項目 | 制限 |
|---|---|
| 標準API | プライベートアプリあたり1秒間に100リクエスト |
| 検索API | 認証トークンあたり1秒間に4リクエスト |
| バッチAPI | 1リクエストあたり最大10件 |
| 1日あたり | アカウントの契約プランによる |
レート制限に達すると429 Too Many Requestsエラーが返されます。大量処理を行う場合は、リクエスト間にスリープを入れるなどの制御が必要です。
| HTTPステータス | 原因 | 対処法 |
|---|---|---|
| 401 | 認証エラー(トークン無効) | トークンの有効期限・スコープを確認 |
| 403 | 権限不足 | プライベートアプリのスコープを確認 |
| 404 | 対象レコードが存在しない | IDの指定を確認 |
| 409 | 重複エラー(メールアドレス等) | 既存レコードを確認し更新に切替 |
| 429 | レート制限超過 | リクエスト間隔を空ける |
自社のカスタムフォームやLPからHubSpotにコンタクトを自動登録する仕組みです。フォーム送信時にAPIでコンタクト作成→ライフサイクルステージ設定→担当者割り当てまでを自動化できます。
ERPや販売管理システムとHubSpotの間で、顧客情報や取引データを同期します。定期的にAPIで差分データを取得・更新するバッチ処理を組むパターンが一般的です。
HubSpotのデータをAPIで取得し、BIツールやスプレッドシートに流し込んで独自のレポートを生成します。HubSpot標準のレポートでは不足する分析が必要な場合に有効です。
なお、iPaaS(YoomやZapierなど)を使えば、コードを書かずにHubSpotと外部システムを連携できる場合もあります。ノーコードで対応可能な範囲はiPaaSを活用し、複雑なロジックが必要な場合にAPIを使うという切り分けが効率的です。
HubSpot APIを活用することで、CRMデータの外部連携や業務の自動化が実現できます。
まずはプライベートアプリの作成とコンタクトの取得から始めて、段階的にAPIの活用範囲を広げていきましょう。CRMのデータを外部システムと連携できるようになると、業務全体の効率化と自動化の幅が大きく広がります。
HubSpot APIの利用自体は無料プランを含む全プランで可能です。ただし、プランによって利用できるAPIの範囲やレート制限が異なります。また、ワークフローやカスタムオブジェクトなど一部の機能はProfessional以上のプランで利用可能です。
自社内部のデータ連携やスクリプトであれば、プライベートアプリがシンプルでおすすめです。マーケットプレイスへの公開や、他社のHubSpotアカウントにアクセスする必要がある場合はOAuthを選択してください。
HubSpotは公式のクライアントライブラリとして、Python(hubspot-api-client)、Node.js(@hubspot/api-client)、Ruby、PHPを提供しています。どちらも十分に使えますが、データ処理やスクリプトにはPython、ウェブアプリケーションやリアルタイム処理にはNode.jsが向いているケースが多いかなと思います。
はい、APIによるプロパティ更新でもワークフローのトリガー条件に該当すればワークフローが発火します。大量データのインポートやバッチ更新を行う際は、意図しないワークフロー発火に注意が必要です。事前にテスト環境(サンドボックス)で確認いただくのがおすすめです。
リクエスト間に適切なスリープ(例:0.1秒)を入れる、バッチAPIを活用して1リクエストで複数レコードを処理する、検索APIの利用は1秒4リクエストを超えないよう制御するといった対策が有効です。