Intégrer une API externe dans WordPress : guide pas à pas avec wp_remote_get

Dans cet article

  • La fonction wp_remote_get() est la méthode native recommandée par WordPress pour consommer une API externe, avec gestion automatique des timeouts et du SSL
  • Un appel API mal caché peut ajouter 300 à 800 ms de temps de chargement par page, d où l importance cruciale des Transients
  • Le trio wp_remote_get / wp_remote_retrieve_body / json_decode couvre 90 % des cas d intégration REST en lecture
  • Pour les requêtes authentifiées, WordPress gère nativement les headers Authorization Bearer et les clés API via le tableau d arguments
  • Stocker une clé API en dur dans functions.php est une erreur de sécurité : utilisez wp-config.php ou une variable d environnement
  • Un shortcode ou un bloc Gutenberg custom permet d afficher les données API sans toucher au template du thème

En onze ans de WordPress sur mesure, j ai intégré des dizaines d API externes pour mes clients : météo, stocks produits, CRM, passerelles de paiement, données publiques. À chaque fois, la question revient : faut-il utiliser cURL, file_get_contents, un plugin tiers, ou la fonction native de WordPress ? Ma réponse est systématiquement la même : wp_remote_get(). C est la méthode la plus fiable, la plus portable, et celle que le Codex recommande officiellement. Voici le guide complet que j aurais aimé avoir à mes débuts.

Pourquoi utiliser wp_remote_get plutôt que cURL ou file_get_contents

WordPress embarque sa propre couche d abstraction HTTP appelée WP_Http. Cette classe détecte automatiquement le transport disponible sur le serveur (cURL, streams PHP, fsockopen) et choisit le meilleur. Quand vous appelez wp_remote_get(), vous ne vous souciez plus de savoir si cURL est installé ou si allow_url_fopen est activé dans le php.ini.

Concrètement, voici ce que wp_remote_get() fait pour vous par rapport à un appel cURL brut :

  • Gestion automatique du SSL : vérification des certificats sans configuration manuelle
  • Timeout configurable avec une valeur par défaut raisonnable de 5 secondes
  • Compatibilité universelle : fonctionne sur les hébergements mutualisés où cURL est parfois désactivé
  • Filtrage via hooks : les filtres pre_http_request et http_response permettent de modifier ou mocker les requêtes dans les tests
  • Format de réponse standardisé : toujours un tableau associatif ou un objet WP_Error

J ai vu des développeurs utiliser file_get_contents() pour consommer une API REST. Sur un hébergement mutualisé classique, cette fonction est souvent bloquée pour les URL distantes. Et même quand elle fonctionne, elle ne gère ni les headers personnalisés, ni les timeouts, ni les codes HTTP de manière propre. Bref, c est un piège. Comme pour le choix d un hébergement VPS bien configuré, mieux vaut partir sur des fondations solides dès le départ.

Premier appel API avec wp_remote_get en quelques lignes de PHP
Premier appel API avec wp_remote_get en quelques lignes de PHP

Premier appel API : récupérer des données en 10 lignes

Commençons par le cas le plus simple : récupérer des données JSON depuis une API publique. Je vais utiliser l API JSONPlaceholder, gratuite et sans authentification, parfaite pour apprendre.

<?php
// Appel GET simple vers une API externe
$response = wp_remote_get( 'https://jsonplaceholder.typicode.com/posts/1' );

// Vérifier si la requête a échoué
if ( is_wp_error( $response ) ) {
    error_log( 'Erreur API : ' . $response->get_error_message() );
    return;
}

// Récupérer le code HTTP
$code = wp_remote_retrieve_response_code( $response );
if ( $code !== 200 ) {
    error_log( 'API a retourné le code : ' . $code );
    return;
}

// Extraire le body et décoder le JSON
$body = wp_remote_retrieve_body( $response );
$data = json_decode( $body, true );

// Utiliser les données
echo '<h3>' . esc_html( $data['title'] ) . '</h3>';
echo '<p>' . esc_html( $data['body'] ) . '</p>';

Ce code illustre les trois fonctions essentielles que vous utiliserez systématiquement :

  1. wp_remote_get() : envoie la requête HTTP GET
  2. wp_remote_retrieve_body() : extrait le corps de la réponse
  3. wp_remote_retrieve_response_code() : récupère le code HTTP (200, 404, 500, etc.)

Le point crucial ici est la vérification avec is_wp_error(). Sans ce test, votre site affichera une erreur fatale si l API est injoignable. J ai déjà vu des sites en production tomber parce qu un développeur avait oublié cette vérification et que l API distante a eu 30 minutes d indisponibilité. La règle d or : toujours tester la réponse avant de l exploiter.

