Install
openclaw skills install snapchatSnapchat Marketing API integration with managed OAuth. Manage ad accounts, campaigns, ad squads, ads, creatives, and audiences. Use this skill when users want to create and manage Snapchat advertising campaigns, view ad performance stats, or manage targeting. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
openclaw skills install snapchatAccess the Snapchat Marketing API with managed OAuth authentication. Manage organizations, ad accounts, campaigns, ad squads, ads, creatives, media, and audiences.
# List your organizations
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/snapchat/v1/me/organizations')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/snapchat/{api-path}
The Snapchat Marketing API uses the path pattern:
https://api.maton.ai/snapchat/v1/{resource}
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"
Manage your Snapchat OAuth connections at https://api.maton.ai.
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=snapchat&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
python3 <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'snapchat'}).encode()
req = urllib.request.Request('https://api.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
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-14T00:00:00.000000Z",
"last_updated_time": "2026-02-14T00:00:00.000000Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "snapchat",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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
If you have multiple Snapchat connections, specify which one to use with the Maton-Connection header:
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/snapchat/v1/me/organizations')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
GET /v1/me
Response:
{
"request_status": "SUCCESS",
"request_id": "...",
"me": {
"id": "...",
"email": "user@example.com",
"display_name": "User Name"
}
}
GET /v1/me/organizations
Response:
{
"request_status": "SUCCESS",
"request_id": "...",
"organizations": [
{
"sub_request_status": "SUCCESS",
"organization": {
"id": "63acee69-77ff-4378-8492-3f8d28e8f241",
"name": "My Organization",
"country": "US",
"contact_name": "John Doe",
"contact_email": "john@example.com"
}
}
]
}
GET /v1/organizations/{organizationId}
GET /v1/organizations/{organizationId}/adaccounts
GET /v1/organizations/{organizationId}/fundingsources
GET /v1/organizations/{organizationId}/members
GET /v1/organizations/{organizationId}/roles
GET /v1/organizations/{organizationId}/catalogs
GET /v1/adaccounts/{adAccountId}
Response:
{
"request_status": "SUCCESS",
"request_id": "...",
"adaccounts": [
{
"sub_request_status": "SUCCESS",
"adaccount": {
"id": "6e916ba9-db2f-40cd-9553-a90e32cedea3",
"name": "My Ad Account",
"type": "PARTNER",
"status": "ACTIVE",
"organization_id": "...",
"currency": "USD",
"timezone": "America/Los_Angeles"
}
}
]
}
GET /v1/adaccounts/{adAccountId}/roles
GET /v1/adaccounts/{adAccountId}/campaigns
GET /v1/adaccounts/{adAccountId}/campaigns?limit=50
Query Parameters:
limit - Number of results (50-1000)GET /v1/campaigns/{campaignId}
POST /v1/adaccounts/{adAccountId}/campaigns
Content-Type: application/json
{
"campaigns": [{
"name": "Campaign Name",
"status": "PAUSED",
"ad_account_id": "{adAccountId}",
"start_time": "2026-02-15T00:00:00.000-08:00"
}]
}
PUT /v1/adaccounts/{adAccountId}/campaigns
Content-Type: application/json
{
"campaigns": [{
"id": "{campaignId}",
"name": "Updated Campaign Name",
"status": "ACTIVE"
}]
}
DELETE /v1/campaigns/{campaignId}
GET /v1/adaccounts/{adAccountId}/adsquads
GET /v1/campaigns/{campaignId}/adsquads
GET /v1/adsquads/{adSquadId}
POST /v1/campaigns/{campaignId}/adsquads
Content-Type: application/json
{
"adsquads": [{
"name": "Ad Squad Name",
"status": "PAUSED",
"campaign_id": "{campaignId}",
"type": "SNAP_ADS",
"placement": "SNAP_ADS",
"optimization_goal": "IMPRESSIONS",
"bid_micro": 1000000,
"daily_budget_micro": 50000000,
"start_time": "2026-02-15T00:00:00.000-08:00",
"targeting": {
"geos": [{"country_code": "us"}]
}
}]
}
PUT /v1/campaigns/{campaignId}/adsquads
Content-Type: application/json
{
"adsquads": [{
"id": "{adSquadId}",
"name": "Updated Ad Squad Name"
}]
}
DELETE /v1/adsquads/{adSquadId}
GET /v1/adaccounts/{adAccountId}/ads
GET /v1/adsquads/{adSquadId}/ads
GET /v1/ads/{adId}
POST /v1/adsquads/{adSquadId}/ads
Content-Type: application/json
{
"ads": [{
"name": "Ad Name",
"status": "PAUSED",
"ad_squad_id": "{adSquadId}",
"creative_id": "{creativeId}",
"type": "SNAP_AD"
}]
}
PUT /v1/adsquads/{adSquadId}/ads
Content-Type: application/json
{
"ads": [{
"id": "{adId}",
"name": "Updated Ad Name"
}]
}
DELETE /v1/ads/{adId}
GET /v1/adaccounts/{adAccountId}/creatives
GET /v1/adaccounts/{adAccountId}/creatives?limit=50&sort=updated_at-desc
GET /v1/creatives/{creativeId}
POST /v1/adaccounts/{adAccountId}/creatives
Content-Type: application/json
{
"creatives": [{
"name": "Creative Name",
"ad_account_id": "{adAccountId}",
"type": "SNAP_AD",
"top_snap_media_id": "{mediaId}",
"headline": "Headline Text",
"brand_name": "Brand Name",
"call_to_action": "VIEW_MORE"
}]
}
PUT /v1/adaccounts/{adAccountId}/creatives
Content-Type: application/json
{
"creatives": [{
"id": "{creativeId}",
"name": "Updated Creative Name"
}]
}
GET /v1/adaccounts/{adAccountId}/media
GET /v1/adaccounts/{adAccountId}/media?limit=50&sort=created_at-desc
GET /v1/media/{mediaId}
GET /v1/adaccounts/{adAccountId}/pixels
GET /v1/pixels/{pixelId}
GET /v1/adaccounts/{adAccountId}/segments
GET /v1/segments/{segmentId}
GET /v1/adaccounts/{adAccountId}/stats?granularity=DAY&start_time=2026-02-01&end_time=2026-02-14
Query Parameters:
granularity - HOUR, DAY, LIFETIMEstart_time - Start date (YYYY-MM-DD)end_time - End date (YYYY-MM-DD)GET /v1/campaigns/{campaignId}/stats?granularity=DAY&start_time=2026-02-01&end_time=2026-02-14
GET /v1/targeting/geo/country
GET /v1/targeting/geo/{countryCode}/region
Example: GET /v1/targeting/geo/us/region
GET /v1/targeting/device/os_type
GET /v1/targeting/location/categories_loi
The Ads Gallery API provides access to Snapchat's public advertising transparency library. This API does not require authentication but can be accessed through the gateway.
GET /v1/ads_library/sponsored_content
Response:
{
"request_status": "SUCCESS",
"request_id": "...",
"sponsored_content": [
{
"sub_request_status": "SUCCESS",
"sponsored_content": {
"id": "...",
"name": "Content Name",
"status": "ACTIVE"
}
}
]
}
POST /v1/ads_library/sponsored_content/search
Content-Type: application/json
{
"limit": 50
}
Search for ads in the public Ads Library by advertiser name and country.
POST /v1/ads_library/ads/search
Content-Type: application/json
{
"paying_advertiser_name": "Nike",
"countries": ["fr", "de"],
"limit": 50
}
Parameters:
paying_advertiser_name (required) - Advertiser name to search forcountries (required) - Array of lowercase 2-letter ISO country codes (e.g., ["fr", "de", "gb"])start_date - ISO 8601 timestamp for date range startend_date - ISO 8601 timestamp for date range endstatus - Filter by status (e.g., "ACTIVE", "PAUSED")limit - Number of results to returnNote: Not all countries are available in the Ads Library. EU countries (fr, de, gb, etc.) are supported. US ads may not be available due to regional restrictions.
Response:
{
"request_status": "SUCCESS",
"request_id": "...",
"paging": {
"next_link": "..."
},
"ad_previews": [
{
"sub_request_status": "SUCCESS",
"ad_preview": {
"id": "...",
"name": "Ad Name",
"ad_account_name": "Advertiser Name",
"status": "ACTIVE",
"creative_type": "WEB_VIEW",
"headline": "Ad Headline",
"call_to_action": "SHOP NOW"
}
}
]
}
The Snapchat API uses cursor-based pagination with the limit parameter (50-1000) and returns a paging object with next_link.
GET /v1/adaccounts/{adAccountId}/campaigns?limit=50
Response:
{
"request_status": "SUCCESS",
"campaigns": [...],
"paging": {
"next_link": "https://adsapi.snapchat.com/v1/adaccounts/{id}/campaigns?cursor=..."
}
}
To get the next page, use the next_link URL (replace host with gateway):
GET /v1/adaccounts/{adAccountId}/campaigns?cursor=...
Some endpoints support sorting with the sort parameter:
GET /v1/adaccounts/{adAccountId}/creatives?sort=updated_at-desc
GET /v1/adaccounts/{adAccountId}/media?sort=created_at-desc
Supported values: updated_at-desc, created_at-desc
// List organizations
const response = await fetch(
'https://api.maton.ai/snapchat/v1/me/organizations',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
console.log(data.organizations);
import os
import requests
# List organizations
response = requests.get(
'https://api.maton.ai/snapchat/v1/me/organizations',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
print(data['organizations'])
import os
import requests
org_id = "YOUR_ORG_ID"
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Get ad accounts
response = requests.get(
f'https://api.maton.ai/snapchat/v1/organizations/{org_id}/adaccounts',
headers=headers
)
ad_accounts = response.json()['adaccounts']
# List campaigns for each ad account
for aa in ad_accounts:
ad_account_id = aa['adaccount']['id']
campaigns = requests.get(
f'https://api.maton.ai/snapchat/v1/adaccounts/{ad_account_id}/campaigns',
headers=headers
).json()
print(f"Ad Account: {aa['adaccount']['name']}")
print(f"Campaigns: {campaigns}")
request_status, request_id, and entity arrays with sub_request_status2026-02-15T00:00:00.000-08:00)tr.snapchat.com) and is not currently routed through this gateway.jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Bad request or invalid parameters |
| 401 | Invalid API key or expired token |
| 403 | Permission denied |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Snapchat API |
{
"request_status": "ERROR",
"request_id": "...",
"debug_message": "Error details",
"display_message": "User-friendly message"
}