Snapchat
Manage Snapchat ad accounts, campaigns, ad squads, ads, creatives, and audiences via OAuth-secured Marketing API integration.
Like a lobster shell, security has layers — review code before you run it.
License
Runtime requirements
SKILL.md
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://gateway.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://gateway.maton.ai/snapchat/{api-path}
The Snapchat Marketing API uses the path pattern:
https://gateway.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
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Snapchat OAuth connections at https://ctrl.maton.ai.
List Connections
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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://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
python3 <<'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": "f5d5458b-fb65-458c-9e51-08844662dd39",
"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://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 Snapchat connections, specify which one to use with the Maton-Connection header:
python3 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/snapchat/v1/me/organizations')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', 'f5d5458b-fb65-458c-9e51-08844662dd39')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
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 return
Note: 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://gateway.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 requests
# List organizations
response = requests.get(
'https://gateway.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 requests
org_id = "YOUR_ORG_ID"
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Get ad accounts
response = requests.get(
f'https://gateway.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://gateway.maton.ai/snapchat/v1/adaccounts/{ad_account_id}/campaigns',
headers=headers
).json()
print(f"Ad Account: {aa['adaccount']['name']}")
print(f"Campaigns: {campaigns}")
Notes
- Monetary Values: All monetary values use micro-currency (1 USD = 1,000,000 micro)
- Bulk Operations: Create/update endpoints accept arrays for batch operations
- Response Format: All responses include
request_status,request_id, and entity arrays withsub_request_status - Timestamps: Use ISO 8601 format with timezone (e.g.,
2026-02-15T00:00:00.000-08:00) - Ads Gallery Countries: Not all countries are available in the Ads Library. EU countries (fr, de, gb, etc.) are supported.
- Conversions API: The Conversions API uses a different base URL (
tr.snapchat.com) and is not currently routed through this gateway. - Public Profile API: The Public Profile API may not be available or requires separate configuration.
- 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 | 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
Files
2 totalComments
Loading comments…