Gérer l authentification : clé API, Bearer token, Basic Auth

La plupart des API professionnelles exigent une authentification. WordPress gère tous les cas courants via le deuxième argument de wp_remote_get(), un tableau d options.

Authentification par clé API en paramètre d URL (OpenWeatherMap, NewsAPI, etc.) :

$api_key = defined( 'MON_API_KEY' ) ? MON_API_KEY : '';
$url = 'https://api.example.com/data?api_key=' . $api_key;
$response = wp_remote_get( $url );

Authentification Bearer Token (Stripe, GitHub, etc.) :

$response = wp_remote_get( 'https://api.example.com/data', array(
    'headers' => array(
        'Authorization' => 'Bearer ' . MON_BEARER_TOKEN,
        'Content-Type'  => 'application/json',
    ),
    'timeout' => 15,
) );

Authentification Basic Auth (WooCommerce REST API, certaines API legacy) :

$response = wp_remote_get( 'https://api.example.com/data', array(
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( 'user:password' ),
    ),
) );

Notez le paramètre timeout que j ai ajouté dans l exemple Bearer. Par défaut, WordPress attend 5 secondes. Pour les API lentes (traitement d images, requêtes complexes), montez à 15 ou 30 secondes. Au-delà, c est souvent le signe d un problème côté API. Si vous travaillez avec des passerelles de paiement comme Stripe, un timeout trop court peut interrompre une transaction en cours.

Sécuriser sa clé API dans WordPress

C est le point que je vois le plus souvent bâclé, même par des développeurs expérimentés. Jamais de clé API en dur dans functions.php, dans un fichier template, ou pire, dans un champ ACF accessible depuis l admin. Voici les deux méthodes que j utilise systématiquement.

Méthode 1 : constante dans wp-config.php (la plus courante)

// Dans wp-config.php, AVANT "C est tout, ne touchez pas à ce qui suit"
define( 'WEATHER_API_KEY', 'votre-cle-ici' );

Puis dans votre code :

$api_key = defined( 'WEATHER_API_KEY' ) ? WEATHER_API_KEY : '';

Méthode 2 : variable d environnement (idéale sur VPS avec .env)

// Dans .env ou dans la config Apache/Nginx
SetEnv WEATHER_API_KEY votre-cle-ici

// Dans PHP
$api_key = getenv( 'WEATHER_API_KEY' );

La méthode 2 est celle que je privilégie sur les VPS OVH que je configure pour mes clients. Le fichier wp-config.php peut se retrouver dans un commit Git par erreur ; une variable d environnement du serveur web, jamais. Dans tous les cas, ajoutez wp-config.php et .env à votre .gitignore. C est non négociable.

La CNIL recommande dans son guide de sécurité des données de ne jamais stocker de secrets en clair dans du code source versionné. C est d autant plus vrai quand votre WordPress traite des données personnelles via une API tierce.

La sécurisation des clés API passe par la configuration serveur et non le code source
La sécurisation des clés API passe par la configuration serveur et non le code source

Mettre en cache avec les Transients pour ne pas plomber les performances

Un appel API externe ajoute typiquement entre 300 et 800 ms au temps de chargement de votre page. Sur un site qui affiche des données API sur chaque page, c est catastrophique pour le SEO et l expérience utilisateur. La solution native de WordPress : les Transients.

