Documentation API Redax
L'API Redax v1 te permet de connecter Redax à tes outils externes (n8n, Zapier, Make, ton CMS). Tu peux récupérer tes articles, clients et audits, et recevoir des notifications en temps réel via webhooks signés.
Version
v1 (stable)
URL de base
https://www.getredax.com/api/v1Authentification
Chaque clé API est liée à un client précis (scope client). Elle donne accès uniquement aux ressources de ce client.
- Crée tes clés depuis
/settings/apidans le dashboard - La clé complète est affichée une seule fois à la création — conserve-la
- Seul le préfixe est stocké en clair (
redax_live_XXXX…), la clé entière est hashée bcrypt en base
Header attendu :
Authorization: Bearer redax_live_...Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
https://www.getredax.com/api/v1/clientRate limiting
L'API est limitée à 100 requêtes par minute par clé API (sliding window via Upstash Redis).
Headers retournés quand la limite est dépassée :
| Header | Description |
|---|---|
X-RateLimit-Limit | Limite totale (100) |
X-RateLimit-Remaining | Requêtes restantes dans la fenêtre courante |
X-RateLimit-Reset | Timestamp Unix de réinitialisation de la fenêtre |
Retry-After | Secondes avant de pouvoir réessayer |
Code HTTP retourné : 429 Too Many Requests
Pagination
Les endpoints de liste ( /articles, /audits) supportent la pagination par offset.
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
| limit | integer | 20 | Nombre d'items (1–100) |
| offset | integer | 0 | Décalage depuis le début |
Format de réponse :
{
"data": [...],
"pagination": {
"total": 42,
"limit": 20,
"offset": 0,
"has_more": true
}
}Endpoints
GET/api/v1/client
Retourne le client lié à ta clé API.
Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
https://www.getredax.com/api/v1/clientRéponse :
{
"data": {
"id": "uuid",
"name": "Mon Client",
"website_url": "https://example.com",
"niche_template": "ecommerce",
"niche_description": "Boutique de vêtements bio",
"target_audience": "Femmes 25-45 ans sensibles à l'écologie",
"language": "fr",
"created_at": "2026-01-15T10:00:00.000Z",
"updated_at": "2026-03-20T14:30:00.000Z"
}
}GET/api/v1/articles
Liste les articles du client, triés par date de création décroissante.
| Paramètre | Type | Description |
|---|---|---|
| status | string | Filtre par statut : draft, optimizing, completed, error |
| limit | integer | Nombre d'articles (1–100, défaut 20) |
| offset | integer | Décalage (défaut 0) |
Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
"https://www.getredax.com/api/v1/articles?status=completed&limit=10"Réponse :
{
"data": [
{
"id": "uuid",
"title": "Les 10 meilleures pratiques SEO en 2026",
"meta_description": "Découvre les techniques SEO les plus efficaces...",
"status": "completed",
"seo_score": 87,
"geo_score": 72,
"word_count": 1850,
"created_at": "2026-05-10T09:00:00.000Z",
"updated_at": "2026-05-10T09:45:00.000Z"
}
],
"pagination": {
"total": 34,
"limit": 10,
"offset": 0,
"has_more": true
}
}GET/api/v1/articles/:id
Détail complet d'un article, incluant content_html et content_markdown.
Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
https://www.getredax.com/api/v1/articles/uuid-de-larticleRéponse :
{
"data": {
"id": "uuid",
"title": "Les 10 meilleures pratiques SEO en 2026",
"meta_description": "Découvre les techniques SEO...",
"content_html": "<h1>Les 10 meilleures...</h1><p>...</p>",
"content_markdown": "# Les 10 meilleures...
...",
"status": "completed",
"seo_score": 87,
"geo_score": 72,
"word_count": 1850,
"created_at": "2026-05-10T09:00:00.000Z",
"updated_at": "2026-05-10T09:45:00.000Z"
}
}GET/api/v1/audits
Liste les audits SEO+GEO du client, triés par date de création décroissante.
| Paramètre | Type | Description |
|---|---|---|
| status | string | Filtre par statut : pending, running, completed, failed |
| limit | integer | Nombre d'audits (1–100, défaut 20) |
| offset | integer | Décalage (défaut 0) |
Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
"https://www.getredax.com/api/v1/audits?status=completed&limit=5"Réponse :
{
"data": [
{
"id": "uuid",
"url": "https://example.com/page",
"status": "completed",
"progress": 100,
"overall_score": 78,
"technical_score": 82,
"content_score": 75,
"geo_score": 68,
"schema_score": 90,
"images_score": 71,
"created_at": "2026-05-15T14:00:00.000Z",
"completed_at": "2026-05-15T14:02:30.000Z"
}
],
"pagination": {
"total": 12,
"limit": 5,
"offset": 0,
"has_more": true
}
}GET/api/v1/audits/:id
Détail complet d'un audit avec full_report (rapport JSON structuré) et cwv_data (Core Web Vitals).
Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
https://www.getredax.com/api/v1/audits/uuid-de-lauditRéponse :
{
"data": {
"id": "uuid",
"url": "https://example.com/page",
"status": "completed",
"progress": 100,
"overall_score": 78,
"technical_score": 82,
"content_score": 75,
"geo_score": 68,
"schema_score": 90,
"images_score": 71,
"full_report": { ... },
"cwv_data": {
"lcp": 2.1,
"fid": 45,
"cls": 0.08
},
"created_at": "2026-05-15T14:00:00.000Z",
"completed_at": "2026-05-15T14:02:30.000Z"
}
}GET/api/v1/audits/:id/issues
Issues détectées dans un audit, triées par sévérité (critical → high → medium → low).
Exemple curl :
curl -H "Authorization: Bearer redax_live_..." \
https://www.getredax.com/api/v1/audits/uuid-de-laudit/issuesRéponse :
{
"data": [
{
"id": "uuid",
"issue_code": "missing_h1",
"severity": "critical",
"category": "technical",
"title": "Balise H1 manquante",
"description": "La page ne contient pas de balise H1.",
"fix": "Ajoute une balise H1 avec le mot-clé principal.",
"estimated_impact": "Amélioration du score technique de +8 points",
"status": "open",
"created_at": "2026-05-15T14:02:30.000Z"
}
]
}GET/api/v1/campaigns
Liste les campagnes éditoriales du client, triées par date de création décroissante.
| Paramètre | Type | Description |
|---|---|---|
| status | string | Filtre par statut : draft, running, paused, completed, cancelled |
| limit | integer | Nombre d'éléments (1–100, défaut 20) |
| offset | integer | Décalage (défaut 0) |
Exemple curl :
curl -H "Authorization: Bearer redax_live_xxx" \
"https://www.getredax.com/api/v1/campaigns?status=running&limit=10"Réponse :
{
"data": [
{
"id": "uuid",
"name": "Test email completed",
"status": "completed",
"cadence_days": 1,
"scheduled_time": "09:00:00",
"timezone": "Europe/Paris",
"start_date": "2026-05-18",
"total_articles": 1,
"generated_count": 1,
"failed_count": 0,
"created_at": "2026-05-18T16:14:00Z",
"completed_at": "2026-05-18T16:21:00Z",
"paused_at": null
}
],
"pagination": { "limit": 10, "offset": 0, "count": 1 }
}GET/api/v1/campaigns/:id
Détail d'une campagne incluant la liste de ses articles planifiés dans scheduled_articles.
Exemple curl :
curl -H "Authorization: Bearer redax_live_xxx" \
"https://www.getredax.com/api/v1/campaigns/uuid"Réponse :
{
"id": "uuid",
"name": "Test email completed",
"status": "completed",
"cadence_days": 1,
"scheduled_time": "09:00:00",
"timezone": "Europe/Paris",
"start_date": "2026-05-18",
"total_articles": 1,
"generated_count": 1,
"failed_count": 0,
"created_at": "2026-05-18T16:14:00Z",
"completed_at": "2026-05-18T16:21:00Z",
"paused_at": null,
"scheduled_articles": [
{
"id": "uuid",
"position": 1,
"brief": "Le ROI des robots aspirateurs...",
"focus_keyword": "robots aspirateurs industriels",
"scheduled_for": "2026-05-18T16:15:00Z",
"status": "generated",
"error_message": null,
"retry_count": 0,
"article_id": "uuid",
"generated_at": "2026-05-18T16:21:00Z"
}
]
}Statuts possibles pour scheduled_articles[].status :
| Statut | Description |
|---|---|
pending | En attente du prochain cron (toutes les 5 min) |
generating | Génération en cours via Claude |
generated | Article créé avec succès — article_id rempli |
failed | Échec — voir error_message |
cancelled / skipped | Suite à une annulation manuelle de la campagne |
Pour récupérer l'article complet, appelle GET /api/v1/articles/{article_id} avec le article_id retourné.
Webhooks
Configuration
Configure tes webhooks depuis /settings/webhooks dans le dashboard. Pour chaque webhook tu définis :
- Une URL HTTPS qui recevra les POST
- La liste des events à écouter
- Un secret partagé utilisé pour signer chaque payload HMAC SHA256
Le secret complet est affiché une seule fois à la création — conserve-le.
Events disponibles
| Event | Quand | Data |
|---|---|---|
article.generated | Article généré avec succès | Objet article (id, title, scores, word_count…) |
audit.completed | Audit SEO+GEO terminé (status = completed) | Objet audit (id, url, scores…) |
test.ping | Déclenché manuellement depuis l'UI | { message, timestamp } |
Format du payload
Chaque payload reçu a cette enveloppe :
{
"event": "article.generated",
"created_at": "2026-05-18T11:30:00.000Z",
"delivery_id": "uuid-pour-idempotency",
"data": {
// Données spécifiques à l'event
}
}Utilise delivery_id pour l'idempotency — chaque tentative a un ID unique.
Headers envoyés
| Header | Valeur | Description |
|---|---|---|
Content-Type | application/json | Toujours présent |
User-Agent | Redax-Webhook/1.0 | |
X-Redax-Event | article.generated | Nom de l'event |
X-Redax-Delivery-Id | uuid v4 | Unique par tentative — utilise-le pour l'idempotency |
X-Redax-Signature | sha256={hex} | HMAC SHA256 du body brut |
Vérification de la signature
Vérifie toujours la signature avant de traiter un payload. Utilise le body brut (raw body, pas le JSON parsé).
Exemple Node.js :
import crypto from "crypto"
function verifyRedaxSignature(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex")
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
)
}
// Express
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.headers["x-redax-signature"]
if (!verifyRedaxSignature(req.body, sig, process.env.REDAX_WEBHOOK_SECRET)) {
return res.status(401).send("Invalid signature")
}
const payload = JSON.parse(req.body.toString())
// traite payload.event...
res.status(200).send("OK")
})En n8n :
// Code node (JavaScript)
const rawBody = $input.first().json.rawBody
const signature = $input.first().headers["x-redax-signature"]
const secret = "whsec_..."
const expected = "sha256=" + require("crypto")
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex")
if (signature !== expected) throw new Error("Invalid signature")
return $input.all()Retry policy
- 2 tentatives max (1 essai initial + 1 retry)
- Backoff : 1 seconde entre les tentatives
- Timeout par tentative : 3 secondes
- Si 10 échecs consécutifs, le webhook est désactivé automatiquement — tu peux le réactiver depuis
/settings/webhooks - Toutes les tentatives sont visibles dans l'onglet Deliveries
Codes erreur
Les erreurs retournent toujours un JSON { "error": "code_machine" }.
| Code HTTP | Error machine | Cause |
|---|---|---|
| 401 | missing_or_invalid_auth_header | Pas de header Authorization Bearer |
| 401 | invalid_api_key | Clé invalide, révoquée ou inexistante |
| 400 | invalid_query_params | Query params invalides (limit hors 1–100, etc.) |
| 400 | invalid_body | Body JSON invalide ou champs manquants |
| 404 | not_found | Resource introuvable ou hors scope du client |
| 429 | rate_limit_exceeded | 100 req/min dépassé — attends Retry-After secondes |
| 500 | internal_error | Erreur serveur — à signaler à hello@axyos-agency.com |