API développeur

Documentation API

Créez des liens protégés, consultez des analyses respectueuses de la vie privée et enregistrez les conversions de votre produit.

01

Effectuez votre première requête

L’API fonctionne de serveur à serveur. N’exposez jamais un jeton dans le JavaScript du navigateur ou un bundle mobile public.

  1. 1Activez Pro ou BusinessL’accès API est activé sur les offres payantes compatibles et pendant l’essai Pro.
  2. 2Créez un jeton à portée limitéeChoisissez uniquement les autorisations nécessaires à votre intégration dans la console développeur.
  3. 3Envoyez-le via HTTPSAuthorization: Bearer 4ul_live_…
  4. 4Conservez-le comme un mot de passeLe jeton complet n’est affiché qu’une fois. Révoquez-le immédiatement en cas d’exposition possible.
curl "https://4ul.ink/api/v1/links?per_page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
02

Référence des endpoints

L’accès à chaque objet est limité au workspace associé au jeton.

MéthodeCheminPortéeRésultat
GET/api/v1/linkslinks:readLiens paginés
POST/api/v1/linkslinks:writeCrée un lien protégé
PATCH/api/v1/links/{id}links:writeMet à jour les champs fournis
DELETE/api/v1/links/{id}links:writeDésactive sans supprimer les analyses
GET/api/v1/links/{id}/analyticsanalytics:readAnalyses agrégées
POST/api/v1/conversionslinks:writeEnregistre un événement attribué
GET/api/v1/domainsdomains:readDomaines personnalisés
POST/api/v1/domainsdomains:writeConnecter un domaine
POST/api/v1/domains/{id}/verifydomains:writeVérifier le DNS
DELETE/api/v1/domains/{id}domains:writeSupprimer
GET/api/v1/webhookswebhooks:readEndpoints webhook
POST/api/v1/webhookswebhooks:writeAjouter un endpoint
PATCH/api/v1/webhooks/{id}webhooks:writeMet à jour les champs fournis
POST/api/v1/webhooks/{id}/testwebhooks:writeEnvoyer un test
POST/api/v1/webhooks/{id}/rotate-secretwebhooks:writeRenouveler le secret
DELETE/api/v1/webhooks/{id}webhooks:writeSupprimer
03

Requêtes et réponses

Les noms de champs correspondent exactement à l’API v1 en production.

POST

Créer un lien

links:write
{
    "destination_url": "https://example.com",
    "slug": "launch",
    "title": "Launch article"
}
destination_url
URL publique HTTP ou HTTPS obligatoire.
title
Facultatif, jusqu’à 190 caractères.
slug
Alias personnalisé facultatif, de 3 à 80 caractères.
201

Réponse du lien

application/json
{
  "data": {
    "id": 123,
    "slug": "launch",
    "short_url": "https://4ul.ink/launch",
    "destination_url": "https://example.com/article",
    "title": "Launch article",
    "click_count": 0,
    "is_active": true,
    "created_at": "2026-07-25 12:00:00"
  }
}
GET

Lister les liens

?page=1&per_page=25
{
  "data": [{ "id": 123, "slug": "launch", "is_active": true }],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
  }
}

per_page accepte de 1 à 100. Les objets lien utilisent la structure complète présentée ci-dessus.

GET

Lire les analyses

analytics:read
/api/v1/links/123/analytics?period=custom
  &from=2026-07-01
  &to=2026-07-20

Les périodes sont 7, 30, 90 ou custom. La réponse inclut aperçu, comparaisons, qualité du trafic, conversions, séries quotidiennes, audiences et tendances horaires, jamais les IP brutes.

PATCH

Mettre à jour un lien

/api/v1/links/123
{
  "destination_url": "https://example.com/new",
  "title": "New title",
  "slug": "new-alias",
  "is_active": true
}

Seuls les champs fournis changent. Un changement de destination programme automatiquement une nouvelle analyse Nova Shield.

POST

Enregistrer une conversion

/api/v1/conversions
{
  "click_token": "4ul_click_…",
  "event": "sale",
  "external_id": "order_1042",
  "amount": 49.00,
  "currency": "USD"
}

Les événements sont lead, sale ou refund. Un événement externe en double renvoie HTTP 409 et n’est jamais compté deux fois.

Portées du jeton

links:read
liste les liens.
links:write
crée, met à jour et désactive les liens et enregistre les conversions.
analytics:read
lit les analyses des liens.
domains:read / domains:write
Domaines personnalisés
webhooks:read / webhooks:write
Webhooks signés

Limites de requêtes

Les jetons autorisent 120 requêtes par minute plus le quota mensuel du workspace. Analytics a une limite supplémentaire de 60 par minute. HTTP 429 inclut Retry-After et RateLimit. Les redirections continuent de fonctionner.

Idempotence

Lors de la création, envoyez un Idempotency-Key de 8 à 128 caractères imprimables. Il reste valable 24 heures dans le workspace. Une répétition identique rejoue la réponse ; des données différentes renvoient HTTP 409.

HTTP

Erreurs

Les erreurs utilisent un format JSON unique. Statuts courants : 400 JSON invalide, 401 jeton invalide, 403 portée ou offre absente, 404 introuvable, 409 conflit, 413 corps trop grand, 415 type incorrect, 422 validation et 429 limite.

{
  "error": "destination_url must be a valid public HTTP or HTTPS URL.",
  "code": "invalid_destination",
  "field": "destination_url",
  "request_id": "req_7fd9c0c8d821e84b3d69d171",
  "error_details": {
    "code": "invalid_destination",
    "message": "destination_url must be a valid public HTTP or HTTPS URL.",
    "field": "destination_url",
    "request_id": "req_7fd9c0c8d821e84b3d69d171"
  }
}
HMAC

Vérifiez chaque webhook

Événements : link.created, link.updated, link.disabled, link.clicked, conversion.created, shield.status_changed et endpoint.test. La livraison automatique réessaie jusqu’à cinq fois.

Les webhooks de disponibilité utilisent shield.availability_changed avec transitions et diagnostics HTTP limités, sans URL de destination.

En-têtes de livraison

X-4ulink-Event: conversion.created
X-4ulink-Delivery: EVENT_UUID
X-4ulink-Timestamp: UNIX_TIMESTAMP
X-4ulink-Signature: sha256=HEX_HMAC

Vérification PHP

$raw = file_get_contents('php://input');
$signed = $timestamp . '.' . $raw;
$expected = 'sha256=' . hash_hmac('sha256', $signed, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}

Utilisez le corps brut, comparez les signatures en temps constant, refusez les horodatages de plus de cinq minutes et stockez X-4ulink-Delivery pour des répétitions idempotentes. L’endpoint doit utiliser HTTPS public sur le port 443.