function get_api_data_cached() {
    // Chercher dans le cache
    $cached = get_transient( 'mon_api_data' );
    if ( $cached !== false ) {
        return $cached;
    }

    // Pas de cache : appel API
    $response = wp_remote_get( 'https://api.example.com/data', array(
        'timeout' => 15,
    ) );

    if ( is_wp_error( $response ) ) {
        return array(); // Retourner un tableau vide en cas d erreur
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( empty( $data ) ) {
        return array();
    }

    // Stocker en cache pour 1 heure (3600 secondes)
    set_transient( 'mon_api_data', $data, HOUR_IN_SECONDS );

    return $data;
}

La durée du cache dépend de la fréquence de mise à jour des données. Voici les valeurs que j applique sur mes projets :

  • Données météo : 30 minutes (HOUR_IN_SECONDS / 2)
  • Taux de change : 1 heure
  • Stocks produits : 5 à 15 minutes
  • Données statiques (liste de pays, catégories) : 24 heures (DAY_IN_SECONDS)

Si votre site utilise un plugin de cache objet comme Redis ou Memcached, les Transients sont automatiquement stockés en mémoire plutôt qu en base de données. C est un gain de performance supplémentaire, surtout combiné avec une bonne optimisation des images et un hébergement adapté.

Un piège courant : ne pas gérer le cas où le cache expire ET l API est indisponible. Le code ci-dessus retourne un tableau vide, ce qui peut casser l affichage. Sur mes projets critiques, j utilise une stratégie stale-while-revalidate maison : je garde l ancienne valeur en cache avec un Transient secondaire sans expiration, et je ne la remplace que si l appel API réussit.

Afficher les données dans un shortcode ou un bloc Gutenberg

La manière la plus souple d injecter des données API dans vos pages est le shortcode. Aucun besoin de modifier les templates du thème, et l éditeur peut placer le bloc où il veut.

add_shortcode( 'api_data', 'render_api_data_shortcode' );

function render_api_data_shortcode( $atts ) {
    $atts = shortcode_atts( array(
        'endpoint' => 'posts',
        'limit'    => 5,
    ), $atts );

    $data = get_api_data_cached(); // Notre fonction avec cache

    if ( empty( $data ) ) {
        return '<p>Données indisponibles pour le moment.</p>';
    }

    $output = '<ul class="api-data-list">';
    $items = array_slice( $data, 0, intval( $atts['limit'] ) );
    foreach ( $items as $item ) {
        $output .= '<li>' . esc_html( $item['title'] ) . '</li>';
    }
    $output .= '</ul>';

    return $output;
}

Usage dans l éditeur : [api_data endpoint="posts" limit="10"]

Pour un bloc Gutenberg custom, le principe reste le même côté serveur. Vous enregistrez un bloc avec register_block_type() et un callback PHP de rendu dynamique qui appelle la même fonction. C est l approche que je recommande pour les projets neufs, car Gutenberg est désormais le standard. Si vous hésitez entre les deux approches, gardez le shortcode pour les sites existants et le bloc pour les nouveaux développements.

Pour les automatisations plus avancées entre WordPress et des services tiers, j utilise souvent Make ou n8n en complément. Mais pour un affichage de données en lecture, wp_remote_get avec un shortcode reste la solution la plus légère.

Envoyer des données avec wp_remote_post

wp_remote_get() couvre les requêtes en lecture. Pour envoyer des données à une API (créer un contact CRM, soumettre un formulaire, déclencher un webhook), utilisez wp_remote_post().

$response = wp_remote_post( 'https://api.example.com/contacts', array(
    'headers' => array(
        'Authorization' => 'Bearer ' . MON_API_TOKEN,
        'Content-Type'  => 'application/json',
    ),
    'body' => wp_json_encode( array(
        'email'     => '[email protected]',
        'firstname' => 'Jean',
        'lastname'  => 'Dupont',
    ) ),
    'timeout' => 15,
) );

if ( is_wp_error( $response ) ) {
    error_log( 'Erreur POST API : ' . $response->get_error_message() );
} else {
    $code = wp_remote_retrieve_response_code( $response );
    if ( $code === 201 ) {
        // Contact créé avec succès
    }
}

Deux points importants. D abord, utilisez wp_json_encode() plutôt que json_encode() : la version WordPress gère correctement l encodage UTF-8 et les caractères spéciaux français (accents, cédilles). Ensuite, précisez toujours le header Content-Type: application/json quand vous envoyez du JSON. Sans ce header, certaines API interprètent le body comme du form-data et rejettent la requête avec un code 400.

Pour les requêtes PUT, PATCH ou DELETE, WordPress propose wp_remote_request() avec le paramètre method :

$response = wp_remote_request( 'https://api.example.com/contacts/42', array(
    'method'  => 'DELETE',
    'headers' => array(
        'Authorization' => 'Bearer ' . MON_API_TOKEN,
    ),
) );

Si vous intégrez un CRM open source comme EspoCRM à WordPress, vous aurez besoin de ces quatre verbes HTTP pour synchroniser les contacts dans les deux sens.

Déboguer et tester ses appels API WordPress avec Query Monitor et la documentation officielle
Déboguer et tester ses appels API WordPress avec Query Monitor et la documentation officielle

Déboguer les erreurs courantes

Voici les erreurs que je rencontre le plus souvent chez mes clients et en intervention sur des projets existants.

Erreur « cURL error 28: Operation timed out » : l API met trop de temps à répondre. Augmentez le timeout à 30 secondes. Si ça persiste, le problème est côté API ou réseau. Vérifiez que votre hébergeur n a pas un pare-feu qui bloque les connexions sortantes.

Erreur « cURL error 60: SSL certificate problem » : le bundle de certificats CA de votre serveur est obsolète. Sur un VPS, mettez à jour le paquet ca-certificates. Sur un mutualisé, contactez l hébergeur. Ne désactivez jamais la vérification SSL avec 'sslverify' => false en production ; c est une faille de sécurité majeure.

Réponse vide ou JSON invalide : vérifiez le Content-Type de la réponse avec wp_remote_retrieve_header( $response, 'content-type' ). Certaines API retournent du XML par défaut si vous ne précisez pas le header Accept.

Code 403 Forbidden : l API rejette votre requête. Causes fréquentes : clé API expirée, IP du serveur non whitelistée, rate limiting atteint. Consultez la documentation officielle WordPress HTTP API pour les options avancées de débogage.

Mon outil de débogage préféré : le plugin Query Monitor. Il affiche toutes les requêtes HTTP sortantes avec leur durée, leur code de réponse et leurs headers. Indispensable en phase de développement.

Comparatif des méthodes d appel API dans WordPress

Pour clarifier définitivement le choix entre les différentes approches, voici un tableau comparatif basé sur mon expérience terrain.

Méthode Compatibilité hébergement Gestion SSL Timeout natif Hooks WordPress Recommandation
wp_remote_get() Universelle Automatique Oui (5s défaut) Oui À privilégier systématiquement
cURL direct (curl_init) Nécessite extension cURL Manuelle Manuelle Non Uniquement si contrainte technique spécifique
file_get_contents() Souvent bloquée Limitée Via context Non À éviter pour les API distantes
Plugin WPGetAPI Universelle Automatique Oui Limités Pour les non-développeurs uniquement
Guzzle / HttpClient Nécessite Composer Automatique Oui Non Réservé aux plugins distribués avec autoloader

Le plugin WPGetAPI mentionné dans le tableau est une solution no-code intéressante pour les intégrateurs qui ne codent pas en PHP. Mais dès qu on a besoin de logique conditionnelle, de cache personnalisé ou de transformation de données, on atteint vite ses limites. Pour un développeur, wp_remote_get() reste toujours le bon choix.

Cas concret : afficher la météo d une ville via OpenWeatherMap

Terminons par un exemple complet et fonctionnel. Ce code crée un shortcode [meteo ville="Paris"] qui affiche la température et la description météo en temps réel, avec cache d une heure.

// Dans functions.php ou dans un plugin custom
add_shortcode( 'meteo', 'afficher_meteo_shortcode' );

function afficher_meteo_shortcode( $atts ) {
    $atts = shortcode_atts( array(
        'ville' => 'Paris',
    ), $atts );

    $ville = sanitize_text_field( $atts['ville'] );
    $transient_key = 'meteo_' . sanitize_key( $ville );

    // Vérifier le cache
    $cached = get_transient( $transient_key );
    if ( $cached !== false ) {
        return $cached;
    }

    // Construire l URL
    $api_key = defined( 'OPENWEATHER_API_KEY' ) ? OPENWEATHER_API_KEY : '';
    if ( empty( $api_key ) ) {
        return '<p>Clé API non configurée.</p>';
    }

    $url = add_query_arg( array(
        'q'     => $ville,
        'appid' => $api_key,
        'units' => 'metric',
        'lang'  => 'fr',
    ), 'https://api.openweathermap.org/data/2.5/weather' );

    // Appel API
    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );

    if ( is_wp_error( $response ) ) {
        return '<p>Impossible de récupérer la météo.</p>';
    }

    $code = wp_remote_retrieve_response_code( $response );
    if ( $code !== 200 ) {
        return '<p>Erreur API météo (code ' . intval( $code ) . ').</p>';
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( empty( $data ) || ! isset( $data['main']['temp'] ) ) {
        return '<p>Données météo invalides.</p>';
    }

    // Construire le HTML
    $temp = round( $data['main']['temp'] );
    $description = ucfirst( $data['weather'][0]['description'] );
    $icone = $data['weather'][0]['icon'];

    $html = '<div class="widget-meteo">';
    $html .= '<img src="https://openweathermap.org/img/wn/' . esc_attr( $icone ) . '@2x.png" alt="' . esc_attr( $description ) . '" width="50" height="50">';
    $html .= '<span class="meteo-temp">' . esc_html( $temp ) . '°C</span>';
    $html .= '<span class="meteo-desc">' . esc_html( $description ) . ' à ' . esc_html( $ville ) . '</span>';
    $html .= '</div>';

    // Mettre en cache 1 heure
    set_transient( $transient_key, $html, HOUR_IN_SECONDS );

    return $html;
}

Ce shortcode illustre toutes les bonnes pratiques vues dans cet article : clé API dans wp-config.php, vérification d erreur à chaque étape, cache Transient, sanitization des entrées avec sanitize_text_field(), et échappement des sorties avec esc_html() et esc_attr(). C est exactement ce niveau de rigueur que j attends quand je fais une revue de code sur un projet client.

Pour aller plus loin dans l automatisation, vous pourriez connecter ce shortcode à un scénario Make ou n8n qui envoie une notification par email via Brevo quand la température dépasse un seuil. Les possibilités sont infinies une fois que vous maîtrisez les bases de l intégration API.

Un dernier conseil : si vous facturez ce type de développement à un client, documentez clairement les limites de l API utilisée (nombre d appels par mois, coût au-delà du quota gratuit) dans vos clauses de contrat. J ai eu un client qui a découvert une facture API de 200 € parce que personne n avait prévu le rate limiting. Depuis, j inclus systématiquement une clause sur les coûts de services tiers.

À retenir

  • Utilisez wp_remote_get() et jamais cURL direct ou file_get_contents() pour consommer une API externe dans WordPress
  • Stockez vos clés API dans wp-config.php via define() ou en variable d environnement serveur, jamais dans le code versionné
  • Mettez systématiquement en cache les réponses API avec set_transient() pour éviter 300 à 800 ms de latence par page
  • Vérifiez toujours la réponse avec is_wp_error() et le code HTTP avant d exploiter les données
  • Documentez dans vos contrats les limites et coûts des API tierces utilisées pour le projet du client

Questions fréquentes


Comment intégrer une API externe dans WordPress sans plugin ?

Utilisez la fonction native wp_remote_get() dans votre fichier functions.php ou dans un plugin custom. Elle gère automatiquement le transport HTTP, le SSL et les timeouts. Combinez-la avec wp_remote_retrieve_body() pour extraire les données JSON, et set_transient() pour mettre en cache les résultats. C est la méthode recommandée par la documentation officielle WordPress.

Quelle est la différence entre wp_remote_get et cURL dans WordPress ?

wp_remote_get() est une couche d abstraction qui utilise cURL en interne quand il est disponible, mais bascule automatiquement sur d autres transports (streams PHP, fsockopen) si cURL n est pas installé. Elle offre en plus la gestion native des hooks WordPress, un format de réponse standardisé et une vérification SSL automatique. cURL direct fonctionne aussi mais n est pas portable entre hébergements et ignore les filtres WordPress.

Comment sécuriser une clé API dans WordPress ?

Définissez votre clé comme constante dans wp-config.php avec define( ‘MA_CLE’, ‘valeur’ ), puis appelez-la dans votre code avec la constante. Sur un VPS, préférez une variable d environnement serveur via getenv(). Ajoutez wp-config.php et .env à votre .gitignore. Ne stockez jamais une clé API dans un fichier template, dans la base de données via un champ ACF, ou dans du code versionné sur Git.

Pourquoi utiliser les Transients pour mettre en cache les appels API ?

Un appel API externe ajoute entre 300 et 800 ms au temps de chargement de chaque page. Les Transients WordPress stockent les données en base (ou en mémoire si Redis est configuré) avec une durée d expiration. Ainsi, l API n est appelée qu une fois par période de cache au lieu d une fois par visiteur. Pour des données météo, un cache de 30 minutes est suffisant ; pour des données statiques, 24 heures conviennent.

wp_remote_get renvoie une erreur SSL, comment la corriger ?

L erreur « cURL error 60: SSL certificate problem » signifie que le bundle de certificats CA de votre serveur est obsolète. Sur un VPS Linux, mettez à jour le paquet ca-certificates avec apt update et apt install ca-certificates. Sur un hébergement mutualisé, contactez le support technique. Ne désactivez jamais la vérification SSL avec sslverify false en production, car cela expose votre site aux attaques man-in-the-middle.

Comment envoyer des données POST à une API depuis WordPress ?

Utilisez wp_remote_post() avec un tableau d arguments contenant le body en JSON (via wp_json_encode) et le header Content-Type application/json. Pour les requêtes PUT, PATCH ou DELETE, utilisez wp_remote_request() avec le paramètre method. Vérifiez toujours le code de réponse HTTP : 201 pour une création réussie, 200 pour une mise à jour, 204 pour une suppression.


Thomas Lefèvre
Thomas Lefèvre

Thomas Lefèvre est développeur freelance full-stack à Paris depuis 2015, spécialisé WordPress sur mesure, no-code (Bubble, Webflow, Make) et SEO technique. Ex-OpenClassrooms, intervenant ponctuel à l école 42, il documente sur Synergie.Web les outils, techniques et vrais coûts du web freelance en France, testés sur de vrais projets clients.