OpenClaw API skills : connecter une API externe
Apprenez à créer des skills HTTP OpenClaw pour appeler une API externe, gérer l'auth et fiabiliser vos intégrations Python.
OpenClaw API skills
Introduction
Les skills API sont ce qui transforme un agent OpenClaw en outil réellement utile. Tant qu'un agent reste limité au texte, il raisonne. Dès qu'il sait appeler une API, il peut récupérer une météo, lire un stock, créer un ticket ou pousser une donnée métier. Si vous avez déjà lu Comprendre les skills OpenClaw, ce tutoriel est l'étape suivante. Vous allez voir comment structurer un skill HTTP, appeler une API publique en GET, ajouter une authentification propre, envoyer un POST et gérer les erreurs sans rendre votre agent fragile.
Résumé rapide
- Un skill API OpenClaw encapsule un appel HTTP dans une classe réutilisable.
- Commencez par un GET simple sur une API publique avant d'ajouter auth et POST.
- Stockez toujours les clés dans des variables d'environnement, jamais dans le code.
- Gérez explicitement timeout, erreurs HTTP et formats de réponse inattendus.
- Testez le skill isolément avant de l'attacher à un agent OpenClaw.
Anatomie d'un skill API OpenClaw
Dans OpenClaw, un skill est une unité d'action exposée à l'agent. L'agent décide quand l'utiliser, mais le skill reste responsable de trois choses : valider les entrées, exécuter l'action et retourner une sortie exploitable. C'est ce découplage qui rend les intégrations API fiables et réutilisables.
Dans la pratique, un skill HTTP contient généralement :
- une description claire pour que le LLM sache quand l'appeler ;
- un schéma d'entrée simple, idéalement validé ;
- un client HTTP, souvent
httpx; - une sortie structurée, courte et prévisible.
Si vous voulez remettre ce pattern dans le cadre global d'un agent, lisez aussi Comprendre les agents OpenClaw. L'agent orchestre, le skill agit.
Pour ce tutoriel, on utilise httpx, car il gère bien les timeouts, les headers, le JSON et les clients synchrones ou asynchrones. Un skill synchrone suffit dans la majorité des cas. Passez à l'asynchrone seulement si vous devez lancer beaucoup d'appels concurrents ou intégrer le skill dans une boucle intensive.
Voici une structure minimale et réaliste :
import httpx
from pydantic import BaseModel, Field
from openclaw.skills import BaseSkill, skill
from openclaw.types import SkillOutput
class ApiGetInput(BaseModel):
url: str = Field(..., description="URL complète à appeler")
timeout: int = Field(10, ge=1, le=30)
@skill(
name="api_get",
description="Récupère des données JSON depuis une API HTTP en GET."
)
class ApiGetSkill(BaseSkill):
def run(self, input: ApiGetInput) -> SkillOutput:
try:
response = httpx.get(input.url, timeout=input.timeout)
response.raise_for_status()
return SkillOutput(success=True, data=response.json())
except httpx.HTTPError as exc:
return SkillOutput(success=False, error=str(exc))
Ce code fait peu de choses, mais il pose les bonnes bases : paramètres explicites, timeout par défaut, raise_for_status() et gestion d'erreur propre.
Créer un skill GET simple
Le meilleur point de départ est une API publique sans authentification. CoinGecko est pratique pour ça, car vous pouvez récupérer un prix crypto sans clé API. Le skill ci-dessous renvoie le prix d'un actif en devise cible.
Étape 1, définir le schéma d'entrée
On limite les paramètres à l'essentiel : identifiant du coin, devise cible, timeout.
Étape 2, appeler l'API et normaliser la réponse
Le skill ne doit pas renvoyer tout le JSON brut si l'agent n'en a pas besoin. Il vaut mieux retourner un objet simple et stable.
import httpx
from pydantic import BaseModel, Field
from openclaw.skills import BaseSkill, skill
from openclaw.types import SkillOutput
class CoinPriceInput(BaseModel):
coin_id: str = Field(..., description="Exemple: bitcoin, ethereum")
vs_currency: str = Field("eur", description="Devise cible, ex: eur ou usd")
timeout: int = Field(10, ge=1, le=30)
@skill(
name="coingecko_price",
description="Récupère le prix d'un crypto-actif via l'API publique CoinGecko."
)
class CoinGeckoPriceSkill(BaseSkill):
def run(self, input: CoinPriceInput) -> SkillOutput:
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": input.coin_id,
"vs_currencies": input.vs_currency,
}
try:
response = httpx.get(url, params=params, timeout=input.timeout)
response.raise_for_status()
payload = response.json()
if input.coin_id not in payload:
return SkillOutput(
success=False,
error=f"Actif introuvable: {input.coin_id}"
)
price = payload[input.coin_id].get(input.vs_currency)
return SkillOutput(
success=True,
data={
"coin_id": input.coin_id,
"vs_currency": input.vs_currency,
"price": price,
},
)
except httpx.TimeoutException:
return SkillOutput(success=False, error="Timeout API CoinGecko")
except httpx.HTTPError as exc:
return SkillOutput(success=False, error=str(exc))
Une fois ce skill prêt, vous pouvez l'enregistrer dans un agent chargé de surveillance ou de reporting. C'est aussi un bon exercice avant d'explorer d'autres exemples de skills OpenClaw.
Checklist de validation
- le skill répond avec un JSON court ;
- le timeout est borné ;
- les cas d'absence de donnée sont gérés ;
- l'agent n'a pas à connaître la structure brute de l'API.
Gérer l'authentification et les variables d'environnement
Dès que vous quittez les APIs publiques, vous devez gérer l'authentification proprement. Le principe est simple : la clé ou le token ne doit jamais être hardcodé dans la classe. Chargez-le depuis une variable d'environnement, puis injectez-le dans les headers.
Exemple avec un Bearer token :
import os
import httpx
from pydantic import BaseModel, Field
from openclaw.skills import BaseSkill, skill
from openclaw.types import SkillOutput
class WeatherInput(BaseModel):
city: str = Field(..., description="Nom de la ville")
@skill(
name="weather_private_api",
description="Récupère la météo depuis une API privée protégée par Bearer token."
)
class PrivateWeatherSkill(BaseSkill):
def run(self, input: WeatherInput) -> SkillOutput:
api_token = os.environ.get("WEATHER_API_TOKEN")
if not api_token:
return SkillOutput(success=False, error="WEATHER_API_TOKEN manquant")
headers = {"Authorization": f"Bearer {api_token}"}
params = {"city": input.city}
try:
response = httpx.get(
"https://api.example.com/weather",
headers=headers,
params=params,
timeout=10,
)
response.raise_for_status()
payload = response.json()
return SkillOutput(
success=True,
data={
"city": input.city,
"temperature": payload.get("temperature"),
"condition": payload.get("condition"),
},
)
except httpx.HTTPStatusError as exc:
return SkillOutput(success=False, error=f"HTTP {exc.response.status_code}")
except httpx.HTTPError as exc:
return SkillOutput(success=False, error=str(exc))
Le même pattern fonctionne avec une API key dans un header comme X-API-Key, ou dans un paramètre de requête si le fournisseur l'impose. Pour OAuth, le plus simple est souvent de déléguer l'obtention du token à une couche séparée, puis de faire consommer au skill un jeton déjà valide. N'encombrez pas votre skill métier avec toute la négociation OAuth si vous pouvez l'éviter.
Créer un skill POST et envoyer des données
Un bon openclaw http skill ne sert pas seulement à lire des données. Il peut aussi créer une ressource côté API, par exemple un lead, un ticket support ou une note CRM. Ici, l'important est de valider le payload avant l'envoi et de retourner un résultat simple à l'agent.
import os
import httpx
from pydantic import BaseModel, EmailStr, Field
from openclaw.skills import BaseSkill, skill
from openclaw.types import SkillOutput
class CreateLeadInput(BaseModel):
name: str = Field(..., min_length=2)
email: EmailStr
source: str = Field("openclaw-agent")
@skill(
name="crm_create_lead",
description="Crée un lead dans le CRM via une API HTTP POST."
)
class CreateLeadSkill(BaseSkill):
def run(self, input: CreateLeadInput) -> SkillOutput:
api_key = os.environ.get("CRM_API_KEY")
if not api_key:
return SkillOutput(success=False, error="CRM_API_KEY manquant")
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
payload = {
"name": input.name,
"email": input.email,
"source": input.source,
}
try:
response = httpx.post(
"https://api.example-crm.com/v1/leads",
headers=headers,
json=payload,
timeout=10,
)
response.raise_for_status()
created = response.json()
return SkillOutput(
success=True,
data={
"lead_id": created.get("id"),
"status": created.get("status", "created"),
},
)
except httpx.HTTPStatusError as exc:
error_body = exc.response.text[:300]
return SkillOutput(
success=False,
error=f"POST refusé ({exc.response.status_code}): {error_body}",
)
except httpx.HTTPError as exc:
return SkillOutput(success=False, error=str(exc))
Piège courant : renvoyer toute la réponse brute du CRM. En général, l'agent a seulement besoin d'un identifiant, d'un statut et parfois d'un message d'erreur lisible. Gardez la sortie compacte.
Exemple concret
Prenons un cas simple et reproductible : un agent de veille crypto doit répondre à la question « quel est le prix actuel du bitcoin en euros, puis enregistrer l'information dans un outil interne ? ».
Le workflow se décompose bien en deux skills API :
coingecko_priceappelle une API publique pour récupérer le prix.crm_create_leadou un skill POST équivalent envoie la donnée à un service interne, par exemple un journal d'événements ou un mini back-office.
Dans OpenClaw, l'agent peut utiliser le premier skill pour récupérer :
{
"coin_id": "bitcoin",
"vs_currency": "eur",
"price": 86342
}
Puis formater un second appel avec ce résultat. L'intérêt n'est pas seulement technique. Vous obtenez une architecture claire :
- le skill GET lit une source externe ;
- le skill POST pousse une donnée métier ;
- l'agent garde la logique de décision entre les deux.
C'est précisément ce qui rend une openclaw intégration api maintenable. Si l'API source change, vous modifiez le skill GET. Si la destination change, vous modifiez le skill POST. L'agent, lui, reste presque intact. Sur des workflows plus larges, ce découplage évite les scripts monolithiques difficiles à faire évoluer.
Bonnes pratiques
La première bonne pratique est la sobriété. Un skill API doit faire une chose bien, pas devenir un mini SDK universel. Si vous devez gérer plusieurs endpoints très différents, créez plusieurs skills.
Ensuite, sécurisez vos secrets : variables d'environnement, rotation des clés, logs nettoyés. Ne stockez jamais une clé API dans le dépôt ni dans le frontmatter d'un article de test. Si vous développez en équipe, documentez les variables nécessaires dans un .env.example sans valeurs réelles.
Sur la robustesse, fixez toujours un timeout, utilisez raise_for_status() et traitez séparément les erreurs réseau, les erreurs HTTP et les réponses JSON invalides. Pour les retries, limitez-vous aux erreurs temporaires comme 429, 502, 503 ou 504. Ne réessayez pas un 401 ou un 403, qui indiquent souvent un problème d'authentification.
Enfin, testez le skill isolément avant intégration à l'agent. Un simple test unitaire avec mock HTTP suffit souvent pour valider les cas critiques : succès, timeout, réponse vide, statut 500. C'est le moyen le plus rapide de fiabiliser un skill api externe openclaw.
Questions fréquentes
Comment brancher une API sur OpenClaw ?
Créez un skill Python dédié à l'appel HTTP, avec un schéma d'entrée clair, un client httpx, une gestion d'erreur explicite et une sortie JSON compacte. Ensuite, enregistrez ce skill dans votre agent. C'est la méthode la plus simple pour brancher une API OpenClaw proprement.
Faut-il créer un skill synchrone ou asynchrone ?
Commencez en synchrone dans la plupart des cas. C'est plus simple à maintenir et largement suffisant pour quelques appels API par tâche. Passez à l'asynchrone seulement si votre agent enchaîne beaucoup de requêtes concurrentes ou si la latence devient un vrai goulot d'étranglement.
Où stocker les clés API d'un skill OpenClaw ?
Dans des variables d'environnement, jamais en dur dans le code. Le skill lit ensuite os.environ au moment de l'exécution. Cette pratique réduit les risques de fuite de secrets et facilite le déploiement sur VPS, Docker ou CI.
Peut-on utiliser GraphQL dans un openclaw http skill ?
Oui. Techniquement, un appel GraphQL reste souvent un POST HTTP avec un JSON contenant query et éventuellement variables. La structure du skill reste la même : validation d'entrée, headers d'authentification, timeout, puis normalisation de la réponse pour l'agent.
Quelle différence entre un skill API et un agent OpenClaw ?
Le skill exécute une action ciblée, par exemple appeler un endpoint REST. L'agent décide quand utiliser ce skill, dans quel ordre, et quoi faire du résultat. En clair, le skill agit, l'agent orchestre.
Articles liés
Un bon skill API OpenClaw reste simple, testable et centré sur une action métier claire. Commencez par un GET public, ajoutez ensuite l'authentification, puis un POST si votre workflow doit écrire dans un système tiers. La prochaine étape logique consiste à enrichir votre boîte à outils avec d'autres patterns de skills.
Vous avez créé votre premier skill API ? Découvrez d'autres exemples de skills OpenClaw pour étendre les capacités de vos agents.
Restez informé sur les agents IA
Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.