Skip to main content

Make.com API Tutorial: Build and Manage Scenarios Programmatically

· 12 min read
Yassine El Haddad
Software Developer & Automation Specialist

I build production AI agents, web scrapers, and automation pipelines. Most of what I publish here comes from the actual problems they run into: proxies that get banned, anti-bot stacks that fingerprint your client, RAG that drifts when the underlying data moves. Stack: Python, TypeScript, Go, FastAPI, LangChain, Crawlee, Playwright, deployed on AWS, GCP, and Cloudflare.

Yes, Make.com has a full REST API. You can create scenarios, activate them, trigger runs, and pull execution logs — all without touching the visual editor.

Most developers discover this too late. They build elaborate Make workflows manually, then wonder how to replicate them across environments, monitor them in a dashboard, or trigger them conditionally from their own code. The Make API solves all three.

This tutorial covers the complete lifecycle: authentication, scenario management, programmatic execution, and log retrieval. Every example runs with curl and Python.

What the Make API Can Do

The Make REST API (v2) exposes every resource you interact with in the UI:

ResourceWhat You Can Do
ScenariosCreate, read, update, delete, clone, activate, deactivate
Scenario RunsTrigger on-demand, pass input data, retrieve outputs
Execution LogsList runs, filter by status, get per-module detail
Webhooks (Hooks)Create and manage webhook triggers
ConnectionsList and verify app credentials
Data StoresRead and write structured data
Organizations & TeamsList users, manage team settings

The API follows standard REST conventions. Every request hits:

https://{zone_url}/api/v2/{endpoint}

For example: https://eu1.make.com/api/v2/scenarios


Step 1: Find Your Zone URL

Make uses regional zones. Your zone URL determines your base URL for every API call. Check the address bar in your Make dashboard — it will show something like https://eu1.make.com/ or https://us1.make.com/.

Available zones:

ZoneURL
Europe 1https://eu1.make.com
Europe 2https://eu2.make.com
US 1https://us1.make.com
US 2https://us2.make.com
Celonis EUhttps://eu1.make.celonis.com
Celonis UShttps://us1.make.celonis.com

If you call the wrong zone, every request returns an authentication error — even with a valid token. Always confirm your zone first.


Step 2: Create an API Token

The Make API authenticates via bearer tokens. To create one:

  1. Open your Make dashboard and click your avatar → Profile
  2. Select the API tab
  3. Click Add token
  4. Set a Label (e.g., my-dashboard-token)
  5. Select the scopes you need (see table below)
  6. Copy the token immediately — Make hides it after you navigate away

Token scopes reference:

ScopeGrants
scenarios:readList scenarios, get details, get logs and blueprints
scenarios:writeCreate, update, clone, activate, deactivate, delete
scenarios:runTrigger scenario runs via API
hooks:readList webhooks
hooks:writeCreate and manage webhooks
connections:readView app connections

For a management dashboard, you need scenarios:read, scenarios:write, and scenarios:run.

Store your token in an environment variable, not in source code:

export MAKE_TOKEN="your-api-token-here"
export MAKE_ZONE="eu1.make.com"
export MAKE_BASE_URL="https://${MAKE_ZONE}/api/v2"

Step 3: Make Your First API Call

Every request passes the token in the Authorization header:

Authorization: Token your-api-token

Verify your setup by fetching your user profile:

curl -X GET "https://${MAKE_ZONE}/api/v2/users/me" \
-H "Authorization: Token ${MAKE_TOKEN}"

Expected response:

{
"user": {
"id": 12345,
"name": "Your Name",
"email": "you@example.com",
"timezone": "Europe/London"
}
}

If you get a 401, the token is wrong. If you get a 404, check your zone URL.


Step 4: List All Scenarios

Scenarios belong to teams. You need your team ID to list them. Get it from the URL in the Make UI (/team/{teamId}/dashboard) or from the API:

curl -X GET "${MAKE_BASE_URL}/teams?organizationId=YOUR_ORG_ID" \
-H "Authorization: Token ${MAKE_TOKEN}"

Then list scenarios for that team:

curl -X GET "${MAKE_BASE_URL}/scenarios?teamId=YOUR_TEAM_ID" \
-H "Authorization: Token ${MAKE_TOKEN}"

