@ericrisco/rsc 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/manifest.json +153 -4
- package/package.json +1 -1
- package/scripts/lib/domains.js +2 -1
- package/scripts/lib/recommend.js +6 -0
- package/skills/automation-flows/SKILL.md +1 -1
- package/skills/automation-strategy/SKILL.md +131 -0
- package/skills/automation-strategy/evals/README.md +16 -0
- package/skills/automation-strategy/evals/cases.yaml +48 -0
- package/skills/automation-strategy/references/automate-decision-and-roi.md +118 -0
- package/skills/automation-strategy/references/orchestration-and-antipatterns.md +107 -0
- package/skills/automation-strategy/references/platform-selection-matrix.md +86 -0
- package/skills/fable-operator/SKILL.md +170 -0
- package/skills/fable-operator/evals/README.md +8 -0
- package/skills/fable-operator/evals/cases.yaml +52 -0
- package/skills/harness/references/providers.yaml +100 -0
- package/skills/make/SKILL.md +255 -0
- package/skills/make/evals/README.md +14 -0
- package/skills/make/evals/cases.yaml +45 -0
- package/skills/make/references/api-v2-cheatsheet.md +114 -0
- package/skills/make/references/blueprint-round-trip.md +128 -0
- package/skills/make/references/make-mcp-and-auth.md +101 -0
- package/skills/n8n/SKILL.md +205 -0
- package/skills/n8n/evals/README.md +14 -0
- package/skills/n8n/evals/cases.yaml +45 -0
- package/skills/n8n/references/auth-and-selfhost.md +62 -0
- package/skills/n8n/references/n8n-mcp-tools.md +84 -0
- package/skills/n8n/references/rest-api-cheatsheet.md +94 -0
- package/skills/power-automate/SKILL.md +169 -0
- package/skills/power-automate/evals/README.md +17 -0
- package/skills/power-automate/evals/cases.yaml +43 -0
- package/skills/power-automate/references/dataverse-web-api.md +187 -0
- package/skills/power-automate/references/entra-auth-setup.md +75 -0
- package/skills/power-automate/references/flowstudio-mcp-and-limits.md +62 -0
- package/skills/roast-me/tools/adapters/__pycache__/__init__.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/base.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/claude.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/codex.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/gemini.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/registry.cpython-312.pyc +0 -0
- package/skills/zapier/SKILL.md +145 -0
- package/skills/zapier/evals/README.md +5 -0
- package/skills/zapier/evals/cases.yaml +50 -0
- package/skills/zapier/references/programmatic-limits-and-partner-api.md +48 -0
- package/skills/zapier/references/when-to-use-vs-n8n-make.md +44 -0
- package/skills/zapier/references/zapier-mcp-tools.md +72 -0
|
@@ -3384,6 +3384,106 @@ providers:
|
|
|
3384
3384
|
CREDENTIALS.md: |
|
|
3385
3385
|
Dashboard: https://app.n8n.cloud/settings/api (or self-hosted equivalent).
|
|
3386
3386
|
`N8N_API_KEY` — secret. Required for all REST API calls.
|
|
3387
|
+
API surface: workflows CRUD + `/activate` `/deactivate` + `/workflows/{id}/execute`
|
|
3388
|
+
(recent; no custom input — use a Webhook trigger for runtime params). See the `n8n` skill.
|
|
3389
|
+
|
|
3390
|
+
- id: MAKE
|
|
3391
|
+
category: automatizacion
|
|
3392
|
+
detectors:
|
|
3393
|
+
imports: []
|
|
3394
|
+
env_vars: ["MAKE_API_TOKEN", "MAKE_ZONE"]
|
|
3395
|
+
deps: []
|
|
3396
|
+
dashboard_url: "https://www.make.com/en/help/tools/api"
|
|
3397
|
+
env_example: |
|
|
3398
|
+
MAKE_ZONE=eu1.make.com # your zone: eu1/eu2/us1/us2 (wrong zone => auth error)
|
|
3399
|
+
MAKE_API_TOKEN= # Profile > API/token; scopes are fixed at creation
|
|
3400
|
+
MAKE_TEAM_ID=
|
|
3401
|
+
files:
|
|
3402
|
+
test_connection.sh: |
|
|
3403
|
+
#!/usr/bin/env bash
|
|
3404
|
+
set -euo pipefail
|
|
3405
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3406
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3407
|
+
: "${MAKE_ZONE:?MAKE_ZONE not set (e.g. eu1.make.com)}"
|
|
3408
|
+
: "${MAKE_API_TOKEN:?MAKE_API_TOKEN not set}"
|
|
3409
|
+
NAME=$(curl -fsS "https://${MAKE_ZONE%/}/api/v2/users/me" -H "Authorization: Token $MAKE_API_TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["authUser"]["name"])')
|
|
3410
|
+
echo "OK — Make API reachable on $MAKE_ZONE (user: $NAME)."
|
|
3411
|
+
README.md: |
|
|
3412
|
+
# MAKE
|
|
3413
|
+
Make.com (formerly Integromat). Scenarios via /api/v2; blueprint is a stringified JSON
|
|
3414
|
+
round-trip. Base URL is zone-scoped. See the `make` skill for dynamic create/manage.
|
|
3415
|
+
CREDENTIALS.md: |
|
|
3416
|
+
Dashboard: Profile > API (https://www.make.com/en/help/tools/api).
|
|
3417
|
+
`MAKE_API_TOKEN` — secret; token scopes are immutable after creation. Wrong `MAKE_ZONE`
|
|
3418
|
+
returns an auth error even with a valid token. Endpoints are case-sensitive.
|
|
3419
|
+
|
|
3420
|
+
- id: ZAPIER
|
|
3421
|
+
category: automatizacion
|
|
3422
|
+
detectors:
|
|
3423
|
+
imports: []
|
|
3424
|
+
env_vars: ["ZAPIER_MCP_URL", "ZAPIER_MCP_API_KEY"]
|
|
3425
|
+
deps: []
|
|
3426
|
+
dashboard_url: "https://mcp.zapier.com"
|
|
3427
|
+
env_example: |
|
|
3428
|
+
ZAPIER_MCP_URL=https://mcp.zapier.com/api/v1/connect
|
|
3429
|
+
ZAPIER_MCP_API_KEY= # Bearer key from the Zapier MCP dashboard (2 tasks per call)
|
|
3430
|
+
files:
|
|
3431
|
+
test_connection.sh: |
|
|
3432
|
+
#!/usr/bin/env bash
|
|
3433
|
+
set -euo pipefail
|
|
3434
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3435
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3436
|
+
: "${ZAPIER_MCP_URL:?ZAPIER_MCP_URL not set}"
|
|
3437
|
+
: "${ZAPIER_MCP_API_KEY:?ZAPIER_MCP_API_KEY not set}"
|
|
3438
|
+
# Zapier exposes no account-CRUD REST API; smoke-test the MCP endpoint with an initialize handshake.
|
|
3439
|
+
CODE=$(curl -s -o /dev/null -w '%{http_code}' -X POST "$ZAPIER_MCP_URL" \
|
|
3440
|
+
-H "Authorization: Bearer $ZAPIER_MCP_API_KEY" -H "Content-Type: application/json" \
|
|
3441
|
+
-H "Accept: application/json, text/event-stream" \
|
|
3442
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"rsc","version":"1"}}}')
|
|
3443
|
+
case "$CODE" in 2*) echo "OK — Zapier MCP endpoint reachable (HTTP $CODE).";; *) echo "FAIL — HTTP $CODE" >&2; exit 1;; esac
|
|
3444
|
+
README.md: |
|
|
3445
|
+
# ZAPIER
|
|
3446
|
+
Zapier has NO public API for a normal user to create/manage their own Zaps. Programmatic
|
|
3447
|
+
use = Zapier MCP (runs pre-configured actions across 9,000+ apps; does not author Zaps).
|
|
3448
|
+
See the `zapier` skill for the honest boundary and when to use n8n/Make instead.
|
|
3449
|
+
CREDENTIALS.md: |
|
|
3450
|
+
Dashboard: https://mcp.zapier.com — generate an MCP server + Bearer key.
|
|
3451
|
+
`ZAPIER_MCP_API_KEY` — secret (Bearer). Each successful tool call costs 2 Zapier tasks.
|
|
3452
|
+
|
|
3453
|
+
- id: POWER_AUTOMATE
|
|
3454
|
+
category: automatizacion
|
|
3455
|
+
detectors:
|
|
3456
|
+
imports: []
|
|
3457
|
+
env_vars: ["PA_DATAVERSE_URL", "PA_TENANT_ID", "PA_CLIENT_ID", "PA_CLIENT_SECRET"]
|
|
3458
|
+
deps: []
|
|
3459
|
+
dashboard_url: "https://make.powerautomate.com"
|
|
3460
|
+
env_example: |
|
|
3461
|
+
PA_DATAVERSE_URL=https://<org>.crm.dynamics.com # your Dataverse org URL (region domain varies)
|
|
3462
|
+
PA_TENANT_ID= # Entra tenant id
|
|
3463
|
+
PA_CLIENT_ID= # Entra app registration (needs a Dataverse application user)
|
|
3464
|
+
PA_CLIENT_SECRET=
|
|
3465
|
+
files:
|
|
3466
|
+
test_connection.sh: |
|
|
3467
|
+
#!/usr/bin/env bash
|
|
3468
|
+
set -euo pipefail
|
|
3469
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3470
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3471
|
+
: "${PA_DATAVERSE_URL:?PA_DATAVERSE_URL not set}"
|
|
3472
|
+
: "${PA_TENANT_ID:?PA_TENANT_ID not set}"; : "${PA_CLIENT_ID:?PA_CLIENT_ID not set}"; : "${PA_CLIENT_SECRET:?PA_CLIENT_SECRET not set}"
|
|
3473
|
+
TOKEN=$(curl -fsS "https://login.microsoftonline.com/${PA_TENANT_ID}/oauth2/v2.0/token" \
|
|
3474
|
+
-d "grant_type=client_credentials&client_id=${PA_CLIENT_ID}&client_secret=${PA_CLIENT_SECRET}&scope=${PA_DATAVERSE_URL%/}/.default" \
|
|
3475
|
+
| python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')
|
|
3476
|
+
N=$(curl -fsS "${PA_DATAVERSE_URL%/}/api/data/v9.2/workflows?\$filter=category%20eq%205&\$top=1" \
|
|
3477
|
+
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["value"]))')
|
|
3478
|
+
echo "OK — Dataverse reachable; cloud-flow query returned $N row(s)."
|
|
3479
|
+
README.md: |
|
|
3480
|
+
# POWER_AUTOMATE
|
|
3481
|
+
Microsoft Power Automate cloud flows via the Dataverse Web API (solution-aware flows only;
|
|
3482
|
+
`api.flow.microsoft.com` is unsupported). Auth is Entra OAuth. See the `power-automate` skill.
|
|
3483
|
+
CREDENTIALS.md: |
|
|
3484
|
+
Register an Entra app; add it as a Dataverse application user with a security role granting
|
|
3485
|
+
Process (workflow) privileges. `PA_CLIENT_SECRET` — secret. Only flows inside a Dataverse
|
|
3486
|
+
solution are code-manageable; personal "My Flows" are not.
|
|
3387
3487
|
|
|
3388
3488
|
# Categories used to group tools in 01-TOOLS/README.md.
|
|
3389
3489
|
categories:
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: make
|
|
3
|
+
description: "Use when operating Make.com (formerly Integromat) programmatically — driving its REST API v2 or the Make MCP server from code or an agent to create, read, update, activate, run, clone, or delete scenarios, connections, hooks, and data stores. Triggers: 'create a Make scenario via the API', 'export a scenario blueprint, mutate it, and push it back', 'start/stop/run a Make scenario from a script', 'clone this Integromat scenario into another team', 'connect the Make MCP server so an agent runs my scenarios as tools', 'my valid Make API token returns an auth error' (zone trap), 'automatiza escenarios de Make.com desde la API'. NOT designing what the flow should do — trigger, branching, mapping, dedup, error path (automation-flows), NOT choosing Make vs n8n vs Zapier by billing model (automation-strategy), NOT operating n8n / Zapier / Power Automate (their skills), NOT a generic typed REST client with pagination/backoff (api-connector-builder) or an inbound webhook receiver in your own app (webhooks)."
|
|
4
|
+
tags: [make, integromat, automation, scenarios, blueprint, mcp, no-code, api, workflows]
|
|
5
|
+
recommends: [automation-flows, automation-strategy, api-connector-builder, webhooks]
|
|
6
|
+
profiles: [full]
|
|
7
|
+
origin: risco
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Make (Integromat) — operate scenarios by REST API and MCP
|
|
11
|
+
|
|
12
|
+
Drive a live Make.com account from code or an agent: create scenarios from a
|
|
13
|
+
blueprint, activate/run/stop/clone/delete them, and manage the connections,
|
|
14
|
+
hooks, data stores, and teams around them. This skill owns the **operate**
|
|
15
|
+
half — the API v2 calls and the MCP wiring. It does **not** design the flow;
|
|
16
|
+
what a scenario *should do* (trigger, routes, mapping, dedup, error handler)
|
|
17
|
+
lives in [`automation-flows`](../automation-flows/SKILL.md), and the
|
|
18
|
+
Make-vs-n8n-vs-Zapier billing call lives in
|
|
19
|
+
[`automation-strategy`](../automation-strategy/SKILL.md). Bring the design
|
|
20
|
+
here, and this skill turns it into API payloads and MCP tool calls.
|
|
21
|
+
|
|
22
|
+
Reality up top (verify at author time — Make ships fast):
|
|
23
|
+
|
|
24
|
+
- **REST API v2 is GA.** Base URL is **zoned**: `https://{zone}.make.com/api/v2`.
|
|
25
|
+
- **The Make MCP server is GA and free on every plan** — you only pay the
|
|
26
|
+
scenario **credits** a run consumes. Cloud MCP has two tool tiers: run tools
|
|
27
|
+
(all plans) and management tools (paid).
|
|
28
|
+
|
|
29
|
+
## Connect first — API token vs MCP
|
|
30
|
+
|
|
31
|
+
Two ways in, chosen by *who is driving*:
|
|
32
|
+
|
|
33
|
+
- **REST API v2** — deterministic CRUD from your own scripts/CI. Full control
|
|
34
|
+
of the blueprint. Use for provisioning, bulk edits, activate/stop pipelines.
|
|
35
|
+
- **Make MCP server** — lets an MCP client (Claude, Cursor, ChatGPT) call your
|
|
36
|
+
scenarios and (on paid plans) manage them as tools, no glue code. Use when an
|
|
37
|
+
**agent** is the operator.
|
|
38
|
+
|
|
39
|
+
`.env` (never inline secrets — read from the environment):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
MAKE_ZONE=eu2.make.com # your org's zone — eu1|eu2|us1|us2 (+ celonis). WRONG ZONE = AUTH ERROR.
|
|
43
|
+
MAKE_API_TOKEN=xxxxxxxx # Profile → API/SDK → API token. Scopes are FIXED at creation.
|
|
44
|
+
MAKE_TEAM_ID=123456 # teamId a scenario is created under (integer)
|
|
45
|
+
MAKE_MCP_TOKEN=yyyyyyyy # separate MCP token, for the token-URL MCP transport
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Auth header (API):** `Authorization: Token {MAKE_API_TOKEN}` — the literal
|
|
49
|
+
word `Token`, a space, then the token. OAuth2 is the alternative for
|
|
50
|
+
multi-user apps. **Scopes are chosen when the token is minted and cannot be
|
|
51
|
+
widened later** — mint with `scenarios:read scenarios:write` (and
|
|
52
|
+
`connections`, `hooks`, `datastores`, `teams` as needed) up front; a
|
|
53
|
+
too-narrow token means re-minting, not patching.
|
|
54
|
+
|
|
55
|
+
## The scenario model (just enough to build the payload)
|
|
56
|
+
|
|
57
|
+
A **scenario** = exactly one trigger module, then a chain of action modules,
|
|
58
|
+
optionally split by **routers** into branches. Data flows by **mapping**:
|
|
59
|
+
a downstream field references an upstream output as `{{2.email}}` (module 2's
|
|
60
|
+
`email`). The whole thing serializes to a **blueprint** — the JSON you GET, edit,
|
|
61
|
+
and POST back. That is the entire operate-side model you need here.
|
|
62
|
+
|
|
63
|
+
Do **not** design the flow in this skill. Trigger choice (webhook vs polling),
|
|
64
|
+
branch logic, idempotency/dedup on a data store, and the error handler
|
|
65
|
+
(Break → Incomplete Executions, etc.) are all `automation-flows`. Take its
|
|
66
|
+
build sheet, then encode it as a blueprint below.
|
|
67
|
+
|
|
68
|
+
## API v2 surface
|
|
69
|
+
|
|
70
|
+
| Group | Endpoints (case-sensitive!) | Use |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| Scenarios | `GET/POST /scenarios`, `GET/PATCH/DELETE /scenarios/{id}`, `.../start`, `.../stop`, `.../run`, `.../clone`, `.../blueprint` | the core |
|
|
73
|
+
| Connections | `GET/POST /connections`, `.../{id}/test` | app auth the modules use |
|
|
74
|
+
| Hooks | `GET/POST /hooks`, `.../{id}/ping`, `.../learn-start` | inbound webhooks/mailhooks |
|
|
75
|
+
| Data stores | `GET/POST /data-stores`, `.../{id}/data` | dedup keys, state |
|
|
76
|
+
| Templates | `GET /templates`, `.../{id}/blueprint` | starting-point blueprints |
|
|
77
|
+
| Teams / Orgs | `GET /teams`, `GET /organizations/{id}` | scoping + rate limit |
|
|
78
|
+
|
|
79
|
+
Two rules that bite: **endpoints and query keys are case-sensitive**, and every
|
|
80
|
+
call is **zoned** — the same token against the wrong `{zone}` returns an auth
|
|
81
|
+
error, not a 404, which sends people chasing a token problem that does not exist.
|
|
82
|
+
|
|
83
|
+
**Rate limits are per plan** (req/min): Core 60 · Pro 120 · Teams 240 ·
|
|
84
|
+
Enterprise 1000. Read your own real ceiling rather than guessing:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
curl -s -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
88
|
+
"https://$MAKE_ZONE/api/v2/organizations/$ORG_ID" | jq '.organization.license.apiLimit'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Dynamic lifecycle — the blueprint round-trip
|
|
92
|
+
|
|
93
|
+
The core technique: **you rarely hand-write a blueprint.** You GET one from a
|
|
94
|
+
template or an existing scenario, mutate the JSON, and POST/PATCH it back **as a
|
|
95
|
+
string**. `blueprint` and `scheduling` are sent as JSON *strings*, not objects.
|
|
96
|
+
|
|
97
|
+
### 1. Get a starting blueprint
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# From an existing scenario (or a template: GET /templates/{id}/blueprint)
|
|
101
|
+
curl -s -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
102
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$TEMPLATE_ID/blueprint" \
|
|
103
|
+
| jq '.response.blueprint' > bp.json # wrapper key: verify .response.blueprint at author time
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Mutate `bp.json` with your design — module parameters, the `{{n.field}}`
|
|
107
|
+
mappings, router filters. Keep secrets out; wire credentials via a
|
|
108
|
+
**connection id**, never a literal key in the blueprint.
|
|
109
|
+
|
|
110
|
+
### 2. Create the scenario (blueprint + scheduling as STRINGS)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
114
|
+
-H "Content-Type: application/json" \
|
|
115
|
+
"https://$MAKE_ZONE/api/v2/scenarios" \
|
|
116
|
+
-d "$(jq -n --argjson team "$MAKE_TEAM_ID" \
|
|
117
|
+
--arg bp "$(jq -c . bp.json)" \
|
|
118
|
+
--arg sched '{"type":"on-demand"}' \
|
|
119
|
+
'{teamId:$team, blueprint:$bp, scheduling:$sched}')"
|
|
120
|
+
# scheduling e.g. {"type":"indefinitely","interval":900} (interval seconds) — verify fields at author time.
|
|
121
|
+
# optional: folderId, basedon (template id)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 3. Validate
|
|
125
|
+
|
|
126
|
+
The create call itself is the validator — a malformed blueprint returns a 400
|
|
127
|
+
naming the offending module/field. Fix the JSON and re-POST. There is no
|
|
128
|
+
separate schema-lint endpoint; a clean create *is* the pass.
|
|
129
|
+
|
|
130
|
+
### 4. Dry-run / test before you schedule
|
|
131
|
+
|
|
132
|
+
Run it once, watching one execution, while still `on-demand` (inactive):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
136
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$ID/run" \
|
|
137
|
+
-H "Content-Type: application/json" -d '{"responsive":true}'
|
|
138
|
+
# inspect the returned execution/bundle output before trusting the flow
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 5. Activate
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# switch scheduling off on-demand first (PATCH), then start
|
|
145
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
146
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$ID/start"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 6. Manage — patch, stop, clone
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Update: same round-trip — GET blueprint, mutate, PATCH back as a string
|
|
153
|
+
curl -s -X PATCH -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
154
|
+
-H "Content-Type: application/json" \
|
|
155
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$ID" \
|
|
156
|
+
-d "$(jq -n --arg bp "$(jq -c . bp.json)" '{blueprint:$bp}')"
|
|
157
|
+
|
|
158
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" ".../scenarios/$ID/stop"
|
|
159
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
160
|
+
-H "Content-Type: application/json" ".../scenarios/$ID/clone" \
|
|
161
|
+
-d '{"teamId": 999, "name": "copy"}' # clone into another team
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 7. Delete — export first (irreversible)
|
|
165
|
+
|
|
166
|
+
`DELETE /scenarios/{id}` is permanent; there is no undo and no trash. **Never
|
|
167
|
+
delete a live scenario without exporting its blueprint first.**
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
curl -s -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
171
|
+
".../scenarios/$ID/blueprint" | jq '.response.blueprint' > backup-$ID.json # export
|
|
172
|
+
curl -s -X DELETE -H "Authorization: Token $MAKE_API_TOKEN" ".../scenarios/$ID"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Make MCP — run and manage scenarios as tools
|
|
176
|
+
|
|
177
|
+
The Make MCP server hands an MCP client your scenarios as callable tools. Two
|
|
178
|
+
transports:
|
|
179
|
+
|
|
180
|
+
- **OAuth (remote):** point the client at `https://mcp.make.com` (or the
|
|
181
|
+
`/stream`, `/sse` variants). Scopes granted at consent decide which tools appear.
|
|
182
|
+
- **MCP token (per-zone):** `https://{zone}.make.com/mcp/u/{MCP_TOKEN}/stateless`
|
|
183
|
+
(also `/stream`, `/sse`). `/stateless` times out at ~60 s; `/stream` and
|
|
184
|
+
`/sse` allow ~5 min — a long scenario needs `/stream` or `/sse`.
|
|
185
|
+
|
|
186
|
+
Tool tiers (exact names move — confirm in the client's tool list at author time):
|
|
187
|
+
|
|
188
|
+
- **Run tools — all plans.** Enumerate on-demand scenarios and execute one with
|
|
189
|
+
inputs, returning its output. This is what lets an agent *use* your automation.
|
|
190
|
+
- **Management tools — paid plans.** View/modify scenarios, connections, hooks,
|
|
191
|
+
data stores, teams, organizations — the CRUD above, surfaced as tools.
|
|
192
|
+
|
|
193
|
+
Client config sketch (token transport):
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{ "mcpServers": { "make": {
|
|
197
|
+
"url": "https://eu2.make.com/mcp/u/${MAKE_MCP_TOKEN}/stream"
|
|
198
|
+
} } }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
MCP calls consume the scenario's normal **credits** — the server is free, the
|
|
202
|
+
runs are not. **Legacy note:** the local stdio server `integromat/make-mcp-server`
|
|
203
|
+
predates the cloud one and exposes on-demand scenarios as tools over stdio;
|
|
204
|
+
prefer the cloud server unless you specifically need a local process.
|
|
205
|
+
|
|
206
|
+
## Honesty / gotchas
|
|
207
|
+
|
|
208
|
+
- **Zone trap.** Wrong `{zone}` → auth error with a perfectly valid token. Check
|
|
209
|
+
the zone before you suspect the token.
|
|
210
|
+
- **Case-sensitive paths.** `/scenarios` works, `/Scenarios` does not.
|
|
211
|
+
- **`blueprint` and `scheduling` are strings, not objects** — stringify them or
|
|
212
|
+
the create/update fails.
|
|
213
|
+
- **Token scopes are frozen at creation.** Can't widen later; re-mint instead.
|
|
214
|
+
- **Delete is irreversible** — export the blueprint first, always.
|
|
215
|
+
- **Credits, not operations.** Make's billing unit became **credits** (was
|
|
216
|
+
"operations"); API-triggered and MCP-triggered runs both burn them.
|
|
217
|
+
- **`.run` on an inactive scenario** is your dry run; scheduled execution needs
|
|
218
|
+
`.start` — don't confuse the two.
|
|
219
|
+
- **Don't hand-author blueprints from scratch** — round-trip a template; the
|
|
220
|
+
format is large and undocumented in full.
|
|
221
|
+
|
|
222
|
+
## Related skills
|
|
223
|
+
|
|
224
|
+
- [`automation-flows`](../automation-flows/SKILL.md) — **design** the flow
|
|
225
|
+
(trigger, routes, mapping, dedup, error path). Build it there, encode the
|
|
226
|
+
blueprint here. Design ↔ operate is the boundary.
|
|
227
|
+
- [`automation-strategy`](../automation-strategy/SKILL.md) — choose Make vs n8n
|
|
228
|
+
vs Zapier by billing model *before* committing to this skill.
|
|
229
|
+
- [`webhooks`](../webhooks/SKILL.md) — building the inbound endpoint that
|
|
230
|
+
*receives* events in your own app (vs Make's `hooks` API here).
|
|
231
|
+
- [`api-connector-builder`](../api-connector-builder/SKILL.md) — a generic typed
|
|
232
|
+
REST client with auth/pagination/backoff, when you outgrow curl.
|
|
233
|
+
- Other platforms: `n8n`, `zapier`, `power-automate` (their own skills).
|
|
234
|
+
|
|
235
|
+
## Checklist
|
|
236
|
+
|
|
237
|
+
- [ ] `MAKE_ZONE` matches the org's actual zone (ruled out the zone trap).
|
|
238
|
+
- [ ] API token minted with all scopes needed (scenarios + connections/hooks/
|
|
239
|
+
datastores as required) — scopes can't be widened later.
|
|
240
|
+
- [ ] Blueprint obtained by round-trip (template/existing), not hand-written.
|
|
241
|
+
- [ ] `blueprint` and `scheduling` sent as JSON **strings**; `teamId` set.
|
|
242
|
+
- [ ] Credentials referenced by connection id — no secrets in the blueprint.
|
|
243
|
+
- [ ] Dry-ran with `/run` and inspected output before `/start`.
|
|
244
|
+
- [ ] Blueprint exported to a file before any `DELETE`.
|
|
245
|
+
- [ ] For MCP: right transport for run length (`/stream`|`/sse` if >60 s), and
|
|
246
|
+
manager tools confirmed present only if the plan is paid.
|
|
247
|
+
|
|
248
|
+
## References
|
|
249
|
+
|
|
250
|
+
- `references/api-v2-cheatsheet.md` — endpoints, auth, scopes, rate limits, the
|
|
251
|
+
common response envelope, and error codes.
|
|
252
|
+
- `references/blueprint-round-trip.md` — the GET→mutate→POST recipe in depth,
|
|
253
|
+
blueprint anatomy, and the stringify gotcha.
|
|
254
|
+
- `references/make-mcp-and-auth.md` — MCP transports, tool tiers, client configs,
|
|
255
|
+
and the token-vs-OAuth decision.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Evals — make
|
|
2
|
+
|
|
3
|
+
`cases.yaml` holds three groups scored by an LLM judge against the rendered
|
|
4
|
+
skill. `should_trigger` confirms Make owns programmatic/MCP operation of a
|
|
5
|
+
Make.com account (create/run/clone/activate/delete scenarios, the blueprint
|
|
6
|
+
round-trip, the zone trap). `should_not_trigger` confirms clean deferral to the
|
|
7
|
+
real siblings — `automation-flows` for flow design, `automation-strategy` for
|
|
8
|
+
platform choice, `n8n` for that platform, `api-connector-builder` for generic
|
|
9
|
+
clients, `webhooks` for inbound receivers. The `capability` case checks the body
|
|
10
|
+
carries the load-bearing facts: the zoned/case-sensitive API, the
|
|
11
|
+
string-not-object blueprint/scheduling, the round-trip, run-before-start,
|
|
12
|
+
export-before-delete irreversibility, frozen token scopes, and the Make MCP
|
|
13
|
+
tiers. Run via the repo's eval runner; treat a miss as a cue to sharpen the
|
|
14
|
+
description's triggers/boundary or fill a body gap.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
skill: make
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Create a Make.com scenario from a blueprint via the API and activate it from my deploy script."
|
|
5
|
+
why: Core operate task — POST /scenarios with a blueprint string, then /start.
|
|
6
|
+
- prompt: "Export a Make scenario blueprint, change the Notion module's mapping, and push it back."
|
|
7
|
+
why: The blueprint round-trip (GET /blueprint → mutate → PATCH as a string) this skill owns.
|
|
8
|
+
- prompt: "My Make API token keeps returning an auth error even though it's valid and the scopes look right."
|
|
9
|
+
why: Classic zone trap — wrong {zone} in the base URL, not a token problem.
|
|
10
|
+
- prompt: "Connect the Make MCP server so Claude can run my scenarios as tools."
|
|
11
|
+
why: MCP transport + tool-tier setup; the agent-operator path.
|
|
12
|
+
- prompt: "Clone this Integromat scenario into another team and stop the original from a cron job."
|
|
13
|
+
why: /clone and /stop lifecycle endpoints driven programmatically.
|
|
14
|
+
- prompt: "Automatiza la creación de escenarios en Make.com desde la API, incluyendo teamId y scheduling."
|
|
15
|
+
why: Spanish phrasing of programmatic scenario creation; required teamId + scheduling string.
|
|
16
|
+
- prompt: "Read my Make org's real API rate limit before I bulk-update 200 scenarios."
|
|
17
|
+
why: GET /organizations/{id} → license.apiLimit, plus rate-limit awareness for API operation.
|
|
18
|
+
|
|
19
|
+
should_not_trigger:
|
|
20
|
+
- prompt: "Design a Make scenario that dedupes Stripe webhooks and has a proper error path before an external call."
|
|
21
|
+
route_to: automation-flows
|
|
22
|
+
why: Flow design (trigger, dedup, error handler) — build it there, then encode the blueprint here.
|
|
23
|
+
- prompt: "Should I use Make, n8n, or Zapier for 80k runs a month given the billing models?"
|
|
24
|
+
route_to: automation-strategy
|
|
25
|
+
why: Platform choice by cost model, not operating a Make account.
|
|
26
|
+
- prompt: "Create and activate an n8n workflow via its REST API."
|
|
27
|
+
route_to: n8n
|
|
28
|
+
why: Different platform; n8n has its own operate skill.
|
|
29
|
+
- prompt: "Build a typed TypeScript client for a REST API with OAuth refresh, pagination, and exponential backoff."
|
|
30
|
+
route_to: api-connector-builder
|
|
31
|
+
why: Generic API-client engineering, not Make-specific operation.
|
|
32
|
+
- prompt: "Verify the HMAC signature on inbound webhooks arriving at my Express endpoint and queue them."
|
|
33
|
+
route_to: webhooks
|
|
34
|
+
why: Inbound receiver in the user's own app, not Make's hooks API.
|
|
35
|
+
|
|
36
|
+
capability:
|
|
37
|
+
- scenario: "Programmatically create a Make scenario from a template blueprint, dry-run it, activate it, and later delete it safely — plus offer the Make MCP path for an agent operator."
|
|
38
|
+
must_include:
|
|
39
|
+
- "Zoned base URL https://{zone}.make.com/api/v2 with header Authorization: Token {token}, and the zone trap (wrong zone → auth error with a valid token)."
|
|
40
|
+
- "POST /scenarios requires teamId, plus blueprint and scheduling sent as JSON STRINGS (not objects)."
|
|
41
|
+
- "Blueprint round-trip: GET /scenarios/{id}/blueprint (or a template), mutate the JSON, send back as a string on create/PATCH."
|
|
42
|
+
- "Dry-run with POST /scenarios/{id}/run and inspect output before POST /scenarios/{id}/start to activate."
|
|
43
|
+
- "Irreversibility rule: export the blueprint to a file before DELETE /scenarios/{id} — deletion is permanent."
|
|
44
|
+
- "Token scopes are fixed at creation and cannot be widened later; endpoints are case-sensitive."
|
|
45
|
+
- "Make MCP server (GA, free; runs cost credits) via OAuth https://mcp.make.com or token URL https://{zone}.make.com/mcp/u/{MCP_TOKEN}/stateless|stream|sse, with run tools (all plans) vs management tools (paid)."
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Make API v2 — cheat-sheet
|
|
2
|
+
|
|
3
|
+
Current as of July 2026. Endpoints and query keys are **case-sensitive** and
|
|
4
|
+
every call is **zoned**. Verify anything you depend on at
|
|
5
|
+
[developers.make.com](https://developers.make.com/api-documentation) at author time.
|
|
6
|
+
|
|
7
|
+
## Base URL & auth
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
https://{zone}.make.com/api/v2
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- `{zone}` ∈ `eu1 | eu2 | us1 | us2` (plus `celonis` for that deployment). The
|
|
14
|
+
wrong zone returns an **authentication error** even with a valid token — this
|
|
15
|
+
is the single most common Make API mistake.
|
|
16
|
+
- Header: `Authorization: Token {MAKE_API_TOKEN}` — literal `Token`, a space,
|
|
17
|
+
the token. OAuth2 exists for multi-user apps.
|
|
18
|
+
- Content type for writes: `Content-Type: application/json`.
|
|
19
|
+
|
|
20
|
+
## Token scopes (frozen at creation)
|
|
21
|
+
|
|
22
|
+
Mint the token in **Profile → API/SDK**. You pick scopes **once**; they cannot
|
|
23
|
+
be widened afterward — a too-narrow token means minting a new one. Grant only
|
|
24
|
+
what you use, e.g. `scenarios:read scenarios:write connections:read
|
|
25
|
+
connections:write hooks:read hooks:write datastores:read datastores:write
|
|
26
|
+
teams:read organizations:read`.
|
|
27
|
+
|
|
28
|
+
## Response envelope
|
|
29
|
+
|
|
30
|
+
Most responses wrap the payload under a root key named for the resource, e.g.
|
|
31
|
+
`{ "scenario": {...} }`, `{ "scenarios": [...] }`, `{ "response": { "blueprint": {...} } }`.
|
|
32
|
+
Extract with `jq '.scenario'` etc. **Confirm the exact wrapper per endpoint at
|
|
33
|
+
author time** — a few endpoints differ.
|
|
34
|
+
|
|
35
|
+
## Endpoint map
|
|
36
|
+
|
|
37
|
+
### Scenarios (the core)
|
|
38
|
+
|
|
39
|
+
| Method | Path | Notes |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| GET | `/scenarios?teamId={id}` | list; paginate with `pg[limit]` / `pg[offset]` |
|
|
42
|
+
| POST | `/scenarios` | body: `teamId` (int), `blueprint` (**string**), `scheduling` (**string**); optional `folderId`, `basedon` |
|
|
43
|
+
| GET | `/scenarios/{id}` | metadata (not the blueprint) |
|
|
44
|
+
| PATCH | `/scenarios/{id}` | update — send `blueprint`/`scheduling`/`name` as strings |
|
|
45
|
+
| DELETE | `/scenarios/{id}` | **permanent, no trash** — export blueprint first |
|
|
46
|
+
| GET | `/scenarios/{id}/blueprint` | the editable JSON (round-trip source) |
|
|
47
|
+
| POST | `/scenarios/{id}/start` | activate scheduled execution |
|
|
48
|
+
| POST | `/scenarios/{id}/stop` | deactivate |
|
|
49
|
+
| POST | `/scenarios/{id}/run` | one manual run; `{"responsive":true}` waits for result |
|
|
50
|
+
| POST | `/scenarios/{id}/clone` | body `{teamId, name}` — copy into a team |
|
|
51
|
+
|
|
52
|
+
### Connections
|
|
53
|
+
|
|
54
|
+
`GET/POST /connections`, `GET/DELETE /connections/{id}`,
|
|
55
|
+
`POST /connections/{id}/test`. Modules reference a connection **by id** for app
|
|
56
|
+
auth — the blueprint holds the id, never the secret.
|
|
57
|
+
|
|
58
|
+
### Hooks (Make's inbound webhooks/mailhooks)
|
|
59
|
+
|
|
60
|
+
`GET/POST /hooks`, `GET/DELETE /hooks/{id}`, `POST /hooks/{id}/ping`,
|
|
61
|
+
`POST /hooks/{id}/learn-start` / `learn-stop` (structure learning). This is
|
|
62
|
+
Make's *own* webhook receiver; building an inbound endpoint in **your** app is
|
|
63
|
+
the `webhooks` skill.
|
|
64
|
+
|
|
65
|
+
### Data stores
|
|
66
|
+
|
|
67
|
+
`GET/POST /data-stores`, `GET/DELETE /data-stores/{id}`,
|
|
68
|
+
`GET/POST/DELETE /data-stores/{id}/data`. The idiomatic place for dedup keys and
|
|
69
|
+
cross-run state (see `automation-flows` for the dedup pattern).
|
|
70
|
+
|
|
71
|
+
### Templates
|
|
72
|
+
|
|
73
|
+
`GET /templates`, `GET /templates/{id}/blueprint`. A published template's
|
|
74
|
+
blueprint is the cleanest round-trip starting point.
|
|
75
|
+
|
|
76
|
+
### Teams & organizations
|
|
77
|
+
|
|
78
|
+
`GET /teams?organizationId={id}`, `GET /organizations/{id}`. Read your real
|
|
79
|
+
rate ceiling: `GET /organizations/{id}` → `license.apiLimit`.
|
|
80
|
+
|
|
81
|
+
## Rate limits (req/min, per plan)
|
|
82
|
+
|
|
83
|
+
| Plan | Limit |
|
|
84
|
+
|---|---|
|
|
85
|
+
| Core | 60 |
|
|
86
|
+
| Pro | 120 |
|
|
87
|
+
| Teams | 240 |
|
|
88
|
+
| Enterprise | 1000 |
|
|
89
|
+
|
|
90
|
+
Don't hard-code it — read `license.apiLimit` from your own org. On `429`, back
|
|
91
|
+
off and retry (generic retry/backoff engineering: `api-connector-builder`).
|
|
92
|
+
|
|
93
|
+
## Scheduling string
|
|
94
|
+
|
|
95
|
+
`scheduling` is a JSON **string**. Common shapes (verify fields at author time):
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{"type":"on-demand"}
|
|
99
|
+
{"type":"indefinitely","interval":900} // interval in seconds
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`on-demand` scenarios run only via `/run` or a webhook trigger; `indefinitely`
|
|
103
|
+
runs on the interval once `/start`ed.
|
|
104
|
+
|
|
105
|
+
## Errors you will actually hit
|
|
106
|
+
|
|
107
|
+
| Symptom | Cause | Fix |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| Auth error with a valid token | wrong `{zone}` | match the org's zone |
|
|
110
|
+
| 400 on create | `blueprint`/`scheduling` sent as objects | stringify them |
|
|
111
|
+
| 400 naming a module/field | malformed blueprint | fix that node, re-POST |
|
|
112
|
+
| 403 on a valid endpoint | token missing that scope | re-mint with the scope |
|
|
113
|
+
| 404 on a path that should exist | wrong case in the path | fix casing |
|
|
114
|
+
| 429 | over plan rate limit | back off; read `apiLimit` |
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# The blueprint round-trip
|
|
2
|
+
|
|
3
|
+
You almost never author a Make blueprint by hand. You **export** one, **mutate**
|
|
4
|
+
the JSON, and **send it back as a string**. This file is that recipe in depth.
|
|
5
|
+
|
|
6
|
+
## Why round-trip
|
|
7
|
+
|
|
8
|
+
A blueprint is a large, only-partially-documented JSON structure. Writing one
|
|
9
|
+
from scratch means guessing internal module parameter keys and metadata that the
|
|
10
|
+
create endpoint will reject. Exporting a working scenario (or a published
|
|
11
|
+
template) gives you a guaranteed-valid skeleton to edit — the diff you make is
|
|
12
|
+
small and reviewable.
|
|
13
|
+
|
|
14
|
+
## Blueprint anatomy (top level)
|
|
15
|
+
|
|
16
|
+
```jsonc
|
|
17
|
+
{
|
|
18
|
+
"name": "My scenario",
|
|
19
|
+
"flow": [ // ordered modules — index 1, 2, 3…
|
|
20
|
+
{
|
|
21
|
+
"id": 1,
|
|
22
|
+
"module": "gateway:CustomWebHook", // module type
|
|
23
|
+
"version": 1,
|
|
24
|
+
"parameters": { "hook": 123456 }, // references a hook by id
|
|
25
|
+
"mapper": {}, // inbound mapping for this module
|
|
26
|
+
"metadata": { "designer": { "x": 0, "y": 0 } }
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": 2,
|
|
30
|
+
"module": "notion:createDatabaseItem",
|
|
31
|
+
"version": 2,
|
|
32
|
+
"parameters": { "__IMTCONN__": 78910 }, // connection id — NOT a secret
|
|
33
|
+
"mapper": { "title": "{{1.body.name}}" } // maps module 1's output
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"metadata": {
|
|
37
|
+
"instant": true,
|
|
38
|
+
"scenario": { "roundtrips": 1, "maxErrors": 3, "autoCommit": true },
|
|
39
|
+
"designer": { "orphans": [] }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Key ideas:
|
|
45
|
+
|
|
46
|
+
- **`flow`** is the ordered module list. Each module has an integer `id`; a
|
|
47
|
+
trigger sits at index 1.
|
|
48
|
+
- **Mapping** is `{{sourceId.path}}` — `{{1.body.name}}` = module 1's
|
|
49
|
+
`body.name`. This is the same mapping `automation-flows` designs; here you are
|
|
50
|
+
only serializing it.
|
|
51
|
+
- **Connections and hooks are referenced by id** (`__IMTCONN__`, `parameters.hook`).
|
|
52
|
+
Create the connection/hook first (or reuse one), put its id here. Never inline
|
|
53
|
+
an API key or token.
|
|
54
|
+
- **Routers/branches** appear as nested `routes` arrays inside a router module.
|
|
55
|
+
- `metadata.scenario` carries run settings (max errors, sequential processing,
|
|
56
|
+
auto-commit) — design decisions from `automation-flows`, encoded here.
|
|
57
|
+
|
|
58
|
+
## Step 1 — export
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
curl -s -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
62
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$SRC_ID/blueprint" \
|
|
63
|
+
| jq '.response.blueprint' > bp.json # verify the .response.blueprint wrapper at author time
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or from a template: `GET /templates/{id}/blueprint`.
|
|
67
|
+
|
|
68
|
+
## Step 2 — mutate
|
|
69
|
+
|
|
70
|
+
Edit `bp.json`: rename it, repoint `parameters.__IMTCONN__` /
|
|
71
|
+
`parameters.hook` at *your* connection/hook ids, adjust `mapper` expressions,
|
|
72
|
+
add/remove modules in `flow`. If you add a module, give it a fresh integer `id`
|
|
73
|
+
and wire downstream mappers to it.
|
|
74
|
+
|
|
75
|
+
Validate it is still JSON before sending:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
jq empty bp.json && echo "valid json"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Step 3 — send back as a STRING
|
|
82
|
+
|
|
83
|
+
The create/update endpoints want `blueprint` (and `scheduling`) as JSON
|
|
84
|
+
**strings**, not objects. Build the body with `jq` so the stringify is correct:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# CREATE
|
|
88
|
+
curl -s -X POST -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
89
|
+
-H "Content-Type: application/json" \
|
|
90
|
+
"https://$MAKE_ZONE/api/v2/scenarios" \
|
|
91
|
+
-d "$(jq -n \
|
|
92
|
+
--argjson team "$MAKE_TEAM_ID" \
|
|
93
|
+
--arg bp "$(jq -c . bp.json)" \
|
|
94
|
+
--arg sched '{"type":"on-demand"}' \
|
|
95
|
+
'{teamId:$team, blueprint:$bp, scheduling:$sched}')"
|
|
96
|
+
|
|
97
|
+
# UPDATE (same scenario)
|
|
98
|
+
curl -s -X PATCH -H "Authorization: Token $MAKE_API_TOKEN" \
|
|
99
|
+
-H "Content-Type: application/json" \
|
|
100
|
+
"https://$MAKE_ZONE/api/v2/scenarios/$ID" \
|
|
101
|
+
-d "$(jq -n --arg bp "$(jq -c . bp.json)" '{blueprint:$bp}')"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`jq -c . bp.json` compacts the blueprint to one line; passing it via `--arg`
|
|
105
|
+
makes it a **string** field. `--argjson team` keeps `teamId` a number.
|
|
106
|
+
|
|
107
|
+
## The stringify gotcha
|
|
108
|
+
|
|
109
|
+
The most common failure is sending `blueprint` as a nested object:
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
// WRONG — object, 400
|
|
113
|
+
{ "teamId": 123, "blueprint": { "flow": [ ... ] }, "scheduling": {"type":"on-demand"} }
|
|
114
|
+
|
|
115
|
+
// RIGHT — string
|
|
116
|
+
{ "teamId": 123, "blueprint": "{\"flow\":[...]}", "scheduling": "{\"type\":\"on-demand\"}" }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If you build the request in Python/JS, `json.dumps()` / `JSON.stringify()` the
|
|
120
|
+
blueprint value itself and assign the resulting string.
|
|
121
|
+
|
|
122
|
+
## Verify, then activate
|
|
123
|
+
|
|
124
|
+
The create/PATCH call is the validator — a bad blueprint returns a 400 naming
|
|
125
|
+
the offending module. On success, dry-run with `POST /scenarios/{id}/run`
|
|
126
|
+
(`{"responsive":true}` to get the output inline), inspect the bundle, then
|
|
127
|
+
`POST /scenarios/{id}/start`. Before any `DELETE`, re-export the blueprint to a
|
|
128
|
+
file — deletion is permanent.
|