TL;DR
Make(旧Integromat)APIは、開発者がワークフローの自動化、シナリオの管理、インテグレーションのプログラム実行を効率化するRESTfulエンドポイントを提供します。OAuth 2.0とAPIキー認証に対応し、シナリオ・実行・ウェブフック・チーム管理が可能。プランごとにレート制限(1分あたり60〜600リクエスト)が設定されています。本記事では、認証設定、シナリオ管理、ウェブフックトリガー、実行監視、本番向け自動化戦略をハンズオンで解説します。
はじめに
Make(Integromat)は、100カ国以上で100万人超のユーザーによる月間20億回以上の自動化オペレーションを支えています。開発者が自動化ツールやクライアントワークフローを効率的に構築・管理する上で、Make API連携は必須です。
例えば、複数クライアントの自動化を扱うエージェンシーでは、手動のシナリオ更新や実行監視、レポート作成に週15〜25時間を消費しがち。Make API統合により、シナリオのデプロイ・実行追跡・エラー処理・レポート作成をフル自動化できます。
このガイドでは、Make API連携の全プロセス(OAuth 2.0とAPIキー認証、シナリオ管理、ウェブフックトリガー、実行監視、チーム管理、本番デプロイ戦略)を実装例とともに解説します。最後まで読めば、運用に耐えるMake自動化環境を自分で構築できるようになります。
💡 ApidogはAPI連携テストを劇的に効率化します。MakeのAPIエンドポイント検証、OAuthフローのテスト、実行応答のデバッグが1つのワークスペースで完結。API仕様インポート、モック応答、チームシェアも対応。
Make APIとは?
Makeは自動化ワークフロー管理用のRESTful APIを提供しています。主な機能は以下です。
- シナリオの作成・更新・削除(CRUD)
- シナリオの手動実行
- 実行履歴の取得・監視
- ウェブフック管理
- チーム&ユーザー管理
- 接続・アプリ管理
- 組織・ワークスペース設定
主な機能
| 機能 | 説明 |
|---|---|
| RESTful API | JSONベースのAPIエンドポイント |
| OAuth 2.0 + APIキー | 柔軟な認証方式 |
| ウェブフック | リアルタイム実行通知 |
| レート制限 | プランごとに1分あたり60~600回 |
| シナリオ管理 | CRUD操作対応 |
| 実行制御 | 実行開始/停止/監視 |
| チームAPI | ユーザー・権限管理 |
MakeのプランとAPIアクセス
| プラン | APIアクセス | レート制限 | 最適な用途 |
|---|---|---|---|
| フリー | 制限あり | 60/分 | テスト・学習 |
| コア | フルAPI | 120/分 | 中小企業 |
| プロ | フルAPI + 優先 | 300/分 | 成長中のチーム |
| チーム | フルAPI + 管理者 | 600/分 | エージェンシー・企業 |
| エンタープライズ | カスタム制限 | カスタム | 大規模組織 |
APIアーキテクチャ概要
MakeはRESTful API構造です。ベースURLは以下:
https://api.make.com/api/v2/
APIバージョン
| バージョン | ステータス | ユースケース |
|---|---|---|
| v2 | 現在 | 新規連携すべて |
| v1 | 非推奨 | 従来連携(移行必要) |
はじめに: 認証設定
ステップ1: Makeアカウント作成
- Make.comにアクセス
- アカウント登録
- 「設定」→「開発者設定」へ
- API認証情報を生成
ステップ2: 認証方式の選択
| 方法 | 最適な用途 | セキュリティレベル |
|---|---|---|
| APIキー | 内部連携・スクリプト | 高(安全に保管) |
| OAuth 2.0 | マルチテナント・外部連携 | より高(ユーザースコープ) |
ステップ3: APIキー取得(簡単)
- 「設定」→「開発者設定」へ
- 「APIキーを作成」クリック
- コピーして安全に保管
# .envファイル
MAKE_API_KEY="your_api_key_here"
MAKE_ORGANIZATION_ID="your_org_id"
ステップ4: OAuth 2.0設定(マルチテナント向け)
- 「設定」→「開発者設定」→「OAuthアプリ」へ
- 「OAuthアプリを作成」
- リダイレクトURIを設定
- クライアントID・シークレット取得
const MAKE_CLIENT_ID = process.env.MAKE_CLIENT_ID;
const MAKE_CLIENT_SECRET = process.env.MAKE_CLIENT_SECRET;
const MAKE_REDIRECT_URI = process.env.MAKE_REDIRECT_URI;
// 認証URL生成
const getAuthUrl = (state) => {
const params = new URLSearchParams({
client_id: MAKE_CLIENT_ID,
redirect_uri: MAKE_REDIRECT_URI,
scope: 'read write execute',
state: state,
response_type: 'code'
});
return `https://www.make.com/oauth/authorize?${params.toString()}`;
};
ステップ5: コードをアクセストークンに交換
const exchangeCodeForToken = async (code) => {
const response = await fetch('https://www.make.com/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: MAKE_CLIENT_ID,
client_secret: MAKE_CLIENT_SECRET,
redirect_uri: MAKE_REDIRECT_URI,
code: code
})
});
const data = await response.json();
return {
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresIn: data.expires_in
};
};
// コールバック処理例
app.get('/oauth/callback', async (req, res) => {
const { code, state } = req.query;
try {
const tokens = await exchangeCodeForToken(code);
// トークン保存
await db.integrations.create({
userId: req.session.userId,
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
tokenExpiry: Date.now() + (tokens.expiresIn * 1000)
});
res.redirect('/success');
} catch (error) {
console.error('OAuth error:', error);
res.status(500).send('認証に失敗しました');
}
});
ステップ6: 認証済みAPIコールの実装
const MAKE_BASE_URL = 'https://api.make.com/api/v2';
const makeRequest = async (endpoint, options = {}) => {
const apiKey = options.useOAuth ? await getOAuthToken() : process.env.MAKE_API_KEY;
const response = await fetch(`${MAKE_BASE_URL}${endpoint}`, {
...options,
headers: {
'Authorization': `Token ${apiKey}`,
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Make APIエラー: ${error.message}`);
}
return response.json();
};
// 利用例
const scenarios = await makeRequest('/scenarios');
console.log(`${scenarios.data.length}個のシナリオが見つかりました`);
シナリオ管理
シナリオ一覧取得
const listScenarios = async (filters = {}) => {
const params = new URLSearchParams({
limit: filters.limit || 50,
offset: filters.offset || 0
});
if (filters.folder) {
params.append('folder', filters.folder);
}
const response = await makeRequest(`/scenarios?${params.toString()}`);
return response;
};
// 利用例
const scenarios = await listScenarios({ limit: 100 });
scenarios.data.forEach(scenario => {
console.log(`${scenario.name} - ${scenario.active ? 'アクティブ' : '一時停止中'}`);
console.log(` 最終実行日時: ${scenario.lastRunDate || 'なし'}`);
});
シナリオ詳細取得
const getScenario = async (scenarioId) => {
const response = await makeRequest(`/scenarios/${scenarioId}`);
return response;
};
// 利用例
const scenario = await getScenario('12345');
console.log(`名前: ${scenario.name}`);
console.log(`モジュール数: ${scenario.modules.length}`);
console.log(`スケジュール: ${scenario.schedule?.cronExpression || '手動'}`);
シナリオ作成
const createScenario = async (scenarioData) => {
const scenario = {
name: scenarioData.name,
blueprint: scenarioData.blueprint, // シナリオのJSONブループリント
active: scenarioData.active || false,
priority: scenarioData.priority || 1,
maxErrors: scenarioData.maxErrors || 3,
autoCommit: scenarioData.autoCommit || true,
description: scenarioData.description || ''
};
const response = await makeRequest('/scenarios', {
method: 'POST',
body: JSON.stringify(scenario)
});
return response;
};
// 利用例
const newScenario = await createScenario({
name: 'Lead Sync to CRM',
blueprint: {
modules: [
{ id: 1, app: 'webhooks', action: 'customWebhook', parameters: { /* ... */ } },
{ id: 2, app: 'salesforce', action: 'createRecord', parameters: { /* ... */ } }
],
connections: [ { from: 1, to: 2 } ]
},
active: true,
description: 'Sync webhook leads to Salesforce'
});
console.log(`シナリオが作成されました: ${newScenario.id}`);
シナリオ更新
const updateScenario = async (scenarioId, updates) => {
const response = await makeRequest(`/scenarios/${scenarioId}`, {
method: 'PATCH',
body: JSON.stringify(updates)
});
return response;
};
// 利用例
await updateScenario('12345', { active: false }); // 一時停止
await updateScenario('12345', {
schedule: {
cronExpression: '0 */6 * * *', // 6時間ごと
timezone: 'America/New_York'
}
});
シナリオ削除
const deleteScenario = async (scenarioId) => {
await makeRequest(`/scenarios/${scenarioId}`, {
method: 'DELETE'
});
console.log(`シナリオ ${scenarioId} が削除されました`);
};
実行管理
シナリオ手動実行
const executeScenario = async (scenarioId, inputData = null) => {
const response = await makeRequest(`/scenarios/${scenarioId}/execute`, {
method: 'POST',
body: inputData ? JSON.stringify(inputData) : undefined
});
return response;
};
// 利用例
const execution = await executeScenario('12345');
console.log(`実行が開始されました: ${execution.id}`);
const executionWithData = await executeScenario('12345', {
lead: {
email: 'prospect@example.com',
name: 'John Doe',
company: 'Acme Corp'
}
});
実行履歴取得
const getExecutionHistory = async (scenarioId, filters = {}) => {
const params = new URLSearchParams({
limit: filters.limit || 50,
from: filters.from,
to: filters.to,
status: filters.status // '成功', 'エラー', '実行中'
});
const response = await makeRequest(`/scenarios/${scenarioId}/executions?${params.toString()}`);
return response;
};
// 利用例
const failedExecutions = await getExecutionHistory('12345', {
from: new Date(Date.now() - 86400000).toISOString(),
status: 'error',
limit: 100
});
failedExecutions.data.forEach(exec => {
console.log(`実行 ${exec.id}: ${exec.error?.message}`);
});
実行詳細取得
const getExecution = async (executionId) => {
const response = await makeRequest(`/executions/${executionId}`);
return response;
};
// 利用例
const execution = await getExecution('98765');
console.log(`ステータス: ${execution.status}`);
console.log(`期間: ${execution.duration}ms`);
console.log(`実行されたモジュール数: ${execution.modulesExecuted}`);
実行停止
const stopExecution = async (executionId) => {
await makeRequest(`/executions/${executionId}`, {
method: 'DELETE'
});
console.log(`実行 ${executionId} が停止されました`);
};
ウェブフック管理
ウェブフック作成
const createWebhook = async (webhookData) => {
const webhook = {
name: webhookData.name,
scenarioId: webhookData.scenarioId,
type: 'custom',
hookType: 'HEAD',
security: { type: 'none' }
};
const response = await makeRequest('/webhooks', {
method: 'POST',
body: JSON.stringify(webhook)
});
return response;
};
// 利用例
const webhook = await createWebhook({
name: 'Lead Capture Webhook',
scenarioId: '12345',
type: 'custom',
hookType: 'HEAD',
security: { type: 'none' }
});
console.log(`ウェブフックURL: ${webhook.url}`);
ウェブフック一覧
const listWebhooks = async () => {
const response = await makeRequest('/webhooks');
return response;
};
// 利用例
const webhooks = await listWebhooks();
webhooks.data.forEach(webhook => {
console.log(`${webhook.name}: ${webhook.url}`);
});
ウェブフック削除
const deleteWebhook = async (webhookId) => {
await makeRequest(`/webhooks/${webhookId}`, {
method: 'DELETE'
});
console.log(`ウェブフック ${webhookId} が削除されました`);
};
チームとユーザー管理
チームメンバー一覧
const listTeamMembers = async (organizationId) => {
const response = await makeRequest(`/organizations/${organizationId}/users`);
return response;
};
// 利用例
const members = await listTeamMembers('org-123');
members.data.forEach(member => {
console.log(`${member.email} - ${member.role}`);
});
チームメンバー追加
const addTeamMember = async (organizationId, email, role) => {
const response = await makeRequest(`/organizations/${organizationId}/users`, {
method: 'POST',
body: JSON.stringify({
email: email,
role: role // 'ビューアー', 'ビルダー', 'マネージャー', '管理者'
})
});
return response;
};
// 利用例
await addTeamMember('org-123', 'newuser@example.com', 'builder');
ユーザーロール更新
const updateUserRole = async (organizationId, userId, newRole) => {
await makeRequest(`/organizations/${organizationId}/users/${userId}`, {
method: 'PATCH',
body: JSON.stringify({ role: newRole })
});
console.log(`ユーザー ${userId} のロールが ${newRole} に更新されました`);
};
ユーザーロール一覧
| ロール | 権限 |
|---|---|
| ビューアー | シナリオ閲覧のみ、編集不可 |
| ビルダー | シナリオ作成・編集 |
| マネージャー | チーム・請求管理 |
| 管理者 | 組織フルアクセス |
レート制限
レート制限概要
| プラン | 1分あたりリクエスト数 | バースト制限 |
|---|---|---|
| フリー | 60 | 100 |
| コア | 120 | 200 |
| プロ | 300 | 500 |
| チーム | 600 | 1000 |
| エンタープライズ | カスタム | カスタム |
レート制限ヘッダー
| ヘッダー | 説明 |
|---|---|
X-RateLimit-Limit |
1分ごとの最大リクエスト数 |
X-RateLimit-Remaining |
残りリクエスト数 |
X-RateLimit-Reset |
リセットまでの秒数 |
レート制限処理サンプル
const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await makeRequest(endpoint, options);
const remaining = response.headers.get('X-RateLimit-Remaining');
if (remaining < 10) {
console.warn(`レート制限が低い: 残り ${remaining} 件`);
}
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`レート制限されています。${delay}ms後に再試行します...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
本番環境デプロイ・チェックリスト
- [ ] 内部連携はAPIキー、クライアント連携はOAuthを使う
- [ ] 認証情報は暗号化DB等で安全に管理
- [ ] レート制限・リクエストキュー処理を実装
- [ ] 実行監視・アラートを必ず設定
- [ ] エラー通知(メール/Slack等)を組み込む
- [ ] 失敗時はリトライロジックを設計
- [ ] 包括的なロギングを追加
- [ ] 重要シナリオはバックアップ/エクスポート
実際の使用例
エージェンシーでのクライアント管理
- 課題: クライアントごとに手動シナリオ更新
- 解決策: Make API×集中ダッシュボード
- 結果: 70%の作業時間削減、デプロイの一貫性向上
主な実装例:
- マルチアカウントOAuth連携
- シナリオ一括デプロイ
- クライアントごとの使用状況レポート
Eコマース注文処理
- 課題: 倉庫連携の手動入力
- 解決策: Shopify→Makeウェブフック自動化
- 結果: 手動ゼロ、99.9%精度
主な実装例:
- ShopifyウェブフックからMakeへ連携
- シナリオで注文処理+倉庫更新
- リトライロジックでエラー対策
結論
Make APIは、エンタープライズレベルのワークフロー自動化を実現するための完全なAPIセットを提供します。ポイントまとめ:
- 内部用途はAPIキー、マルチテナント/外部向けはOAuth 2.0利用
- シナリオ・実行・ウェブフックのCRUD操作がAPI経由で可能
- チーム・組織管理もAPI化
- レート制限はプランごと(1分60〜600リクエスト)
- 本番運用ではモニタリング・アラート・リトライを必須実装
- ApidogでAPIテスト・チーム開発を効率化
FAQ
Make APIで認証するにはどうすればよいですか?
内部連携は「開発者設定」からAPIキーを、マルチテナントアプリはOAuth 2.0を利用してください。
プログラムでシナリオをトリガーできますか?
はい。/scenarios/{id}/execute エンドポイントで、入力データ付き/なしでシナリオを手動トリガー可能です。
Makeのレート制限は何ですか?
プランによりますが、1分あたり60(フリー)~600(チーム/エンタープライズ)リクエストです。
実行ログを取得するにはどうすればよいですか?
/scenarios/{id}/executions で日付・ステータスフィルタ付き履歴を取得できます。
API経由でウェブフックを作成できますか?
はい。/webhooks エンドポイントでウェブフックの作成・一覧・削除ができます。
Top comments (0)