API per sviluppatori

Documentazione API

Crea link protetti, consulta analisi attente alla privacy e registra conversioni dal tuo prodotto.

01

Effettua la prima richiesta

L’API è server-to-server. Non esporre mai un token nel JavaScript del browser o in un bundle mobile pubblico.

  1. 1Attiva Pro o BusinessL’accesso API è disponibile nei piani a pagamento supportati e durante la prova Pro.
  2. 2Crea un token con ambito limitatoScegli nella Console sviluppatore solo i permessi necessari all’integrazione.
  3. 3Invialo tramite HTTPSAuthorization: Bearer 4ul_live_…
  4. 4Conservalo come una passwordIl token completo viene mostrato una sola volta. Revocalo subito in caso di possibile esposizione.
curl "https://4ul.ink/api/v1/links?per_page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
02

Riferimento degli endpoint

L’accesso a ogni oggetto è limitato al workspace assegnato al token.

MetodoPercorsoAmbitoRisultato
GET/api/v1/linkslinks:readLink paginati
POST/api/v1/linkslinks:writeCrea un link protetto
PATCH/api/v1/links/{id}links:writeAggiorna i campi inviati
DELETE/api/v1/links/{id}links:writeDisattiva senza eliminare le analisi
GET/api/v1/links/{id}/analyticsanalytics:readAnalisi aggregate
POST/api/v1/conversionslinks:writeRegistra un evento attribuito
GET/api/v1/domainsdomains:readDomini personalizzati
POST/api/v1/domainsdomains:writeCollega un dominio
POST/api/v1/domains/{id}/verifydomains:writeVerifica DNS
DELETE/api/v1/domains/{id}domains:writeRimuovi
GET/api/v1/webhookswebhooks:readEndpoint webhook
POST/api/v1/webhookswebhooks:writeAggiungi endpoint
PATCH/api/v1/webhooks/{id}webhooks:writeAggiorna i campi inviati
POST/api/v1/webhooks/{id}/testwebhooks:writeInvia test
POST/api/v1/webhooks/{id}/rotate-secretwebhooks:writeRuota segreto
DELETE/api/v1/webhooks/{id}webhooks:writeElimina
03

Richieste e risposte

I nomi dei campi corrispondono esattamente all’API v1 attiva.

POST

Crea un link

links:write
{
    "destination_url": "https://example.com",
    "slug": "launch",
    "title": "Launch article"
}
destination_url
URL pubblico HTTP o HTTPS obbligatorio.
title
Facoltativo, fino a 190 caratteri.
slug
Alias personalizzato facoltativo, da 3 a 80 caratteri.
201

Risposta del link

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

Elenca link

?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 accetta da 1 a 100. Gli oggetti link usano la struttura completa mostrata sopra.

GET

Leggi analisi

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

I periodi sono 7, 30, 90 o custom. La risposta include panoramica, confronti, qualità del traffico, conversioni, serie giornaliere, pubblico e schemi orari, mai IP grezzi.

PATCH

Aggiorna un link

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

Cambiano solo i campi inviati. Modificare la destinazione accoda automaticamente una nuova analisi Nova Shield.

POST

Registra una conversione

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

Gli eventi sono lead, sale o refund. Un evento esterno duplicato restituisce HTTP 409 e non viene mai contato due volte.

Ambiti del token

links:read
elenca i link.
links:write
crea, aggiorna e disattiva link e registra conversioni.
analytics:read
legge le analisi dei link.
domains:read / domains:write
Domini personalizzati
webhooks:read / webhooks:write
Webhook firmati

Limiti delle richieste

I token consentono 120 richieste al minuto più la quota mensile del workspace. Analytics ha un ulteriore limite di 60 al minuto. HTTP 429 include Retry-After e RateLimit. I reindirizzamenti continuano a funzionare.

Idempotenza

Durante la creazione invia un Idempotency-Key da 8 a 128 caratteri stampabili. Vale 24 ore nel workspace. Un tentativo identico riproduce la risposta; dati diversi con la stessa chiave restituiscono HTTP 409.

HTTP

Errori

Gli errori usano un unico formato JSON. Stati comuni: 400 JSON non valido, 401 token non valido, 403 ambito o piano mancante, 404 non trovato, 409 conflitto, 413 corpo grande, 415 tipo errato, 422 validazione e 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

Verifica ogni webhook

Eventi: link.created, link.updated, link.disabled, link.clicked, conversion.created, shield.status_changed ed endpoint.test. La consegna automatica riprova fino a cinque volte.

I webhook di disponibilità usano shield.availability_changed con transizioni e diagnostica HTTP limitata, senza URL di destinazione.

Header di consegna

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

Verifica 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;
}

Usa il corpo grezzo, confronta le firme in tempo costante, rifiuta timestamp oltre cinque minuti e conserva X-4ulink-Delivery per tentativi idempotenti. L’endpoint deve usare HTTPS pubblico sulla porta 443.