Response:

{
"scenarios": [
{
"id": 98765,
"name": "Lead Sync to HubSpot",
"isActive": true,
"teamId": 11111,
"scheduling": { "type": "indefinitely", "interval": 900 },
"lastEdit": "2026-03-10T14:23:00.000Z",
"nextExec": "2026-03-15T15:00:00.000Z",
"dlqCount": 0
}
],
"pg": { "limit": 10, "offset": 0 }
}

Key fields:

  • isActive — whether the scenario is currently running on schedule
  • scheduling.interval — run frequency in seconds
  • dlqCount — number of failed executions in the dead-letter queue
  • nextExec — timestamp of the next scheduled run

Python equivalent:

import os
import requests

BASE_URL = f"https://{os.environ['MAKE_ZONE']}/api/v2"
HEADERS = {"Authorization": f"Token {os.environ['MAKE_TOKEN']}"}

def list_scenarios(team_id: int) -> list[dict]:
response = requests.get(
f"{BASE_URL}/scenarios",
headers=HEADERS,
params={"teamId": team_id}
)
response.raise_for_status()
return response.json()["scenarios"]

scenarios = list_scenarios(team_id=11111)
for s in scenarios:
status = "✅ active" if s["isActive"] else "⏸ inactive"
print(f"{s['id']} | {s['name']} | {status}")

Step 5: Create a Scenario Programmatically

Creating a scenario via API requires three fields: teamId, blueprint, and scheduling.

The blueprint is a JSON string that defines the scenario's modules and connections. The easiest way to get a valid blueprint: build a scenario in the UI, then export it via:

curl -X GET "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/blueprint" \
-H "Authorization: Token ${MAKE_TOKEN}"

Then pass that blueprint to the create endpoint:

curl -X POST "${MAKE_BASE_URL}/scenarios" \
-H "Authorization: Token ${MAKE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"teamId": 11111,
"blueprint": "{\"name\":\"My API Scenario\",\"flow\":[],\"metadata\":{\"version\":1,\"scenario\":{\"roundtrips\":1,\"maxErrors\":3}}}",
"scheduling": "{\"type\":\"indefinitely\",\"interval\":3600}"
}'

Scheduling types:

TypeMeaning
indefinitelyRun every N seconds (set interval)
on-demandOnly run when triggered via API
onceRun once at a specific time
immediatelyRun as fast as possible

For scenarios you plan to trigger via API, use on-demand:

"scheduling": "{\"type\":\"on-demand\"}"

Python helper to clone an existing scenario:

def clone_scenario(source_id: int, team_id: int, new_name: str) -> dict:
response = requests.post(
f"{BASE_URL}/scenarios/{source_id}/clone",
headers=HEADERS,
json={"teamId": team_id, "name": new_name}
)
response.raise_for_status()
return response.json()["scenario"]

new_scenario = clone_scenario(
source_id=98765,
team_id=11111,
new_name="Lead Sync to HubSpot — Staging"
)
print(f"Cloned scenario ID: {new_scenario['id']}")

Step 6: Activate and Deactivate Scenarios

Activating a scenario schedules it to run. Deactivating stops all future scheduled runs (without deleting it).

Activate:

curl -X POST "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/start" \
-H "Authorization: Token ${MAKE_TOKEN}"

Deactivate:

curl -X POST "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/stop" \
-H "Authorization: Token ${MAKE_TOKEN}"

Both return the scenario ID and the updated isActive flag:

{ "scenario": { "id": 98765, "isActive": true } }

Practical use case: deploy a new scenario in inactive state, run a validation check, then activate only if the check passes:

def deploy_and_validate(scenario_id: int) -> bool:
# Run a test execution first
result = run_scenario(scenario_id, responsive=True)
if result.get("status") == "1": # 1 = success
activate_scenario(scenario_id)
print(f"Scenario {scenario_id} validated and activated")
return True
print(f"Validation failed: {result}")
return False

Step 7: Trigger a Scenario Run

The most powerful feature: trigger an on-demand run from your own code. The scenario must be active and set to on-demand scheduling.

