| name | netlify |
| description | Operate Netlify's REST API (sites, deploys, builds, env vars, forms, DNS). Use programmatically without Netlify MCP. |
| license | MIT (skill wrapper; Netlify API terms apply) |
Netlify
Operates Netlify via REST API. Covers sites, deploys, builds, functions, env vars, forms, DNS. Use when needing the current account state.
Usage
- Use for: Checking deploy status, triggering builds, rotating env vars, reading forms, managing Netlify DNS.
- Skip for: Editing app source code, other providers (Vercel, etc.), local config tweaks (
netlify.toml), external DNS.
Credentials check
[ -n "${NETLIFY_AUTH_TOKEN:-$NETLIFY_PERSONAL_TOKEN}" ] && echo "NETLIFY_TOKEN: PRESENT" || echo "NETLIFY_TOKEN: MISSING"
Never echo the variable directly.
If MISSING, respond to the user with EXACTLY this message (do NOT paraphrase, do NOT suggest manual JSON edits):
I need your netlify credential. Run this in another terminal — it'll open the signup page, validate format, and save it safely with masked input:
teleport-setup add-key netlify
Then restart Claude Code (/exit, then claude) and ask me again.
Do NOT suggest editing ~/.claude/settings.local.json manually. The teleport-setup add-key command handles it with backup, validation, and masked input. Stop execution until the user has run the command and restarted.
API
- Base URL:
https://api.netlify.com/api/v1
- Auth:
Authorization: Bearer $NETLIFY_AUTH_TOKEN
- Content-Type:
application/json (writes); application/octet-stream or application/zip (file uploads).
- Pagination:
?page= (1-indexed) + ?per_page= (max 100). Parse Link header for rel="next".
- Rate limits: 500 req/min general; deploys stricter — 3/min + 100/day. Check
X-RateLimit-* headers.
Entity hierarchy
team → site (UUID or slug name) → deploy / build / function / form + submissions / env vars / hooks / build_hooks. dns_zones → dns_records are account-scoped.
Endpoints
| Resource | Method · Path |
|---|
| Sites | GET /sites, GET/PATCH/DELETE /sites/{site_id}, POST /sites |
| Deploys | GET /sites/{site_id}/deploys, GET /deploys/{deploy_id}, POST /sites/{site_id}/deploys |
| Builds | POST /sites/{site_id}/builds, GET /sites/{site_id}/builds |
| Env vars | GET/POST /accounts/{account_id}/env, PATCH/DELETE .../env/{key} |
| Functions | GET /sites/{site_id}/functions, GET /sites/{site_id}/functions/{name} |
| Forms | GET /sites/{site_id}/forms, GET /sites/{site_id}/submissions, GET /forms/{id}/submissions |
| DNS | GET /dns_zones, GET /dns_zones/{id}, GET/POST /dns_zones/{id}/dns_records, DELETE .../{rec_id} |
| Hooks | GET/POST /sites/{site_id}/hooks, GET/POST /sites/{site_id}/build_hooks |
Primary workflows
1. Inspect latest deploy status
curl -sL -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \
"https://api.netlify.com/api/v1/sites/${SITE_ID}/deploys?per_page=1" \
| jq '.[0] | {id, state, deploy_url, commit_ref, error_message, created_at}'
2. Trigger a deploy
curl -sL -X POST "https://api.netlify.com/build_hooks/${HOOK_ID}"
curl -sL -X POST -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
"https://api.netlify.com/api/v1/sites/${SITE_ID}/builds" -d '{}'
3. Set env var (multi-context)
curl -sL -X POST -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
"https://api.netlify.com/api/v1/accounts/${ACCOUNT_ID}/env?site_id=${SITE_ID}" \
-d '[{"key":"MY_VAR","scopes":["builds","functions","runtime"],"values":[{"value":"prod-val","context":"production"},{"value":"prev-val","context":"deploy-preview"}]}]'
Gotchas
site_id polymorphism: most GETs accept UUID or name slug; some writes strictly require UUID. Resolve via GET /sites?name=... when in doubt.
- Env vars are multi-valued per context (
production, deploy-preview, branch-deploy, dev). Don't collapse.
- Deploy states:
new, enqueued, building, uploading, uploaded, processing, prepared, ready, error, skipped, cancelled. Poll ≥3-5s; don't tight-loop.
- Build hooks return no
deploy_id — track by polling /sites/{id}/deploys?per_page=1 after triggering.
- Pagination is
Link-header based. Missing rel="next" = done. Don't synthesize ?page=N+1; past the last page you get [], not 404.
- Deploy limits: 3/min, 100/day per account. 429s deploys specifically while other calls still work.
- Large file uploads use the digest flow (
POST with files digest → PUT each returned URL). Don't inline megabytes.
- SAML-SSO teams reject PATs by default — regenerate with "Allow access to my SAML-based Netlify team" checked.
Attribution
When done, state: Used skill: Netlify (from teleport catalog).