HubSpot APIの認証方式(プライベートアプリ・OAuth)の違いと設定方法。コンタクトの取得・作成・更新のAPI操作とコード例。
「HubSpotのデータを外部システムと連携したい」「定型的な処理をAPIで自動化したい」——こうしたニーズが出てきたとき、最初の一歩となるのがHubSpot APIの理解です。
HubSpot APIとは、HubSpotのCRMデータや各種機能にプログラムからアクセスするためのインターフェースです。RESTful APIとして提供されており、コンタクト・会社・取引などのCRMオブジェクトの作成・取得・更新・削除(CRUD)や、マーケティング・セールス機能の操作が可能です。
この記事では、HubSpot APIの認証方法からコンタクト取得・取引操作の基本まで、実際のコード例付きで解説します。 この分野の体系的な情報はHubSpot連携・エコシステムガイドでまとめています。
本記事は「HubSpotのデータ品質管理ガイド|Data Hubで実現するCRMデータクレンジングと運用ルール」シリーズの一部です。
本記事はHubSpotゴールドパートナーのStartLinkの「HubSpot完全ガイド」関連記事です。
この記事でわかること
- HubSpot APIの認証方式(プライベートアプリ・OAuth)の違いと設定方法 — HubSpot APIは、大きく以下のカテゴリに分かれています。
- コンタクトの取得・作成・更新のAPI操作とコード例 — コンタクト一覧を取得する基本的なAPIリクエストです。
- 取引(Deals)の操作方法 — response = requests.get(
- APIのレート制限と注意点 — よくある落とし穴と、それを回避するための具体的な対策を整理しています。
- 実務での活用パターン — 実際の活用シーンを交えて、実務で再現できるレベルで解説します。
HubSpotの取り組みを検討されている方に、
HubSpot APIの全体像
02
SECTION 02
HubSpot APIの全体像
APIの種類
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 で公開されています。各エンドポイントの仕様、リクエスト例、レスポンス例が記載されていますので、開発時には必ず参照いただくことをおすすめします。
認証方式|プライベートアプリとOAuth
03
SECTION 03
認証方式|プライベートアプリとOAuth
旧APIキーは廃止済み
HubSpotでは以前「APIキー」による認証方式が提供されていましたが、2022年11月30日をもって廃止されました。現在は以下の2つの方式を使用します。
方式1:プライベートアプリ(Private App)
プライベートアプリは、自社内部での利用に最適な認証方式です。アクセストークンを発行し、APIリクエストのヘッダーに含めるだけで認証が完了します。
設定手順は以下のとおりです。
- HubSpotにログインし、歯車マーク(設定)をクリック
- 左メニューから「連携」→「プライベートアプリ」を選択
- 「プライベートアプリを作成」をクリック
- アプリ名を入力し、必要なスコープ(権限)を選択
- 「アプリを作成」をクリックしてアクセストークンを取得
アクセストークンの使い方は以下のとおりです。取得したトークンをHTTPリクエストのAuthorizationヘッダーにBearer {トークン}の形式で設定します。
プライベートアプリでは必要最小限のスコープのみを付与いただくのがセキュリティ上のベストプラクティスです。例えばコンタクトの読み取りだけが必要な場合、crm.objects.contacts.readのみを選択します。
方式2:OAuth 2.0
OAuthは、外部のサードパーティアプリや公開アプリで使用する認証方式です。ユーザーの同意を得た上でアクセストークンを取得するフローになります。
社内ツールや自社の管理スクリプトであれば、プライベートアプリの方がシンプルでおすすめです。マーケットプレイスに公開するアプリや、複数のHubSpotアカウントに対応する必要がある場合はOAuthを使用します。
| 認証方式 |
適するケース |
複雑さ |
| プライベートアプリ |
自社内部ツール、管理スクリプト、データ連携 |
シンプル |
| OAuth 2.0 |
公開アプリ、マーケットプレイス、マルチアカウント対応 |
やや複雑 |
Salesforceでいう「Connected App」に近い概念ですが、HubSpotのプライベートアプリの方が設定はシンプルです。
コンタクトAPIの基本操作
コンタクト一覧の取得
コンタクト一覧を取得する基本的なAPIリクエストです。
import requests
BASE_URL = "https://api.hubapi.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リクエストという制限がありますので、大量の検索処理を行う場合はレート制限に注意が必要です。
HubSpotのAPIリファレンスドキュメント。エンドポイントの仕様を確認できます。
取引(Deals)APIの操作
05
SECTION 05
取引(Deals)APIの操作
取引一覧の取得
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、数千〜数万件ならインポート機能を検討いただくのがおすすめです。
APIのレート制限と注意点
レート制限
HubSpot APIには以下のレート制限があります。
| 項目 |
制限 |
| 標準API |
プライベートアプリあたり1秒間に100リクエスト |
| 検索API |
認証トークンあたり1秒間に4リクエスト |
| バッチAPI |
1リクエストあたり最大10件 |
| 1日あたり |
アカウントの契約プランによる |
レート制限に達すると429 Too Many Requestsエラーが返されます。大量処理を行う場合は、リクエスト間にスリープを入れるなどの制御が必要です。
よくあるエラーと対処法
| HTTPステータス |
原因 |
対処法 |
| 401 |
認証エラー(トークン無効) |
トークンの有効期限・スコープを確認 |
| 403 |
権限不足 |
プライベートアプリのスコープを確認 |
| 404 |
対象レコードが存在しない |
IDの指定を確認 |
| 409 |
重複エラー(メールアドレス等) |
既存レコードを確認し更新に切替 |
| 429 |
レート制限超過 |
リクエスト間隔を空ける |
セキュリティ上の注意
- アクセストークンをソースコードに直接記述しない(環境変数やシークレット管理を使用)
- 不要になったプライベートアプリは削除する
- 必要最小限のスコープのみを付与する
- 本番データに対する操作は十分テストしてから実行する
実務での活用パターン
パターン1:外部フォームからのリード取り込み
自社のカスタムフォームやLPからHubSpotにコンタクトを自動登録する仕組みです。フォーム送信時にAPIでコンタクト作成→ライフサイクルステージ設定→担当者割り当てまでを自動化できます。
パターン2:基幹システムとのデータ同期
ERPや販売管理システムとHubSpotの間で、顧客情報や取引データを同期します。定期的にAPIで差分データを取得・更新するバッチ処理を組むパターンが一般的です。
パターン3:レポート・ダッシュボードの自動生成
HubSpotのデータをAPIで取得し、BIツールやスプレッドシートに流し込んで独自のレポートを生成します。HubSpot標準のレポートでは不足する分析が必要な場合に有効です。
なお、iPaaS(YoomやZapierなど)を使えば、コードを書かずにHubSpotと外部システムを連携できる場合もあります。ノーコードで対応可能な範囲はiPaaSを活用し、複雑なロジックが必要な場合にAPIを使うという切り分けが効率的です。
まとめ
- HubSpot APIを活用することで、CRMデータの外部連携や業務の自動化が実現できます
- 1. 認証:プライベートアプリでアクセストークンを発行(社内利用はこれで十分) 2. 基本操作:GET/POST/PATCHでCRMオブジェクトのCRUD 3. 検索:Search APIで条件指定のデータ取得 4. バッチ処理:複数レコードの一括操作で効率化 5. 関連付け:オブジェクト間のAssociationでデータのリレーション構築
- まずはプライベートアプリの作成とコンタクトの取得から始めて、段階的にAPIの活用範囲を広げていきましょう
- CRMのデータを外部システムと連携できるようになると、業務全体の効率化と自動化の幅が大きく広がります
あわせて、HubSpotで多言語サイト構築・グローバル展開、HubSpotとLINE公式アカウントを連携する方法、HubSpot×Zoom/Teams連携(ウェビナー含む)なども参考にしていただければと思います。
よくある質問(FAQ)
Q1. HubSpot APIを使うのに追加費用はかかりますか?
HubSpot APIの利用自体は無料プランを含む全プランで可能です。ただし、プランによって利用できるAPIの範囲やレート制限が異なります。また、ワークフローやカスタムオブジェクトなど一部の機能はProfessional以上のプランで利用可能です。
Q2. プライベートアプリとOAuth、どちらを選ぶべきですか?
自社内部のデータ連携やスクリプトであれば、プライベートアプリがシンプルでおすすめです。マーケットプレイスへの公開や、他社のHubSpotアカウントにアクセスする必要がある場合はOAuthを選択してください。
Q3. PythonとNode.js、どちらが適していますか?
HubSpotは公式のクライアントライブラリとして、Python(hubspot-api-client)、Node.js(@hubspot/api-client)、Ruby、PHPを提供しています。どちらも十分に使えますが、データ処理やスクリプトにはPython、ウェブアプリケーションやリアルタイム処理にはNode.jsが向いているケースが多くなっています。
Q4. APIでデータを更新する際、ワークフローは発火しますか?
はい、APIによるプロパティ更新でもワークフローのトリガー条件に該当すればワークフローが発火します。大量データのインポートやバッチ更新を行う際は、意図しないワークフロー発火に注意が必要です。事前にテスト環境(サンドボックス)で確認いただくのがおすすめです。
Q5. レート制限に引っかからないようにするには?
リクエスト間に適切なスリープ(例:0.1秒)を入れる、バッチAPIを活用して1リクエストで複数レコードを処理する、検索APIの利用は1秒4リクエストを超えないよう制御するといった対策が有効です。