# meta-ads-fetcher (`luteous_freezer/meta-ads-fetcher`) Actor

- **URL**: https://apify.com/luteous\_freezer/meta-ads-fetcher.md
- **Developed by:** [Jérôme Spiell](https://apify.com/luteous_freezer) (community)
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Meta Ads Fetcher

Récupère les publicités d'un compte Meta via la **Marketing API** : nomenclature sur les trois niveaux, performances, copy, et surtout **les URLs média** — MP4 téléchargeables et images pleine résolution.

***

### Pourquoi cet actor existe

Le connecteur MCP Meta fonctionne bien, mais il a deux limites que rien ne permet de contourner de son côté :

**Il n'est pas ouvert sur tous les comptes.** Meta déploie l'accès progressivement, compte par compte. Un compte parfaitement actif peut ne pas l'avoir. Un compte désactivé ne l'aura jamais.

**Il ampute un champ décisif.** Sur `ads_get_ad_videos`, le champ `source` est explicitement rejeté — c'est pourtant lui qui donne l'URL MP4 téléchargeable. Résultat : avec le MCP seul, on ne peut pas analyser une vidéo.

La Marketing API n'a aucune de ces limites. Le verrou `is_ads_mcp_enabled` ne concerne que le serveur MCP : l'API classique fonctionne sur **n'importe quel compte auquel tu as accès**.

***

### Ce que tu récupères

| Donnée | Détail |
|---|---|
| **Nomenclature** | Nom de l'ad, de l'ad set et de la campagne — les trois niveaux, pour parser ta convention de nommage |
| **Copy** | Titre, body, call-to-action |
| **Vidéos** | **URL MP4 téléchargeable**, miniature, durée |
| **Statics** | **Image pleine résolution**, dimensions, hash |
| **Dynamic creative** | Assets extraits de `asset_feed_spec` — le cas que la plupart des scripts oublient |
| **Performances** | Spend, impressions, reach, fréquence, clics, CTR, CPC, CPM, achats, CPA, métriques vidéo |
| **Aperçu** | Rendu HTML de l'annonce (optionnel, ralentit sur gros volume) |

***

### Installation — une seule fois

#### 1. L'app Meta

Sur [developers.facebook.com](https://developers.facebook.com) → **Mes apps** → **Créer une app** → type **Business**.

Dans l'app : **Ajouter un produit** → **Marketing API**.

*Si tu as déjà une app Business, inutile d'en créer une autre — ajoute-lui simplement le produit Marketing API.*

#### 2. Le system user et son token

Dans ton **Business Manager** → **Paramètres de l'entreprise** → **Utilisateurs** → **Utilisateurs système** → **Ajouter**.

- Nom : au choix
- Rôle : **Employé** suffit

Puis, sur ce system user :

1. **Ajouter des ressources** → tes comptes publicitaires → accès **Afficher les performances** (lecture seule suffit)
2. **Générer un nouveau token** → choisis ton app → permission **`ads_read`** (ajoute `business_management` si tu gères des comptes clients)
3. **Copie le token immédiatement** — il ne sera plus affiché

> 💡 **Ce token n'expire pas**, contrairement à un token utilisateur qui dure environ 60 jours. C'est toute la raison de passer par un system user.

#### 3. Pour un compte client

Le client partage son compte publicitaire avec ton Business Manager **en partenaire**, puis tu assignes ce compte à ton system user.

Un accès **lecture seule** en **Standard Access** suffit. Les limites de débit sont juste plus basses — sans conséquence sur un usage normal.

#### 4. L'actor

Sur [console.apify.com](https://console.apify.com) → **Actors** → **Development** → **Create new** → template **Node.js — Empty project**.

Copie les fichiers de ce dossier :

```
.actor/actor.json
.actor/input_schema.json
src/main.js
package.json
Dockerfile
```

⚠️ Trois pièges du template par défaut :

- Il crée souvent un `INPUT_SCHEMA.json` **à la racine** → supprime-le, garde celui dans `.actor/`
- Écrase `src/main.js` entièrement
- Vérifie que `package.json` contient bien `"type": "module"`

Puis **Build**, et **Publication** pour l'appeler depuis le MCP Apify.

***

### Utilisation

```json
{
  "accessToken": "<ton token system user>",
  "adAccountId": "664188280758656",
  "datePreset": "last_30d",
  "includeInsights": true,
  "includeMedia": true
}
```

⚠️ **L'identifiant du compte va sans le préfixe `act_`.**

Depuis Claude :

```
call-actor("<username>/meta-ads-fetcher", {
  accessToken: "<token>",
  adAccountId: "<id>",
  datePreset: "last_30d"
})
```

**Pour une période précise :**

```json
{ "timeRange": { "since": "2026-01-01", "until": "2026-03-31" } }
```

***

### Deux pièges documentés par Meta

**`thumbnail_url` est en basse résolution par défaut.** L'actor l'expose sous le nom `thumbnail_low_res` pour éviter qu'on l'utilise par erreur — l'image pleine résolution est dans `media.url`, récupérée via le hash.

**`source` peut revenir vide sur certaines vidéos**, typiquement celles issues d'un post de page sur lequel le token n'a pas les droits. L'actor bascule alors automatiquement sur `advideos`. Si ça échoue aussi, le champ `note` explique pourquoi — plutôt qu'un `null` silencieux.

***

### Structure des résultats

Une ligne par ad :

```json
{
  "ad_id": "120247580389050526",
  "ad_name": "Batch 08/04/26 - Static 7",
  "adset_name": "...",
  "campaign_name": "...",
  "effective_status": "ACTIVE",
  "created_time": "2026-04-08T10:23:00+0000",
  "title": "...",
  "body": "...",
  "media": {
    "type": "video",
    "video_id": "4350315591909408",
    "source": "https://video.xx.fbcdn.net/....mp4",
    "thumbnail": "https://scontent...jpg",
    "length_seconds": 40.7
  },
  "is_dynamic_creative": false,
  "spend": 5625.42,
  "purchases": 312,
  "cost_per_purchase": 18.03,
  "ctr": 1.24,
  "cpm": 8.91
}
```

Un objet **SUMMARY** est aussi écrit dans le key-value store : nombre d'ads, répartition statics/vidéos, vidéos sans source, dynamic creatives.

***

### Messages d'erreur

| Message | Cause |
|---|---|
| `Token invalide ou expire` | Régénère le token du system user |
| `Permissions insuffisantes sur le compte` | Le system user n'est pas assigné à ce compte, ou pas avec `ads_read` |
| `Quota API atteint` | Attends quelques minutes, ou réduis la période |
| `Aucune ad trouvee` | Vérifie l'identifiant du compte, ou élargis `effectiveStatus` |

***

### Coût

Quelques centimes par exécution — c'est du temps de calcul Apify, pas d'appel payant.

L'API Meta est gratuite dans les limites de débit standard. Sur un très gros historique, découper la période en plusieurs exécutions plutôt que de tout demander d'un coup.

# Actor input Schema

## `accessToken` (type: `string`):

Token du system user, avec la permission ads\_read. Contrairement a un token utilisateur (60 jours), celui-ci n'expire pas.

## `adAccountId` (type: `string`):

Identifiant numerique, SANS le prefixe act\_. Exemple : 664188280758656

## `datePreset` (type: `string`):

Periode des performances. Ignore si timeRange est renseigne.

## `timeRange` (type: `object`):

Pour une periode sur mesure : { "since": "2026-01-01", "until": "2026-03-31" }. Prioritaire sur la periode ci-dessus.

## `effectiveStatus` (type: `array`):

Laisse vide pour tout recuperer. Sinon : ACTIVE, PAUSED, ARCHIVED, ADSET\_PAUSED, CAMPAIGN\_PAUSED.

## `limit` (type: `integer`):

Nombre TOTAL d'ads a recuperer, toutes pages confondues. Sur un gros compte, commencer a 20-50 pour tester : chaque ad declenche plusieurs appels Meta.

## `includeInsights` (type: `boolean`):

Spend, impressions, CTR, CPM, achats, CPA, metriques video.

## `includeMedia` (type: `boolean`):

URLs MP4 des videos et images pleine resolution. C'est la raison d'etre de cet actor : le MCP ne les donne pas.

## `includePreviews` (type: `boolean`):

Le rendu de l'annonce en HTML. Ralentit nettement sur un gros volume.

## `apiVersion` (type: `string`):

A ne changer que si Meta deprecie la version par defaut.

## Actor input object example

```json
{
  "datePreset": "last_30d",
  "limit": 50,
  "includeInsights": true,
  "includeMedia": true,
  "includePreviews": false,
  "apiVersion": "v21.0"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("luteous_freezer/meta-ads-fetcher").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("luteous_freezer/meta-ads-fetcher").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call luteous_freezer/meta-ads-fetcher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,luteous_freezer/meta-ads-fetcher"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CIQOGC9TVeuz0NygT/builds/at8gCEH5HN8RfUjSp/openapi.json
