Sviluppatori
API CarClean
Invii la foto di un'auto, ricevi lo scatto da studio. Una sola chiamata HTTP, la stessa pipeline della dashboard: ritaglio, sfondo studio, luci e logo sulla targa.
1
Prendi una chiave
Le chiavi si creano dalla dashboard in App → API. Il token in chiaro viene mostrato una sola volta: a database resta solo il suo hash. Se lo perdi, revoca la chiave e creane un'altra.
Ogni chiave porta gli scope che le assegni: images:write per creare elaborazioni, jobs:read per leggere job e risultati, account:read per crediti e piano. Le chiavi sono segreti server-side: non metterle in app mobile o codice frontend.
Authorization: Bearer cc_live_9xK3aQ7f...
# oppure
X-API-Key: cc_live_9xK3aQ7f...2
La prima chiamata
Il modo più rapido per vedere il risultato: modalità sincrona, risposta binaria, file salvato su disco.
curl -X POST https://api.carclean.it/v1/images/enhance \
-H "Authorization: Bearer $CARCLEAN_API_KEY" \
-F "[email protected]" \
-F "mode=sync" \
-F "response_format=binary" \
--output risultato.jpgLa foto può arrivare come file multipart, come image_base64 o come image_url da scaricare. Formati accettati: JPEG, PNG e WebP, fino a 15 MB. Passa plate_text per il testo in targa, oppure un logo già disegnato. background accetta uno sfondo del piano. Start: bianco, grigio, cemento, grafite, nero, caldo, vetrina, asfalto, tramonto, notte. Dealer aggiunge marmo, legno, loft, corte, lago. Flotta aggiunge neve, tetto, hangar, pioggia, alba, costa. Se non passi shot, la foto viene riconosciuta da sola: gli esterni vanno nello sfondo scelto con la targa, gli interni tengono l'abitacolo. Lo sfondo si adatta solo se si vede fuori dall'auto. Il modello di generazione è fisso.
3
Sincrono o asincrono
Un'elaborazione richiede in genere da 30 secondi a qualche minuto. Hai due modi per gestire l'attesa.
Asincrono (default): la risposta arriva subito con 202 e il job in stato queued. Poi scegli come seguirlo: webhook, stream SSE o polling su GET /v1/jobs/{id}. È la modalità da usare in produzione, perché non tiene occupato un worker del tuo server.
Sincrono (mode=sync): la richiesta resta aperta fino a timeout secondi e restituisce il risultato. Comodo per script e prove manuali; ricordati di allineare i timeout di proxy e client.
curl -X POST https://api.carclean.it/v1/images/enhance \
-H "Authorization: Bearer $CARCLEAN_API_KEY" \
-F "[email protected]" \
-F "webhook_url=https://gestionale.esempio.it/hooks/carclean" \
-F 'metadata={"annuncio":"4471"}'Il campo metadata torna invariato nel job e nel webhook: è il posto giusto per il tuo numero di annuncio o ID veicolo, così non devi tenere una tabella di corrispondenza.
4
Il risultato
A job concluso, il campo resultcontiene tre immagini: lo scatto finale, l'affiancamento prima/dopo e la foto originale normalizzata.
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"object": "image_job",
"status": "done",
"progress": 100,
"metadata": { "annuncio": "4471" },
"result": {
"image_url": "https://…/output.jpg?X-Amz-Signature=…",
"before_after_url": "https://…/before-after.jpg?X-Amz-Signature=…",
"download_url": "https://api.carclean.it/v1/jobs/7c9e6679-…/image",
"expires_at": "2026-09-16T11:03:04.117Z"
}
}Gli URL firmati scadono dopo un'ora: vanno bene per scaricare subito il file. Se invece salvi il riferimento a lungo termine, usa download_url, che è autenticato e non scade.
5
Webhook firmati
Passando webhook_url ricevi una POST a job concluso, con evento job.done o job.failed. Ogni consegna porta l'header X-CarClean-Signature, un HMAC-SHA256 di "<timestamp>.<corpo grezzo>" calcolato con il segreto mostrato accanto alla chiave.
const atteso = createHmac("sha256", secret)
.update(`${timestamp}.${corpoGrezzo}`)
.digest("hex");Calcola la firma sul corpo grezzo, prima di qualsiasi parsing JSON. Rispondi con un 2xx entro 10 secondi: in caso di errore riproviamo fino a 3 volte con attesa crescente. Usa data.id per deduplicare.
Tutti gli endpoint
| Metodo | Percorso | Descrizione |
|---|---|---|
| POST | /v1/images/enhance | Invia una foto e crea l'elaborazione |
| GET | /v1/jobs | Elenca i job, paginati a cursore |
| GET | /v1/jobs/{id} | Stato e risultato di un job |
| GET | /v1/jobs/{id}/image | Byte dell'immagine (output, prima/dopo, originale) |
| GET | /v1/jobs/{id}/events | Avanzamento in tempo reale via SSE |
| GET | /v1/models | Riservato all'operatore della piattaforma |
| GET | /v1/account | Crediti e piano |
| GET | /v1/meta | Limiti e capacità correnti, senza autenticazione |
| GET | /v1/health | Health check, senza autenticazione |
La specifica OpenAPI descrive anche le rotte interne della dashboard e si importa in Postman, Insomnia o in un generatore di client.
Errori e limiti
Gli errori hanno sempre la stessa forma, con un code stabile su cui fare i controlli e un message in italiano per le persone.
{
"error": {
"code": "insufficient_scope",
"message": "La chiave non ha gli scope necessari: images:write"
}
}| Codice | HTTP | Cosa fare |
|---|---|---|
invalid_request | 400 | Correggi i parametri; è anche il caso dei crediti esauriti |
invalid_api_key | 401 | Chiave revocata o scaduta: rigenerala |
insufficient_scope | 403 | Crea una chiave con gli scope giusti |
job_not_ready | 409 | Elaborazione non finita: riprova più tardi |
payload_too_large | 413 | Ridimensiona l'immagine |
rate_limit_exceeded | 429 | Attendi i secondi indicati in Retry-After |
upstream_error | 502 | Ritentabile con backoff |
Il limite predefinito è di 60 richieste al minuto per chiave; ogni risposta riporta gli header X-RateLimit-*. Ogni elaborazione avviata consuma un credito, come dalla dashboard; le chiamate in lettura non ne consumano.
Pronto a integrare?
Crea l'account e attiva un piano per generare foto dall'API.

