> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appdna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Snapchat Ads

> Connect a Snapchat Ads account to manage campaigns, ad squads, ads, and creatives, upload image and video media, pull stats, and run multi-ad-squad creative experiments from the dashboard.

## Overview

Connecting Snapchat Ads lets the dashboard:

* Create, update, pause, resume, and delete **campaigns** and **ad squads** (Snap's term for ad sets).
* Upload **image** and **video** media into the connected ad account and bind them into creatives.
* Create and manage **ads** that reference a creative plus an ad squad.
* Pull spend, impressions, swipes, and conversion metrics from the campaign stats endpoint.
* Run creative experiments by rotating multiple ad squads under one campaign.

The integration uses the **Snap Marketing API v1** with **OAuth 2.0** authentication and refresh tokens.

## Prerequisites

Before connecting, make sure you have:

1. An active Snapchat Business account with at least one organization and one ad account.
2. The role of **Admin** or **Campaign Manager** on the ad account so OAuth can mint tokens with write scope.
3. An OAuth 2.0 application configured for the dashboard's redirect URI, with OAuth credentials configured by your administrator.

## OAuth scope

The connection requests a single scope:

```
snapchat-marketing-api
```

This scope covers all read and write operations on campaigns, ad squads, ads, creatives, media, and stats.

## Connect

1. Open the **Paid UA → Integrations** page in the dashboard.
2. Click **Connect** on the Snapchat Ads tile.
3. Sign in with the Snap account that has access to your organization's ad accounts.
4. Approve the requested scope.
5. After redirect, the dashboard exchanges the auth code for tokens and probes `/me/organizations` followed by `/organizations/{id}/adaccounts` to confirm access and capture the ad account ids.

Access tokens are rotated automatically before expiry using the refresh token.

## What happens behind the scenes

| Operation                              | API endpoint                                                              |
| -------------------------------------- | ------------------------------------------------------------------------- |
| List organizations the user can access | `GET /me/organizations`                                                   |
| List ad accounts under an organization | `GET /organizations/{id}/adaccounts`                                      |
| Create / list campaigns                | `POST` / `GET /adaccounts/{id}/campaigns`                                 |
| Update / pause / resume campaign       | `PUT /adaccounts/{id}/campaigns` (body wrapped in `{ campaigns: [...] }`) |
| Delete campaign                        | `DELETE /campaigns/{id}`                                                  |
| Create / update ad squads              | `POST` / `PUT /adaccounts/{id}/adsquads`                                  |
| Create / update ads                    | `POST` / `PUT /adaccounts/{id}/ads`                                       |
| Upload media                           | `POST /adaccounts/{id}/media`                                             |
| Create creative                        | `POST /adaccounts/{id}/creatives`                                         |
| Pull stats                             | `GET /campaigns/{id}/stats?granularity=DAY&fields=...`                    |

Snap wraps create / update bodies in collection arrays (`{ campaigns: [...] }`, `{ adsquads: [...] }`, `{ ads: [...] }`, `{ creatives: [...] }`, `{ media: [...] }`). The integration handles this transparently.

Every write request carries an `Idempotency-Key` HTTP header so retries do not produce duplicate resources, even if the platform connection drops mid-request.

## Budget conversion

Snap budgets are stored in **micro-currency** (1 USD = 1,000,000 micros). The dashboard sends USD values in its DTOs and converts to micros (`Math.round(amount_usd * 1_000_000)`) before the request lands. Pause / resume operations send `{ status: 'PAUSED' | 'ACTIVE' }`.

## Rate limiting

Requests are throttled per ad account using a sliding-window rate limiter, and rate limits apply. If the platform reports HTTP 429, the request is automatically retried with exponential backoff.

If the rate limiter is unavailable, it fails closed and the request is reported as a quota error to the platform's automation — preventing accidental over-quota fan-out under outage.

## Reporting

Metrics are pulled hourly (or on demand) from `/campaigns/{id}/stats` with `granularity=DAY` and the standard Snap field set (spend, impressions, swipes, view\_completion, conversion\_purchases). Spend is converted from native currency to USD on ingestion. The native currency, the FX rate used, and the local-currency spend are kept alongside the USD value for downstream analytics.

## Experiments (multi-ad-squad rotation)

The dashboard maps experiment variants onto **multiple ad squads** under a single campaign, with each variant carrying its own targeting and creative reference. The control variant ships **active**; treatments ship **paused** until the experiment runner toggles them. Per-variant performance is read back from the stats endpoint with `breakdown=adsquad_id`.

## Live write access

Live write access is enabled by AppDNA for your account. Until it is enabled, write operations are not sent to Snapchat.

## Disconnect

Click **Disconnect** on the integration tile. The OAuth refresh token is removed from the dashboard. To fully revoke access, also remove the third-party app authorisation from your Snapchat Business connected-apps list.

## Troubleshooting

* **"Snapchat Ads /me returned 401"** — the OAuth token has been revoked or has expired without a valid refresh token. Re-connect the integration.
* **"Snapchat Ads create\_campaign: 429 — ..."** — your ad account's per-second API quota was breached. The dashboard backs off automatically; if the error persists, lower campaign-mutation frequency.
* **"webhooks not supported on snapchat\_ads"** — Snap's Marketing API does not expose webhooks. State changes (ad disapproved, daily cap hit, account suspended) are detected via the hourly metrics-sync job.
* **Writes are not reaching Snapchat** — live write access is enabled by AppDNA for your account. Contact AppDNA support if writes are not taking effect.
* **`creative_id` references a missing creative** — Snap's ad references creatives by id. Make sure to upload media first (`upload_media`), then create the creative (`create_creative`), and finally create the ad with the resulting `creative_id` bound on it.