curl -X POST "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/run" \
-H "Authorization: Token ${MAKE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"responsive": true,
"data": {
"email": "lead@example.com",
"company": "Acme Corp"
}
}'

The responsive flag controls execution mode:

responsiveBehavior
false (default)Returns executionId immediately; run happens async
trueWaits up to 40 seconds; returns final status and outputs

Response when responsive: true:

{
"executionId": "abc123xyz",
"status": "1"
}

Status codes: 1 = success, 2 = warning, 3 = error.

You can also pass a callbackUrl — Make will POST the result to that URL when the run finishes. This is ideal for runs that exceed the 40-second timeout:

curl -X POST "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/run" \
-H "Authorization: Token ${MAKE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"responsive": false,
"callbackUrl": "https://yourapp.com/webhooks/make-callback",
"data": { "batchId": "2026-03-15" }
}'

Full Python wrapper:

def run_scenario(
scenario_id: int,
data: dict | None = None,
responsive: bool = True,
callback_url: str | None = None
) -> dict:
payload: dict = {"responsive": responsive}
if data:
payload["data"] = data
if callback_url:
payload["callbackUrl"] = callback_url

response = requests.post(
f"{BASE_URL}/scenarios/{scenario_id}/run",
headers={**HEADERS, "Content-Type": "application/json"},
json=payload
)
response.raise_for_status()
return response.json()

# Trigger with input data, wait for result
result = run_scenario(
scenario_id=98765,
data={"email": "lead@example.com", "source": "website"},
responsive=True
)
print(f"Execution ID: {result['executionId']}, Status: {result['status']}")

Step 8: Read Execution Logs

Pull the last N execution logs for a scenario:

curl -X GET "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/logs?pg[limit]=20" \
-H "Authorization: Token ${MAKE_TOKEN}"

Filter by status (3 = errors only):

curl -X GET "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/logs?status=3&pg[limit]=50" \
-H "Authorization: Token ${MAKE_TOKEN}"

Log response fields:

{
"scenarioLogs": [
{
"imtId": "abc123",
"timestamp": "2026-03-15T14:30:00.000Z",
"status": 1,
"duration": 1240,
"operations": 3,
"transfer": 4096,
"instant": false
}
]
}
  • status: 1 = success, 2 = warning, 3 = error
  • duration: execution time in milliseconds
  • operations: number of module executions (billable units)
  • transfer: data processed in bytes

Get the full detail of a specific execution:

curl -X GET "${MAKE_BASE_URL}/scenarios/YOUR_SCENARIO_ID/executions/EXECUTION_ID" \
-H "Authorization: Token ${MAKE_TOKEN}"

Step 9: Build a Scenario Health Dashboard

Combine the endpoints above into a monitoring script. This example prints a status table for all scenarios in a team:

import os
from datetime import datetime, timezone
import requests

BASE_URL = f"https://{os.environ['MAKE_ZONE']}/api/v2"
HEADERS = {"Authorization": f"Token {os.environ['MAKE_TOKEN']}"}
TEAM_ID = int(os.environ["MAKE_TEAM_ID"])

def get_scenarios() -> list[dict]:
r = requests.get(f"{BASE_URL}/scenarios", headers=HEADERS, params={"teamId": TEAM_ID})
r.raise_for_status()
return r.json()["scenarios"]

def get_recent_logs(scenario_id: int, limit: int = 5) -> list[dict]:
r = requests.get(
f"{BASE_URL}/scenarios/{scenario_id}/logs",
headers=HEADERS,
params={"pg[limit]": limit}
)
r.raise_for_status()
return r.json().get("scenarioLogs", [])

def health_report():
scenarios = get_scenarios()
print(f"\n{'ID':<10} {'Name':<35} {'Active':<8} {'Last Status':<14} {'DLQ':<5}")
print("-" * 80)

for s in scenarios:
logs = get_recent_logs(s["id"], limit=1)
last_status = "—"
if logs:
code = logs[0]["status"]
last_status = {1: "✅ success", 2: "⚠️ warning", 3: "❌ error"}.get(code, str(code))

active = "✅" if s["isActive"] else "⏸"
dlq = s.get("dlqCount", 0)
dlq_flag = f"🔴 {dlq}" if dlq > 0 else "0"

