API et serveur MCP

Créez des jetons dans votre espace, rubrique Développeurs. Chaque jeton a des droits limités, se modifie (nom et droits) et se révoque à tout moment.

Authentification

Authorization: Bearer rl_live_…

Réponses en JSON. Erreurs : { "error": { "code", "message" } }. Limite de débit selon la formule (Solo 20, Pro 60, Agence 120 requêtes par minute) et 1 requête par seconde au plus, indiquées dans les en-têtes X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Burst. Au-delà : 429 avec Retry-After. Service très sollicité : 503 avec Retry-After. Pour créer beaucoup de liens, utilisez /v1/links/batch.

Modifier : POST ou PATCH

Les trois points d’accès de modification acceptent POST aussi bien que PATCH, sur le même chemin et avec le même corps. Préférez POST : certaines infrastructures (pare-feu, façade d’hébergement, proxy d’entreprise) coupent les requêtes PATCH avant qu’elles n’arrivent au service, et la connexion est alors réinitialisée sans réponse HTTP. Les en-têtes X-HTTP-Method-Override: PATCH et le champ _method sont acceptés aussi ; ils ne sont pas nécessaires.

curl -X POST https://api.reli.es/v1/links/42 \
  -H "Authorization: Bearer rl_live_…" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://exemple.fr/nouvelle-page"}'

Créer un lien

curl https://api.reli.es/v1/links \
  -H "Authorization: Bearer rl_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://exemple.fr/offre",
    "slug": "offre-hiver",
    "tags": ["sms"],
    "utm": {"source": "sms", "campaign": "hiver"},
    "expires_at": "2026-12-31T23:59:00+01:00"
  }'
201 Created
{
  "data": {
    "id": 42,
    "short_url": "https://reli.es/offre-hiver",
    "domain": "reli.es",
    "slug": "offre-hiver",
    "destination": "https://exemple.fr/offre",
    "title": null,
    "status": "active",
    "tags": ["sms"],
    "utm": {"source": "sms", "campaign": "hiver"},
    "protected": false,
    "starts_at": null,
    "ends_at": "2026-12-31T23:59:00+01:00",
    "expired_url": null,
    "clicks": 0,
    "qr_svg": "https://api.reli.es/v1/links/42/qr.svg",
    "created_at": "2026-09-29T10:12:04+02:00"
  }
}

Noms des champs

La réponse nomme la destination « destination » et la date de fin « ends_at ». À l’envoi, les deux écritures sont acceptées : url ou destination, expires_at ou ends_at. Tout autre nom est refusé par un 422 qui le désigne — un champ mal nommé n’est jamais ignoré en silence.

422 Unprocessable Content
{ "error": {
  "code": "unknown_field",
  "message": "Champ inconnu : lien. Champs acceptés : url, destination, …",
  "unknown": ["lien"],
  "accepted": ["url", "destination", "title", "tags", "utm", "starts_at", "expires_at", "ends_at", "expired_url", "password"]
} }

Lister les liens

Filtres : tag, status (active, archived, blocked, review), domain, q, limit (100 au plus) et cursor. Le curseur de page suivante est à la racine de la réponse ; il vaut null sur la dernière page. Les liens des pages bio et des campagnes ne figurent pas dans cette liste.

GET https://api.reli.es/v1/links?tag=sms&limit=50
{ "data": [ { "id": 42, … } ], "next_cursor": "42" }

Statistiques

GET /v1/links/{id}/stats?days=30 (1 à 365 jours). Un clic est enregistré tout de suite : il apparaît dans la foulée. Les ouvertures répétées du même visiteur dans les 30 minutes comptent dans repeats, jamais dans clicks. Un appel venu d’un serveur (sans langue d’affichage, en HEAD, ou préchargé par le navigateur) compte dans bots : un essai en ligne de commande n’augmente donc pas clicks.

{ "data": {
  "days": 30, "clicks": 128, "uniques": 96, "qr": 12, "bots": 31, "repeats": 7,
  "previous_period_clicks": 88,
  "daily": [ {"date": "2026-09-01", "clicks": 4}, … ],
  "countries": [ {"label": "FR", "n": 101}, … ],
  "cities": [ … ], "devices": [ … ], "sources": [ … ],
  "link": { "id": 42, "short_url": "https://reli.es/offre-hiver" }
} }

Fins de lien

Fin de lien choisie (slug) : de 2 à 64 caractères, lettres minuscules, chiffres et tirets, sans tiret au début ni à la fin. Les majuscules envoyées sont ramenées en minuscules. Une fin de lien déjà prise, réservée ou interdite donne un 422 avec un message qui propose une variante. Une fin de lien n’est jamais réattribuée, même après archivage.

Sans slug, le service en attribue une de six caractères en minuscules, sans caractère ambigu (ni 0 ni o, ni 1 ni l ni i) : lisible sous un QR code imprimé et dictable au téléphone.

Points d’accès

