3-1 Marketing & CMS API の全体像
Marketing Hub と CMS Hub に関連する API カテゴリを整理する。
Forms API
/marketing/v3/forms
Marketing
Email(Single Send)API
/marketing/v3/transactional/single-email/send
Marketing
Marketing Email API
/marketing/v3/emails
Marketing
Blog Posts API
/cms/v3/blogs/posts
CMS
Site Pages / Landing Pages API
/cms/v3/pages/site-pages | /landing-pages
CMS
HubDB API
/cms/v3/hubdb/tables
CMS
URL Mappings API
/cms/v3/url-mappings
CMS
スコープの注意:
Marketing API と CMS API はそれぞれ異なるスコープが必要です。
Private App 作成時に content・forms・transactional-email など、
使用する API に応じたスコープを付与してください。
3-2 Forms API — フォームの作成と送信データ取得
HubSpot フォームをプログラムで作成・管理し、送信データを取得・活用する。
Forms API エンドポイント
GET
/marketing/v3/forms
フォーム一覧を取得
GET
/marketing/v3/forms/{formId}
特定フォームの詳細を取得
POST
/marketing/v3/forms
新しいフォームを作成
PATCH
/marketing/v3/forms/{formId}
フォームを更新
POST
/submissions/v3/form-data/submit/{portalId}/{formGuid}
フォームにデータを送信(外部フォームからの連携)
GET
/form-integrations/v1/submissions/forms/{formGuid}
フォーム送信データを取得
Node.js — フォーム作成
import { Client }
from '@hubspot/api-client';
const client =
new Client({ accessToken: process.env.HUBSPOT_ACCESS_TOKEN });
const form =
await client.marketing.forms.formsApi.create({
formType:
'hubspot',
name:
'お問い合わせフォーム 2026',
configuration: {
language:
'ja',
cloneable:
false,
postSubmitAction: {
type:
'thank_you',
value:
'お問い合わせありがとうございました。',
},
},
fieldGroups: [
{
fields: [
{
fieldType:
'email',
name:
'email',
label:
'メールアドレス',
required:
true,
},
{
fieldType:
'text',
name:
'firstname',
label:
'お名前',
required:
true,
},
],
},
{
fields: [
{
fieldType:
'textarea',
name:
'message',
label:
'お問い合わせ内容',
required:
true,
},
],
},
],
});
console.log(
`Form created: ${form.id}`);
Node.js — 外部フォームから HubSpot に送信
async function submitToHubSpot(formGuid, data) {
const portalId = process.env.HUBSPOT_PORTAL_ID;
const url =
`https://api.hsforms.com/submissions/v3/integration/submit/${portalId}/${formGuid}`;
const response =
await fetch(url, {
method:
'POST',
headers: {
'Content-Type':
'application/json' },
body: JSON.stringify({
fields: [
{ objectTypeId:
'0-1', name:
'email', value: data.email },
{ objectTypeId:
'0-1', name:
'firstname', value: data.name },
{ objectTypeId:
'0-1', name:
'message', value: data.message },
],
context: {
pageUri: data.pageUrl,
pageName: data.pageName,
ipAddress: data.ipAddress,
},
}),
});
if (!response.ok)
throw new Error(
`Submit failed: ${response.status}`);
return await response.json();
}
Forms API と Submissions API:
フォームの構造管理には /marketing/v3/forms、
フォームへのデータ送信(外部フォームからの連携)には hsforms.com の Submissions エンドポイントを使います。
後者は Private App Token なしでも送信可能ですが、スパム対策のため IP アドレスや pageUri の送信を推奨します。
3-3 Transactional Email API — 単発メール送信
購入確認・パスワードリセットなどのトランザクションメールを API から送信する。
📧 Transactional Email の要件
Transactional Email API を使うには Marketing Hub Professional 以上 が必要です。
また、送信前に HubSpot のメールツールでトランザクションメールテンプレートを作成し、
そのメール ID を指定して送信します。スコープ transactional-email が必要です。
Node.js — Single Send Email
const result =
await client.marketing.transactionalApi.sendEmail({
emailId:
12345678,
message: {
to:
'customer@example.com',
cc: [
'support@mycompany.com'],
replyTo:
'noreply@mycompany.com',
sendId:
`order-confirm-${orderId}`,
},
contactProperties: {
firstname:
'太郎',
email:
'customer@example.com',
},
customProperties: {
order_id:
'ORD-2026-001',
order_amount:
'¥49,800',
product_name:
'Proプラン(年間)',
login_url:
'https://app.example.com/login',
},
});
console.log(
`Status: ${result.sendResult}`);
Node.js — sendId による重複送信防止
const sendId =
`order-${orderId}-confirm`;
try {
await client.marketing.transactionalApi.sendEmail({
emailId: CONFIRM_EMAIL_ID,
message: { to: customerEmail, sendId },
customProperties: { order_id: orderId },
});
}
catch (err) {
if (err.response?.status !==
409)
throw err;
console.log(
'Email already sent (duplicate sendId). Skipping.');
}
⚠ Marketing Email と Transactional Email の違い:
Marketing Email(一斉配信)はオプトアウトしたコンタクトには送信されません。
Transactional Email は商取引上必要なメール(購入確認・パスワードリセットなど)に限り、
オプトアウト済みのコンタクトにも送信されます。用途を厳守してください。
3-4 Blog Posts API — ブログ記事の管理
ブログ記事のプログラム作成・更新・公開スケジュール設定を行う。
Blog Posts API エンドポイント
GET
/cms/v3/blogs/posts
ブログ記事一覧(フィルター・ソート対応)
GET
/cms/v3/blogs/posts/{objectId}
特定記事を取得
POST
/cms/v3/blogs/posts
新しいブログ記事を作成(下書き)
PATCH
/cms/v3/blogs/posts/{objectId}
記事を更新
POST
/cms/v3/blogs/posts/{objectId}/draft/push-live
下書きを公開する
POST
/cms/v3/blogs/posts/schedule
公開日時をスケジュール設定
Node.js — ブログ記事の作成と公開
const post =
await client.cms.blogs.blogPostsApi.create({
name:
'HubSpot API 開発のベストプラクティス 2026',
contentGroupId:
BLOG_ID,
slug:
'hubspot-api-best-practices-2026',
metaDescription:
'HubSpot API を使った開発の最新ベストプラクティスを解説。',
postBody:
`
<h2>はじめに</h2>
<p>HubSpot API v3 では...</p>
`,
tagIds: [
TAG_ID_1,
TAG_ID_2],
featuredImage:
'https://example.com/og-image.png',
featuredImageAltText:
'HubSpot API 開発',
publishDate:
'2026-04-01T09:00:00.000Z',
currentState:
'DRAFT',
});
await client.cms.blogs.blogPostsApi.pushLiveDraft(post.id);
await fetch(
`https://api.hubapi.com/cms/v3/blogs/posts/schedule`,
{
method:
'POST',
headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
'Content-Type':
'application/json',
},
body: JSON.stringify({
id: post.id,
publishDate:
'2026-04-01T09:00:00.000Z',
}),
}
);
Node.js — ブログ記事の一覧取得とフィルター
const posts =
await client.cms.blogs.blogPostsApi.getPage(
undefined,
30,
undefined,
undefined,
undefined,
'PUBLISHED',
undefined,
undefined,
undefined,
undefined,
'publishDate',
'DESCENDING'
);
console.log(posts.results.map(p => ({ id: p.id, name: p.name, url: p.url })));
3-5 Pages API — サイトページ・ランディングページの管理
CMS Hub のページをプログラムで作成・複製・公開する。
📄 Site Pages
通常のウェブサイトページ。
エンドポイント:/cms/v3/pages/site-pages
用途:会社概要・製品ページ・FAQ など
🎯 Landing Pages
マーケティング用ランディングページ。
エンドポイント:/cms/v3/pages/landing-pages
用途:キャンペーン・ホワイトペーパーDLなど
Node.js — ランディングページの作成と公開
const page =
await fetch(
'https://api.hubapi.com/cms/v3/pages/landing-pages',
{
method:
'POST',
headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
'Content-Type':
'application/json',
},
body: JSON.stringify({
name:
'春キャンペーン 2026 LP',
slug:
'spring-campaign-2026',
templatePath:
'@hubspot/growth/templates/landing-page.html',
headHtml:
'<meta name="description" content="春キャンペーン特集">',
metaDescription:
'春キャンペーン特集ページ',
currentState:
'DRAFT',
}),
}
).then(r => r.json());
await fetch(
`https://api.hubapi.com/cms/v3/pages/landing-pages/${page.id}/draft/push-live`,
{
method:
'POST',
headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}` },
}
);
Node.js — ページの複製(テンプレートから量産)
async function clonePage(sourcePageId, newName, newSlug) {
const res =
await fetch(
`https://api.hubapi.com/cms/v3/pages/landing-pages/${sourcePageId}/clone`,
{
method:
'POST',
headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
'Content-Type':
'application/json',
},
body: JSON.stringify({ name: newName }),
}
);
const cloned =
await res.json();
await fetch(
`https://api.hubapi.com/cms/v3/pages/landing-pages/${cloned.id}`,
{
method:
'PATCH',
headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
'Content-Type':
'application/json',
},
body: JSON.stringify({ slug: newSlug }),
}
);
return cloned;
}
3-6 HubDB API — 動的テーブルデータの管理
HubDB はスプレッドシート感覚で使えるデータベース。CMS ページに動的コンテンツを埋め込む際に活用する。
🗄 HubDB のユースケース
HubDB は「CMS ページで動的なデータを表示したい」ときに使います。
例えば店舗一覧ページ・チームメンバー紹介・料金表・FAQなど、
構造化されたデータを HubDB テーブルに格納し、HubL テンプレートから呼び出して表示します。
API からも読み書きできるため、外部システムとの同期にも使えます。
HubDB API エンドポイント
GET
/cms/v3/hubdb/tables
テーブル一覧を取得
POST
/cms/v3/hubdb/tables
新しいテーブルを作成
GET
/cms/v3/hubdb/tables/{tableIdOrName}/rows
テーブルの行データを取得
POST
/cms/v3/hubdb/tables/{tableIdOrName}/rows
行を追加
PATCH
/cms/v3/hubdb/tables/{tableIdOrName}/rows/{rowId}/draft
行を更新(下書き)
POST
/cms/v3/hubdb/tables/{tableIdOrName}/draft/publish
下書きを公開(テーブル全体)
Node.js — HubDB テーブル作成
const table =
await client.cms.hubdb.tablesApi.createTable({
name:
'store_locations',
label:
'店舗一覧',
useForPages:
true,
columns: [
{ name:
'store_name', label:
'店舗名', type:
'TEXT' },
{ name:
'address', label:
'住所', type:
'TEXT' },
{ name:
'phone', label:
'電話番号', type:
'TEXT' },
{ name:
'prefecture', label:
'都道府県', type:
'SELECT',
options: [
{ name:
'東京都', type:
'option', order:
1 },
{ name:
'大阪府', type:
'option', order:
2 },
{ name:
'愛知県', type:
'option', order:
3 },
],
},
{ name:
'latitude', label:
'緯度', type:
'NUMBER' },
{ name:
'longitude', label:
'経度', type:
'NUMBER' },
{ name:
'is_open', label:
'営業中', type:
'BOOL' },
],
});
Node.js — 行の追加と公開
await client.cms.hubdb.rowsApi.createTableRow(table.id, {
values: {
store_name:
'渋谷店',
address:
'東京都渋谷区渋谷1-1-1',
phone:
'03-1234-5678',
prefecture: { name:
'東京都' },
latitude:
35.6580,
longitude:
139.7016,
is_open:
true,
},
});
await client.cms.hubdb.tablesApi.publishDraftTable(table.id);
Node.js — HubDB データの取得とフィルター
const rows =
await client.cms.hubdb.rowsApi.getTableRows(
'store_locations',
undefined,
undefined,
100,
undefined,
undefined,
'is_open=true',
);
console.log(rows.results.map(r => r.values));
const response =
await fetch(
'https://api.hubapi.com/cms/v3/hubdb/tables/store_locations/rows?prefecture__contains=東京&is_open=true&limit=50',
{ headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}` } }
);
const data =
await response.json();
HubDB の下書き管理:
HubDB はライブ版と下書き版の2つの状態を持ちます。
行を追加・更新した後は必ず publishDraftTable() を実行して公開してください。
公開しないと CMS ページには反映されません。
3-7 URL Mappings API — リダイレクト管理
旧 URL から新 URL へのリダイレクトをプログラムで一括管理する。サイトリニューアル時に特に有用。
Node.js — リダイレクト一括登録
const redirects = [
{ routePrefix:
'/old-blog/article-1', destination:
'/blog/new-article-1', redirectStyle:
301 },
{ routePrefix:
'/old-about', destination:
'/about-us', redirectStyle:
301 },
{ routePrefix:
'/campaign-2025', destination:
'/campaign-2026', redirectStyle:
302 },
];
for (
const redirect
of redirects) {
await fetch(
'https://api.hubapi.com/cms/v3/url-mappings', {
method:
'POST',
headers: {
'Authorization':
`Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
'Content-Type':
'application/json',
},
body: JSON.stringify({
routePrefix: redirect.routePrefix,
destination: redirect.destination,
redirectStyle: redirect.redirectStyle,
isOnlyAfterNotFound:
false,
isMatchQueryString:
false,
}),
});
await new Promise(r => setTimeout(r,
100));
}
console.log(
`${redirects.length} redirects registered.`);
3-8 実践パターン:外部システムと HubSpot の同期
外部データを HubDB や Blog API に定期同期する実用的なパターンを学ぶ。
🔄 同期パターンの例
社内の商品データベース(MySQL など)の情報を毎日 HubDB に同期し、
HubSpot の CMS ページで常に最新の商品情報を表示する。
同期処理は Node.js スクリプト + GitHub Actions のスケジュール実行で実装できます。
Node.js — HubDB への差分同期スクリプト
async function syncToHubDB(tableId, externalData) {
const existing =
await client.cms.hubdb.rowsApi.getTableRows(tableId, undefined, undefined,
1000);
const existingMap =
new Map(existing.results.map(r => [r.values.external_id, r]));
let added =
0, updated =
0, deleted =
0;
for (
const item
of externalData) {
const existing_row = existingMap.get(item.id);
if (!existing_row) {
await client.cms.hubdb.rowsApi.createTableRow(tableId, {
values: { external_id: item.id, name: item.name, price: item.price },
});
added++;
}
else if (existing_row.values.price !== item.price) {
await client.cms.hubdb.rowsApi.updateDraftTableRow(tableId, existing_row.id, {
values: { price: item.price },
});
updated++;
}
existingMap.delete(item.id);
}
for (
const [, row]
of existingMap) {
await client.cms.hubdb.rowsApi.purgeDraftTableRow(tableId, row.id);
deleted++;
}
await client.cms.hubdb.tablesApi.publishDraftTable(tableId);
console.log(
`Sync done: +${added} / ~${updated} / -${deleted}`);
}
.github/workflows/hubdb-sync.yml
name: Sync Products to HubDB
on:
schedule:
- cron:
'0 2 * * *'
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version:
'20'
- run: npm ci
- name: Run sync
env:
HUBSPOT_ACCESS_TOKEN: ${{ secrets.HUBSPOT_ACCESS_TOKEN }}
DB_CONNECTION_STRING: ${{ secrets.DB_CONNECTION_STRING }}
run: node scripts/sync-products.js
3-9 この章のまとめ
次章(カスタムオブジェクト & スキーマ設計)に進む前に確認する。
✅ Chapter 3 チェックリスト
- Marketing API と CMS API のカテゴリ分けとスコープ要件を理解した
- Forms API でフォームをプログラム作成できる
- 外部フォームから HubSpot Forms にデータ送信できる(Submissions API)
- Transactional Email API でトランザクションメールを送信できる
- sendId による重複送信防止を実装できる
- Blog Posts API で記事の作成・更新・公開・スケジュール設定ができる
- Pages API でランディングページの作成・複製・公開ができる
- HubDB のテーブル構造(ライブ版/下書き版)を理解した
- HubDB テーブルの作成・行追加・公開を実装できる
- 外部データを HubDB に差分同期するスクリプトを理解した
- URL Mappings API でリダイレクトを一括登録できる
- GitHub Actions のスケジュール実行で定期同期を自動化できる
次章(Chapter 4)について:
カスタムオブジェクトとスキーマ設計を学びます。標準オブジェクトでは表現できないビジネスデータ構造を
カスタムオブジェクトとして設計し、プロパティ型・アソシエーション・Enterprise 専用機能まで解説します。