print(f"{s['id']:<10} {s['name'][:34]:<35} {active:<8} {last_status:<14} {dlq_flag:<5}")

health_report()

Sample output:

ID Name Active Last Status DLQ
--------------------------------------------------------------------------------
98765 Lead Sync to HubSpot ✅ ✅ success 0
98766 Daily Report Email ✅ ⚠️ warning 0
98767 Slack Alerts (Staging) ⏸ ❌ error 3

Scenarios with dlqCount > 0 have executions that failed and need inspection. You can retrieve and retry them via the incomplete executions API (/scenarios/{id}/incomplete-executions).


Make API vs Zapier API: When to Use Each

Both platforms offer APIs, but they differ significantly in depth:

FeatureMake APIZapier API
Create automations via API✅ Full scenario blueprints❌ Limited; no Zap creation
Trigger runs programmatically✅ Native endpoint✅ Via webhooks only
Pass input data on trigger✅ Structured data object✅ Via webhook payload
Read execution logs✅ Full log history⚠️ Basic only
Manage connections/credentials
Pagination, filtering✅ Full support⚠️ Limited
Best forTeams managing 10+ scenarios programmaticallySimple webhook triggers

If you're building tooling on top of your automation layer — staging environments, deployment pipelines, monitoring dashboards — Make's API is the better foundation.


Rate Limits

Make applies a per-organization request limit for most API endpoints. One important exception: the /scenarios/{id}/run endpoint is not subject to the standard rate limit. You can trigger scenario runs as frequently as your plan allows.

For other endpoints, Make uses sliding window limits. If you exceed them, you receive a 429 Too Many Requests response. Implement exponential backoff:

import time

def api_call_with_retry(func, *args, max_retries: int = 3, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except requests.HTTPError as e:
if e.response.status_code == 429 and attempt < max_retries - 1:
wait = 2 ** attempt
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)
else:
raise

FAQ

Frequently Asked Questions

Yes. Make.com has a full REST API (v2) that lets you create, manage, and execute scenarios programmatically. The API is documented at https://developers.make.com/api-documentation/ and supports token-based authentication as well as OAuth 2.0.

Generate an API token from your Make profile (Profile → API → Add token). Pass it in the Authorization header as: Authorization: Token your-token. Each token has scopes you select at creation time — you cannot add scopes later without creating a new token.

Send a POST request to /api/v2/scenarios with a JSON body containing teamId, blueprint (a JSON string), and scheduling (a JSON string). The easiest way to get a valid blueprint is to export one from an existing scenario using GET /api/v2/scenarios/{id}/blueprint.

Use POST /api/v2/scenarios/{id}/run. The scenario must be active and set to on-demand scheduling. Pass responsive: true to wait for the result synchronously, or use callbackUrl for async notification. You can pass input data in the data object.

Make hosts data in separate regional zones (eu1, eu2, us1, us2). Your zone URL is the base for all API calls — e.g., https://eu1.make.com/api/v2/. Using the wrong zone returns auth errors even with a valid token. Find your zone in the URL of your Make dashboard.

Yes. Use GET /api/v2/scenarios/{id}/logs to retrieve execution history, filtered by status (1=success, 2=warning, 3=error), date range, and duration. For detailed per-execution data including outputs and error messages, use GET /api/v2/scenarios/{id}/executions/{executionId}.

The Make API is available on all plans. However, certain features — like Scenario Inputs (required for passing data to runs) — require the Pro plan or higher. See https://www.make.com/en/pricing for current plan limits.


Next Steps

You now have everything you need to integrate Make.com into your development workflow:

  • Deployment pipelines: clone a template scenario, configure connections, activate on deploy
  • Multi-environment management: maintain separate staging and production scenarios programmatically
  • Monitoring dashboards: pull execution logs and DLQ counts into your existing observability stack
  • Conditional automation: trigger Make scenarios from your application logic in response to events

Start building with Make.com — the free plan includes 1,000 operations per month and full API access.

If you're combining Make with data extraction workflows, the Apify + Make.com integration guide shows how to trigger Apify scrapers from Make scenarios and pipe the resulting datasets into downstream apps.