MéthodeCheminDroitRôle
POST/v1/linkslinks:writeCréer un lien : url, domain, slug, title, tags, utm, starts_at, expires_at, expired_url, password
POST/v1/links/batchlinks:writeCréer jusqu’à 100 liens : { "links": [ … ] } ; réponse 207 avec une ligne par lien
GET/v1/linkslinks:readLister : tag, status, domain, q, cursor, limit (100 au plus)
GET/v1/links/{id}links:readLire un lien
POST · PATCH/v1/links/{id}links:writeModifier destination, titre, tags, dates, UTM
DELETE/v1/links/{id}links:writeArchiver (la fin de lien n’est jamais réattribuée)
GET/v1/links/{id}/statsstats:readStatistiques : days (1 à 365)
GET/v1/links/{id}/qr.svglinks:readQR code SVG ou PNG
GET/v1/domainsdomains:readDomaines utilisables. Ce droit ne sert qu’ici : créer un lien sur reli.es n’en a pas besoin.
GET · POST · PATCH/v1/pages/{handle}pages:read · pages:writeLire une page bio, modifier titre et présentation
GET/v1/account—Formule, limites et consommation
GET/v1/managed-accountsaccounts:managedComptes gérés, à viser par l’en-tête Relies-Account

Campagnes : un lien par contact

Réservé aux comptes agence et aux comptes qu’ils gèrent. Une campagne porte une destination, un domaine, des paramètres de suivi et une date de fin ; chaque contact reçoit ensuite sa propre fin de lien, créée par lots de 100 en une seule requête. La référence de contact (ref) est votre identifiant : de 1 à 64 caractères, lettres, chiffres, point, deux-points, tiret et souligné. Elle est conservée telle quelle : n’y mettez ni nom, ni numéro de téléphone, ni adresse e-mail.

MéthodeCheminRôle
GET · POST/v1/campaignsLister, créer : name, url, domain, utm, expires_at, expired_url, kore_ref
GET · POST · PATCH/v1/campaigns/{id}Lire, modifier : name, url, expires_at, expired_url, kore_ref
POST/v1/campaigns/{id}/contactsAjouter de 1 à 100 contacts en une requête : { "contacts": [ {"ref": "c-1024"}, {"ref": "c-1025", "url": "https://exemple.fr/page-b"} ] }
GET/v1/campaigns/{id}/contactsLister les contacts : clicked, clicked_since, limit (500 au plus)
DELETE/v1/campaigns/{id}/contacts/{ref}Oublier un contact : sa référence est effacée, le lien est archivé
curl https://api.reli.es/v1/campaigns/7/contacts \
  -H "Authorization: Bearer rl_live_…" \
  -H "Content-Type: application/json" \
  -d '{"contacts": [{"ref": "c-1024"}, {"ref": "c-1025", "url": "https://exemple.fr/page-b"}]}'
200 OK (207 si une ligne échoue)
{ "data": [ { "index": 0, "ref": "c-1024", "ok": true, "created": true,
              "link": { "id": 512, "short_url": "https://reli.es/k7m4qp", … } }, … ],
  "created": 2, "existing": 0, "failed": 0 }

Une référence déjà connue de la campagne renvoie le lien existant (existing) : le même envoi peut être rejoué sans créer de doublon. Le premier clic de chaque contact déclenche le webhook campaign.contact_clicked.

Droits des jetons

links:read · links:write · stats:read · pages:read · pages:write · domains:read · campaigns:read · campaigns:write · accounts:managed

Un droit manquant donne un 403 « forbidden » qui nomme le droit attendu. Les droits d’un jeton se modifient dans l’espace, rubrique Développeurs, sans changer sa valeur : les outils déjà branchés continuent de fonctionner.

Webhooks

Événements : link.created, link.blocked, link.clicked (groupé par minute), page.form_submitted, campaign.contact_clicked (comptes gérés). Chaque envoi porte l’en-tête X-Relies-Signature : t=horodatage,v1=signature, où la signature est le HMAC-SHA256 de « horodatage.corps » avec votre secret. Refusez les envois de plus de 5 minutes. Trois nouvelles tentatives en cas d’échec : après 1 minute, 10 minutes, 1 heure.

$payload = file_get_contents('php://input');
[$t, $v1] = sscanf($_SERVER['HTTP_X_RELIES_SIGNATURE'], 't=%d,v1=%s');
$valid = abs(time() - $t) < 300
    && hash_equals(hash_hmac('sha256', $t.'.'.$payload, $secret), $v1);

Serveur MCP

Adresse : https://api.reli.es/mcp · transport HTTP, même jeton que l’API.

claude mcp add --transport http reli-es https://api.reli.es/mcp \
  --header "Authorization: Bearer rl_live_…"
OutilRôle
liens_creerCréer un ou plusieurs liens
liens_chercherChercher par destination, tag, état
liens_statsStatistiques d’un lien ou du compte
lien_modifierModifier destination, titre, tags, dates
lien_archiverArchiver, avec confirmation explicite
page_lire · page_modifierLire une page bio, ajouter un bouton de lien
qr_exporterAdresse du QR code SVG ou PNG
compte_etatFormule, limites et consommation