Netlify
Access the Netlify API with managed OAuth authentication. Manage sites, deploys, builds, DNS zones, environment variables, and webhooks.
Quick Start
# List all sites
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/netlify/api/v1/sites')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/netlify/{native-api-path}
Replace {native-api-path} with the actual Netlify API endpoint path. The gateway proxies requests to api.netlify.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Netlify OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=netlify&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'netlify'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "9e674cd3-2280-4eb4-9ff7-b12ec8ca3f55",
"status": "ACTIVE",
"creation_time": "2026-02-12T11:15:33.183756Z",
"last_updated_time": "2026-02-12T11:15:51.556556Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "netlify",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Netlify connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/netlify/api/v1/sites')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '9e674cd3-2280-4eb4-9ff7-b12ec8ca3f55')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
User & Accounts
Get Current User
GET /netlify/api/v1/user
List Accounts
GET /netlify/api/v1/accounts
Get Account
GET /netlify/api/v1/accounts/{account_id}
Sites
List Sites
GET /netlify/api/v1/sites
With filtering:
GET /netlify/api/v1/sites?filter=all&page=1&per_page=100
Get Site
GET /netlify/api/v1/sites/{site_id}
Create Site
POST /netlify/api/v1/{account_slug}/sites
Content-Type: application/json
{
"name": "my-new-site"
}
Update Site
PUT /netlify/api/v1/sites/{site_id}
Content-Type: application/json
{
"name": "updated-site-name"
}
Delete Site
DELETE /netlify/api/v1/sites/{site_id}
Deploys
List Deploys
GET /netlify/api/v1/sites/{site_id}/deploys
Get Deploy
GET /netlify/api/v1/deploys/{deploy_id}
Create Deploy
POST /netlify/api/v1/sites/{site_id}/deploys
Content-Type: application/json
{
"title": "Deploy from API"
}
Lock Deploy
POST /netlify/api/v1/deploys/{deploy_id}/lock
Unlock Deploy
POST /netlify/api/v1/deploys/{deploy_id}/unlock
Restore Deploy (Rollback)
PUT /netlify/api/v1/deploys/{deploy_id}
Builds
List Builds
GET /netlify/api/v1/sites/{site_id}/builds
Get Build
GET /netlify/api/v1/builds/{build_id}
Trigger Build
POST /netlify/api/v1/sites/{site_id}/builds
Environment Variables
Environment variables are managed at the account level with optional site scope.
List Environment Variables
GET /netlify/api/v1/accounts/{account_id}/env?site_id={site_id}
Create Environment Variables
POST /netlify/api/v1/accounts/{account_id}/env?site_id={site_id}
Content-Type: application/json
[
{
"key": "MY_VAR",
"values": [
{"value": "my_value", "context": "all"}
]
}
]
Context values: all, production, deploy-preview, branch-deploy, dev
Update Environment Variable
PUT /netlify/api/v1/accounts/{account_id}/env/{key}?site_id={site_id}
Content-Type: application/json
{
"key": "MY_VAR",
"values": [
{"value": "updated_value", "context": "all"}
]
}
Delete Environment Variable
DELETE /netlify/api/v1/accounts/{account_id}/env/{key}?site_id={site_id}
DNS Zones
List DNS Zones
GET /netlify/api/v1/dns_zones
Create DNS Zone
POST /netlify/api/v1/dns_zones
Content-Type: application/json
{
"name": "example.com",
"account_slug": "my-account"
}
Get DNS Zone
GET /netlify/api/v1/dns_zones/{zone_id}
Delete DNS Zone
DELETE /netlify/api/v1/dns_zones/{zone_id}
DNS Records
List DNS Records
GET /netlify/api/v1/dns_zones/{zone_id}/dns_records
Create DNS Record
POST /netlify/api/v1/dns_zones/{zone_id}/dns_records
Content-Type: application/json
{
"type": "A",
"hostname": "www",
"value": "192.0.2.1",
"ttl": 3600
}
Delete DNS Record
DELETE /netlify/api/v1/dns_zones/{zone_id}/dns_records/{record_id}
Build Hooks
List Build Hooks
GET /netlify/api/v1/sites/{site_id}/build_hooks
Create Build Hook
POST /netlify/api/v1/sites/{site_id}/build_hooks
Content-Type: application/json
{
"title": "My Build Hook",
"branch": "main"
}
Response includes a url that can be POSTed to trigger a build.
Delete Build Hook
DELETE /netlify/api/v1/hooks/{hook_id}
Webhooks
List Webhooks
GET /netlify/api/v1/hooks?site_id={site_id}
Create Webhook
POST /netlify/api/v1/hooks?site_id={site_id}
Content-Type: application/json
{
"type": "url",
"event": "deploy_created",
"data": {
"url": "https://example.com/webhook"
}
}
Events: deploy_created, deploy_building, deploy_failed, deploy_succeeded, form_submission
Delete Webhook
DELETE /netlify/api/v1/hooks/{hook_id}
Forms
List Forms
GET /netlify/api/v1/sites/{site_id}/forms
List Form Submissions
GET /netlify/api/v1/sites/{site_id}/submissions
Delete Form
DELETE /netlify/api/v1/sites/{site_id}/forms/{form_id}
Functions
List Functions
GET /netlify/api/v1/sites/{site_id}/functions
Services/Add-ons
List Available Services
GET /netlify/api/v1/services
Get Service Details
GET /netlify/api/v1/services/{service_id}
Pagination
Use page and per_page query parameters:
GET /netlify/api/v1/sites?page=1&per_page=100
Default per_page varies by endpoint. Check response headers for pagination info.
Code Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/netlify/api/v1/sites',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const sites = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/netlify/api/v1/sites',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
sites = response.json()
Create Site and Set Environment Variable
import os
import requests
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Create site
site = requests.post(
'https://gateway.maton.ai/netlify/api/v1/my-account/sites',
headers=headers,
json={'name': 'my-new-site'}
).json()
# Add environment variable
requests.post(
f'https://gateway.maton.ai/netlify/api/v1/accounts/{site["account_id"]}/env',
headers=headers,
params={'site_id': site['id']},
json=[{'key': 'API_KEY', 'values': [{'value': 'secret', 'context': 'all'}]}]
)
Notes
- Site IDs are UUIDs (e.g.,
d37d1ce4-5444-40f5-a4ca-a2c40a8b6835) - Account slugs are used for creating sites within a team (e.g.,
my-team-slug) - Deploy IDs are returned when creating deploys and can be used to track deploy status
- Build hooks return a URL that can be POSTed to externally trigger builds
- Environment variable contexts control where variables are available:
all,production,deploy-preview,branch-deploy,dev - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing Netlify connection |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Netlify API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
netlify. For example:
- Correct:
https://gateway.maton.ai/netlify/api/v1/sites - Incorrect:
https://gateway.maton.ai/api/v1/sites