Snapchat
by @byungkyu
Snapchat Marketing API integration with managed OAuth. Manage ad accounts, campaigns, ad squads, ads, creatives, and audiences. Use this skill when users wan...
clawhub install snapchatπ About This Skill
name: snapchat description: | Snapchat 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. metadata: author: maton version: "1.0" clawdbot: emoji: π§ homepage: "https://maton.ai" requires: env: - MATON_API_KEY
Snapchat
Access the Snapchat Marketing API with managed OAuth authentication. Manage organizations, ad accounts, campaigns, ad squads, ads, creatives, media, and audiences.
Quick Start
# 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
Base URL
https://api.maton.ai/snapchat/{api-path}
The Snapchat Marketing API uses the path pattern:
https://api.maton.ai/snapchat/v1/{resource}
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
1. Sign in or create an account at maton.ai 2. Go to maton.ai/settings 3. Copy your API key
Connection Management
Manage your Snapchat OAuth connections at https://api.maton.ai.
List Connections
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
Create Connection
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
Get Connection
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.
Delete Connection
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
Specifying Connection
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.
Security & Permissions
API Reference
Current User
#### Get Current User
GET /v1/me
Response:
{
"request_status": "SUCCESS",
"request_id": "...",
"me": {
"id": "...",
"email": "user@example.com",
"display_name": "User Name"
}
}
#### List My Organizations
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"
}
}
]
}
Organizations
#### Get Organization
GET /v1/organizations/{organizationId}
#### List Organization Ad Accounts
GET /v1/organizations/{organizationId}/adaccounts
#### List Organization Funding Sources
GET /v1/organizations/{organizationId}/fundingsources
#### List Organization Members
GET /v1/organizations/{organizationId}/members
#### List Organization Roles
GET /v1/organizations/{organizationId}/roles
#### List Product Catalogs
GET /v1/organizations/{organizationId}/catalogs
Ad Accounts
#### Get Ad Account
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"
}
}
]
}
#### List Ad Account Roles
GET /v1/adaccounts/{adAccountId}/roles
Campaigns
#### List Campaigns
GET /v1/adaccounts/{adAccountId}/campaigns
GET /v1/adaccounts/{adAccountId}/campaigns?limit=50
Query Parameters:
limit - Number of results (50-1000)#### Get Campaign
GET /v1/campaigns/{campaignId}
#### Create Campaign
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"
}]
}
#### Update Campaign
PUT /v1/adaccounts/{adAccountId}/campaigns
Content-Type: application/json{
"campaigns": [{
"id": "{campaignId}",
"name": "Updated Campaign Name",
"status": "ACTIVE"
}]
}
#### Delete Campaign
DELETE /v1/campaigns/{campaignId}
Ad Squads
#### List Ad Squads
GET /v1/adaccounts/{adAccountId}/adsquads
GET /v1/campaigns/{campaignId}/adsquads
#### Get Ad Squad
GET /v1/adsquads/{adSquadId}
#### Create Ad Squad
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"}]
}
}]
}
#### Update Ad Squad
PUT /v1/campaigns/{campaignId}/adsquads
Content-Type: application/json{
"adsquads": [{
"id": "{adSquadId}",
"name": "Updated Ad Squad Name"
}]
}
#### Delete Ad Squad
DELETE /v1/adsquads/{adSquadId}
Ads
#### List Ads
GET /v1/adaccounts/{adAccountId}/ads
GET /v1/adsquads/{adSquadId}/ads
#### Get Ad
GET /v1/ads/{adId}
#### Create Ad
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"
}]
}
#### Update Ad
PUT /v1/adsquads/{adSquadId}/ads
Content-Type: application/json{
"ads": [{
"id": "{adId}",
"name": "Updated Ad Name"
}]
}
#### Delete Ad
DELETE /v1/ads/{adId}
Creatives
#### List Creatives
GET /v1/adaccounts/{adAccountId}/creatives
GET /v1/adaccounts/{adAccountId}/creatives?limit=50&sort=updated_at-desc
#### Get Creative
GET /v1/creatives/{creativeId}
#### Create Creative
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"
}]
}
#### Update Creative
PUT /v1/adaccounts/{adAccountId}/creatives
Content-Type: application/json{
"creatives": [{
"id": "{creativeId}",
"name": "Updated Creative Name"
}]
}
Media
#### List Media
GET /v1/adaccounts/{adAccountId}/media
GET /v1/adaccounts/{adAccountId}/media?limit=50&sort=created_at-desc
#### Get Media
GET /v1/media/{mediaId}
Pixels
#### List Pixels
GET /v1/adaccounts/{adAccountId}/pixels
#### Get Pixel
GET /v1/pixels/{pixelId}
Audience Segments
#### List Segments
GET /v1/adaccounts/{adAccountId}/segments
#### Get Segment
GET /v1/segments/{segmentId}
Stats
#### Get Ad Account Stats
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 Campaign Stats
GET /v1/campaigns/{campaignId}/stats?granularity=DAY&start_time=2026-02-01&end_time=2026-02-14
Targeting
#### Get Countries
GET /v1/targeting/geo/country
#### Get Regions by Country
GET /v1/targeting/geo/{countryCode}/region
Example: GET /v1/targeting/geo/us/region
#### Get OS Types
GET /v1/targeting/device/os_type
#### Get Location Categories
GET /v1/targeting/location/categories_loi
Ads Gallery (Public Ads Library)
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.
#### List Sponsored Content
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"
}
}
]
}
#### Search Sponsored Content
POST /v1/ads_library/sponsored_content/search
Content-Type: application/json{
"limit": 50
}
#### Search Ads
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"
}
}
]
}
Pagination
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=...
Sorting
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
Code Examples
JavaScript
// 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);
Python
import os
import requestsList 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'])
List All Campaigns Example
import os
import requestsorg_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}")
Notes
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 environmentsError Handling
| 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 |
Response Error Format
{
"request_status": "ERROR",
"request_id": "...",
"debug_message": "Error details",
"display_message": "User-friendly message"
}
Resources
π‘ Examples
# 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
π Tips & Best Practices
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