---
title: "Extraire les données de votre boutique Shopify avec l'API GraphQL Admin"
description: "Le connecteur Shopify extrait les données de votre boutique Shopify via l'API GraphQL Admin : produits, clients, commandes, inventaire, marketing, B2B, paiements"
url: https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/connectors-sources-shopify
lang: fr
lastUpdated: 2026-09-14
---
> For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/fr/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/fr/llms-full.txt.

# Extraire les données de votre boutique Shopify avec l'API GraphQL Admin

## Objectif

Le connecteur Shopify extrait les données de votre boutique Shopify via l'**API GraphQL Admin** : produits, clients, commandes, inventaire, marketing, B2B, paiements, contenu, et plus encore.

**40 types d'endpoints intégrés** + une **requête personnalisée** comme solution de secours pour du GraphQL arbitraire.

Le connecteur renvoie du **JSON brut** depuis l'API Shopify. La platform aplatit automatiquement les champs imbriqués en colonnes et stocke le résultat dans le lakehouse. Aucune définition de schéma manuelle n'est nécessaire.

## 1. Obtenir un token d'accès à l'API Admin

Vous installez votre propre **application personnalisée** sur votre boutique. Le connecteur utilise ensuite les identifiants de cette application pour lire vos données, rien d'autre.

Deux méthodes permettent d'obtenir les identifiants, toutes deux prises en charge :

### Méthode A : Dev Dashboard (recommandée pour les nouvelles boutiques)

1. Allez sur [partners.shopify.com](https://partners.shopify.com) et connectez-vous (gratuit, aucune carte requise).
2. Ouvrez le **Dev Dashboard**, cliquez sur **Create app**, nommez-la (par exemple `data-connector`).
3. Dans la nouvelle application, allez dans **Versions** → **Create a new version**.
4. Dans **Access** → **Champs d'accès**, collez la [liste des scopes recommandés](#3-scopes-recommandés) ci-dessous.
5. Ouvrez **Demander l'accès** en haut de la section **Access** → activez **Customer data** (et Order data, etc.) → cochez **Analyses de données** (Data analytics) → sauvegardez. _Sur une boutique de développement, ceci est approuvé instantanément._
6. **Publiez** la version.
7. Installez l'application sur votre boutique depuis la section **Distribution**.
8. Ouvrez les **Settings** de l'application → copiez **Client ID** et **Client Secret**.
9. Dans l'interface du connecteur, remplissez **Shop**, laissez **Access Token** vide, et collez **Client ID** + **Client Secret**. Le connecteur les échangera contre un token hors ligne dès la première exécution.

### Méthode B : Token existant (plus rapide, si vous en avez déjà un)

Si vous avez déjà obtenu un token d'accès à l'API Admin via l'ancien flux « Develop apps » (le token commence par `shpat_`) ou en exécutant vous-même l'échange OAuth `client_credentials` (`shpua_`), collez-le directement dans le champ **Access Token**, en laissant **Client ID** / **Client Secret** vides.

## 2. Configurer les identifiants

Le connecteur accepte deux modes d'authentification interchangeables :

| Champ             | Mode A (token direct)                  | Mode B (échange OAuth)                      |
| ----------------- | -------------------------------------- | ------------------------------------------- |
| **Shop**          | `my-store` ou `my-store.myshopify.com` | identique                                   |
| **Access Token**  | `shpat_xxx…` ou `shpua_xxx…`           | vide                                        |
| **Client ID**     | vide                                   | chaîne hexadécimale depuis le Dev Dashboard |
| **Client Secret** | vide                                   | commence par `shpss_`                       |

Si les deux sont renseignés, le token direct est prioritaire.

## 3. Scopes recommandés

Collez cette liste séparée par des virgules dans le champ **Access scopes** de la version de votre application personnalisée (Dev Dashboard → Access → Champs d'accès) :

```
read_products, read_customers, read_orders, read_draft_orders,
read_inventory, read_locations, read_discounts,
read_shopify_payments_payouts, read_shopify_payments_disputes,
read_shopify_payments_accounts, read_marketing_events,
read_content, read_users, read_shipping, read_metaobjects,
read_metaobject_definitions, read_publications, read_locales,
read_markets, read_files, read_companies, read_assigned_fulfillment_orders,
read_audit_events
```

Si un nom de scope est rejeté, supprimez-le. Shopify renomme les scopes entre les versions de l'API, mais le connecteur gère les scopes manquants avec souplesse (renvoie `[]` avec un avertissement au lieu de planter).

Pour les données **Customer / Order / Draft Order / Abandoned Checkout**, vous devez également activer l'approbation **Protected Customer Data** (voir Méthode A, étape 5). Sans cela, ces endpoints renvoient des lignes mais avec les champs PII vidés.

## 4. Ajouter une source Shopify sur la Data Platform

1. Dans les **Connectors** de la Data Platform, trouvez **Shopify** dans le magasin de sources et cliquez sur **Select**.
2. Renseignez les champs de connexion en utilisant soit le Mode A (token direct), soit le Mode B (Client ID + Client Secret) de l'[étape 2](#2-configurer-les-identifiants).
3. Cliquez sur **Connect**. Avec le Mode B, le connecteur échange le Client ID/Secret contre un token d'accès hors ligne à cette étape.
4. Cliquez sur **Add an Endpoint**, choisissez un type d'endpoint dans la liste déroulante (par exemple `products`, `orders`, `custom_query`), puis renseignez les paramètres requis (par exemple `segment_id`, `query_filter`, `max_items`).
5. Répétez l'étape 4 pour chaque endpoint supplémentaire que vous souhaitez ingérer dans cette source. Chaque endpoint devient une table distincte dans le lakehouse.
6. Nommez la source et cliquez sur **Create**.

:::warning
Le **nom technique** ne peut pas être modifié après la création de la source. Il est utilisé lors de l'ouverture de la source via le [SDK Data Platform](https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/landing-page-developers-python-sdk.md).
:::

## 5. Types d'endpoints disponibles

### Commerce principal (14)

| Endpoint                       | Description                               | Paramètres requis        |
| ------------------------------ | ----------------------------------------- | ------------------------ |
| **products**                   | Produits du catalogue                     |                          |
| **product\_variants**          | Toutes les variantes de tous les produits |                          |
| **collections**                | Collections manuelles + intelligentes     |                          |
| **customers**                  | Fiches clients                            |                          |
| **customer\_segment\_members** | Membres d'un segment spécifique           | `segment_id`             |
| **orders**                     | Commandes (filtrables)                    | `query_filter` optionnel |
| **draft\_orders**              | Commandes en attente non converties       |                          |
| **abandoned\_checkouts**       | Données de tunnel de conversion           |                          |
| **fulfillment\_orders**        | File d'attente logistique                 |                          |
| **tender\_transactions**       | Répartition par type de paiement          |                          |
| **locations**                  | Boutiques / entrepôts                     |                          |
| **inventory\_items**           | Données de référence SKU + coût           |                          |
| **segments**                   | Définitions de segments clients           |                          |
| **companies**                  | Sociétés B2B                              |                          |

### B2B & marchés (4)

| Endpoint               | Description                   | Paramètres requis |
| ---------------------- | ----------------------------- | ----------------- |
| **company\_locations** | Adresses de livraison B2B     |                   |
| **price\_lists**       | Tarification B2B / gros       |                   |
| **catalogs**           | Affectations de catalogue B2B |                   |
| **markets**            | Configuration multi-région    |                   |

### Promotions & fidélité (4)

| Endpoint                  | Description                                          | Paramètres requis |
| ------------------------- | ---------------------------------------------------- | ----------------- |
| **discount\_nodes**       | Toutes les remises (automatiques + code + manuelles) |                   |
| **code\_discount\_nodes** | Remises par code uniquement                          |                   |
| **gift\_cards**           | Cartes cadeaux (Shopify Plus uniquement)             |                   |
| **selling\_plan\_groups** | Plans d'abonnement                                   |                   |

### Marketing & Shopify Payments (5)

| Endpoint                  | Description                        | Paramètres requis |
| ------------------------- | ---------------------------------- | ----------------- |
| **marketing\_events**     | Suivi des campagnes                |                   |
| **publications**          | Publications de canaux de vente    |                   |
| **payouts**               | Versements Shopify Payments        |                   |
| **disputes**              | Litiges Shopify Payments           |                   |
| **balance\_transactions** | Registre détaillé Shopify Payments |                   |

### Métadonnées & données personnalisées (3)

| Endpoint                    | Description                                      | Paramètres requis                            |
| --------------------------- | ------------------------------------------------ | -------------------------------------------- |
| **metaobjects**             | Instances de données personnalisées              | `metaobject_type`                            |
| **metaobject\_definitions** | Schémas de métaobjets                            |                                              |
| **metafield\_definitions**  | Schémas de métachamps (par type de propriétaire) | `owner_type` (PRODUCT, CUSTOMER, ORDER, ...) |

### Contenu (5)

| Endpoint           | Description                             | Paramètres requis |
| ------------------ | --------------------------------------- | ----------------- |
| **articles**       | Articles de blog                        |                   |
| **blogs**          | Conteneurs de blog                      |                   |
| **pages**          | Pages statiques de la boutique en ligne |                   |
| **url\_redirects** | Règles de redirection d'URL             |                   |
| **files**          | Ressources média téléversées            |                   |

### Administration & opérations (4)

| Endpoint                  | Description                    | Paramètres requis |
| ------------------------- | ------------------------------ | ----------------- |
| **events**                | Journal d'audit de la boutique |                   |
| **staff\_members**        | Équipe de la boutique          |                   |
| **delivery\_profiles**    | Zones et tarifs de livraison   |                   |
| **fulfillment\_services** | Intégrations 3PL               |                   |

### Objet unique (1)

| Endpoint | Description                                                          | Paramètres requis |
| -------- | -------------------------------------------------------------------- | ----------------- |
| **shop** | Paramètres au niveau de la boutique (renvoie un seul enregistrement) |                   |

### GraphQL personnalisé (1)

| Endpoint          | Description                                               | Paramètres requis                                                           |
| ----------------- | --------------------------------------------------------- | --------------------------------------------------------------------------- |
| **custom\_query** | Exécute n'importe quelle requête GraphQL que vous écrivez | `query` (votre GraphQL), `variables` optionnel, `connection_path` optionnel |

Pour `custom_query`, votre GraphQL **doit** déclarer `$first: Int!` et `$after: String` comme variables et paginer une connexion avec `pageInfo { hasNextPage endCursor }`. Le connecteur injecte automatiquement les curseurs.

## 6. Pagination et `max_items`

L'API GraphQL de Shopify ne renvoie jamais tous les résultats en une seule fois. Chaque liste est **paginée**. Le connecteur gère la pagination automatiquement ; le seul paramètre que vous contrôlez est le champ `max_items` dans l'interface.

### Le champ `max_items`

Chaque endpoint (intégré ou `custom_query`) expose un champ **Max Items**. Il indique au connecteur « arrête-toi après avoir collecté N enregistrements, même si d'autres sont disponibles ».

| Ce que vous voulez                        | Définir Max Items à                   | Ce qui se passe                                                                                                                                           |
| ----------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tous les enregistrements                  | vide                                  | Le connecteur boucle jusqu'à ce que Shopify indique `hasNextPage: false`. Cela peut être 1 requête (petite boutique) ou 1000+ requêtes (grande boutique). |
| Juste le premier enregistrement           | `1`                                   | Une requête avec une taille de page de 1. S'arrête immédiatement.                                                                                         |
| Les 5 premiers enregistrements            | `5`                                   | Une requête avec une taille de page de 5. S'arrête.                                                                                                       |
| Les 100 premiers enregistrements          | `100`                                 | Une requête avec une taille de page de 100. S'arrête.                                                                                                     |
| Les 250 premiers enregistrements          | `250`                                 | Une requête avec une taille de page de 250 (le maximum Shopify). S'arrête.                                                                                |
| Les 1000 premiers enregistrements         | `1000`                                | Quatre requêtes de 250 chacune.                                                                                                                           |
| 50 enregistrements pour tester, puis tout | `50` d'abord, puis relancer avec vide | Schéma courant en phase d'itération.                                                                                                                      |

### Comment ça fonctionne en coulisses

Le connecteur choisit dynamiquement la taille de page :

```
page_size = min(100, max_items - already_collected)   # si max_items est défini
page_size = 100                                        # si max_items est vide
```

Chaque requête demande à Shopify ce nombre d'enregistrements. Une fois que `max_items` est atteint ou que `hasNextPage: false`, la boucle s'arrête.

Ainsi, `max_items: 5` déclenche exactement **une** requête HTTP (`first=5, after=null`). Aucune boucle de pagination, aucun second appel. Vous n'avez pas besoin d'écrire vous-même de logique de pagination.

### « Donne-moi juste la première page »

Il n'existe pas de bascule explicite « première page uniquement ». Mais comme Shopify limite la taille de page à 250, **définir `max_items` à une valeur ≤ 250 garantit une seule requête HTTP**. Si vous voulez « la taille de page Shopify naturelle » (50–100 par défaut), définissez simplement `max_items: 50` ou `100`.

### S'applique à chaque endpoint

Cela fonctionne de la même manière pour :

- Les 40 endpoints intégrés (`products`, `orders`, `customers`, ...).
- L'endpoint `custom_query` : le connecteur injecte toujours `first` et `after` dans votre requête et respecte `max_items`.

Vous n'écrivez jamais `first: 5` vous-même dans votre requête GraphQL. Vous écrivez `first: $first` et laissez le connecteur injecter la bonne valeur en fonction de `max_items`.

## 7. Requête personnalisée : exemples

L'endpoint `custom_query` accepte n'importe quel GraphQL que vous écrivez contre l'API Admin. Trois règles s'appliquent :

1. Déclarez `$first: Int!` et `$after: String` dans les variables de la requête.
2. Paginez une connexion avec `pageInfo { hasNextPage endCursor }`.
3. Soit définissez le champ **Connection Path** (par exemple `products`), soit laissez le connecteur détecter automatiquement la connexion.

Voici des modèles concrets pour des cas courants. Collez l'un d'eux dans le champ **GraphQL Query**, remplissez le champ **Variables** si nécessaire, et exécutez.

### Exemple 1 : produits minimalistes (juste quelques champs)

Utile lorsque vous avez seulement besoin des ID + titres pour des jointures en aval, plutôt que les 20 champs par défaut de l'endpoint `products`.

```graphql
query ($first: Int!, $after: String) {
  products(first: $first, after: $after) {
    edges {
      node {
        id
        title
        handle
        vendor
        createdAt
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

- **Variables** : laisser vide
- **Connection Path** : `products` (ou laisser vide pour la détection automatique)

### Exemple 2 : commandes avec un filtre de date

Reproduit l'endpoint intégré `orders` mais vous permet d'ajuster à la fois le filtre et la sélection de champs. Passez le filtre via Variables.

```graphql
query ($first: Int!, $after: String, $query: String) {
  orders(first: $first, after: $after, query: $query, sortKey: CREATED_AT) {
    edges {
      node {
        id
        name
        createdAt
        displayFinancialStatus
        totalPriceSet { shopMoney { amount currencyCode } }
        customer { id email }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

- **Variables** : `{"query": "created_at:>=2026-04-01 AND financial_status:paid"}`
- **Connection Path** : `orders`

La syntaxe complète de recherche est documentée sur [shopify.dev/docs/api/usage/search-syntax](https://shopify.dev/docs/api/usage/search-syntax).

### Exemple 3 : produits avec leurs variantes et métachamps

Cas où l'endpoint `products` par défaut ne suffit pas. Cela récupère les variantes de chaque produit en ligne ainsi que quelques métachamps spécifiques.

```graphql
query ($first: Int!, $after: String) {
  products(first: $first, after: $after) {
    edges {
      node {
        id
        title
        variants(first: 50) {
          edges {
            node { id sku price inventoryQuantity }
          }
        }
        metafields(first: 10, namespace: "custom") {
          edges {
            node { key value type }
          }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

- **Variables** : laisser vide
- **Connection Path** : `products`

:::warning
Chaque `first:` imbriqué s'ajoute au coût de la requête. Sur un plan Standard (budget de 100 points par requête), `products(first: $first)` avec `variants(first: 50)` et `metafields(first: 10)` consomme environ `first × (50 + 10 + 1)` points. Gardez la taille de page parent petite (par exemple `max_items: 20`) pour ce type de requête imbriquée.
:::

### Exemple 4 : lignes de commande (une sous-ressource non exposée comme endpoint de premier niveau)

Les lignes de chaque commande ne constituent pas un endpoint intégré. La seule façon de les obtenir est via une requête personnalisée.

```graphql
query ($first: Int!, $after: String) {
  orders(first: $first, after: $after, query: "status:any", sortKey: CREATED_AT) {
    edges {
      node {
        id
        name
        lineItems(first: 50) {
          edges {
            node {
              id
              title
              quantity
              originalUnitPriceSet { shopMoney { amount currencyCode } }
              variant { id sku }
            }
          }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

- **Variables** : laisser vide
- **Connection Path** : `orders`

### Exemple 5 : connexion imbriquée (utilisation de Connection Path)

Lorsque la connexion n'est pas à la racine, par exemple les versements d'une transaction de solde Shopify Payments spécifique. Définissez explicitement **Connection Path**.

```graphql
query ($first: Int!, $after: String) {
  shopifyPaymentsAccount {
    payouts(first: $first, after: $after) {
      edges {
        node {
          id
          status
          issuedAt
          summary {
            chargesGross { amount currencyCode }
            refundsFee { amount currencyCode }
          }
        }
      }
      pageInfo { hasNextPage endCursor }
    }
  }
}
```

- **Variables** : laisser vide
- **Connection Path** : `shopifyPaymentsAccount.payouts` _(requis, la détection automatique fonctionnerait aussi ici, mais l'explicite est plus clair lorsqu'il y a plusieurs connexions à différentes profondeurs)_

### Astuces

- **Testez d'abord dans le GraphiQL Explorer.** Shopify propose un GraphiQL intégré à la boutique à l'adresse `https://{shop}.myshopify.com/admin/api/explorer`. Construisez et validez votre requête là-bas avant de la coller dans le connecteur. L'auto-complétion et la documentation du schéma rendent l'itération bien plus rapide.
- **Découverte des champs.** Le schéma complet est documenté sur [shopify.dev/docs/api/admin-graphql/latest](https://shopify.dev/docs/api/admin-graphql/latest). Chaque page de type liste les champs disponibles et leur coût.
- **Deux endroits, deux rôles.** Votre chaîne de requête DOIT déclarer `$first: Int!` et `$after: String` dans sa liste de variables. C'est la **déclaration** GraphQL qui permet à Shopify de savoir qu'il doit les attendre. Le connecteur injecte ensuite leurs **valeurs** à l'exécution, page après page. Le champ UI **Variables** sert aux _valeurs_ des variables supplémentaires que votre requête déclare (par exemple `$query`, `$ownerType`, `$segmentId`), n'y mettez jamais `first` ou `after`, le connecteur les écrase.
- **`max_items` s'applique exactement comme pour les endpoints intégrés** : voir la [section 6](#6-pagination-et-max_items).

## 8. Exemple rapide : extraire les produits

1. **Type d'endpoint** : `products`
2. **Max Items** : `1000` (ou vide pour tout extraire)
3. Exécutez l'extraction de table.

Le connecteur renvoie du JSON brut. La platform aplatit automatiquement les champs imbriqués (par exemple `featuredImage.url` devient une colonne `featuredimage_url`).

Pour une requête ciblée : par exemple uniquement les commandes des 30 derniers jours :

1. **Type d'endpoint** : `orders`
2. **Filtre de requête** : `created_at:>=2026-04-01`
3. **Max Items** : vide

Le champ `query_filter` accepte la [syntaxe de recherche Shopify](https://shopify.dev/docs/api/usage/search-syntax).

## 9. Bonnes pratiques

### Normaliser le nom de la boutique une bonne fois pour toutes

Le connecteur accepte `my-store`, `my-store.myshopify.com`, ou `https://my-store.myshopify.com/`. Les trois formes résolvent vers le même hôte. Choisissez celle qui est la plus lisible.

### Utiliser `custom_query` pour des extractions ciblées

Les requêtes par défaut renvoient \~10–20 champs par enregistrement. Si vous n'avez besoin que de quelques champs et avez des millions d'enregistrements, écrivez une `custom_query` avec seulement ces champs, le coût de la requête est à peu près proportionnel au nombre de champs.

### Rafraîchir les tokens via Client ID + Secret

Si vous avez configuré le Mode B (Client ID + Client Secret), le connecteur relance l'échange OAuth à chaque démarrage de tâche. Cela signifie qu'un token compromis / renouvelé peut être remplacé en réémettant le secret dans le Dev Dashboard, sans toucher à la configuration du connecteur.

### `query_filter` par défaut pour les commandes

L'endpoint orders utilise `status:any` par défaut pour inclure toutes les commandes (ouvertes, fermées, annulées). Si vous voulez uniquement les commandes ouvertes, définissez `query_filter: status:open`.

## 10. Restriction par plan & scope

Certains endpoints sont restreints par plan ou par scope :

| Endpoint                                                                                                  | Restriction                                                  |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `gift_cards`                                                                                              | Shopify Plus uniquement                                      |
| `payouts`, `disputes`, `balance_transactions`                                                             | Shopify Payments doit être activé sur la boutique            |
| `companies`, `company_locations`, `catalogs`, `price_lists`                                               | Le B2B doit être activé                                      |
| `customers`, `orders`, `draft_orders`, `abandoned_checkouts`, `fulfillment_orders`, `tender_transactions` | Approbation Protected Customer Data (voir Méthode A étape 5) |

Lorsqu'un scope ou un plan est manquant, le connecteur enregistre un avertissement et renvoie une liste vide pour cet endpoint, vos autres tables continuent de fonctionner.

:::info
Pour des informations techniques détaillées (internes de l'authentification, référence complète des endpoints, pagination, limites de débit, format de sortie, limitations), consultez la [référence technique Shopify](https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/connectors-sources-shopify-technical-reference.md).
:::

## Aller plus loin

Si vous avez besoin d'une formation ou d'une assistance technique pour la mise en oeuvre de nos solutions, contactez votre commercial ou cliquez sur [ce lien](https://www.ovhcloud.com/fr/professional-services/) pour obtenir un devis et demander une analyse personnalisée de votre projet à nos experts de l’équipe Professional Services.

Posez vos questions, faites-nous part de vos commentaires et interagissez directement avec l’équipe qui développe la Data Platform sur le [canal Discord](https://discord.gg/ovhcloud) dédié.

Si vous avez besoin d'une assistance concernant vos services OVHcloud, créez une demande depuis notre [centre d'aide](https://help.ovhcloud.com/csm?id=csm_get_help).

Rejoignez notre [communauté d'utilisateurs](https://community.ovhcloud.com/).
