EN
RESTful JSON API 2.0.1
rel. 2.0.1

Introduzione

Le API Qapla' v2 offrono una piattaforma avanzata per l'integrazione sia in lettura che in scrittura con sistemi di e-commerce proprietari o per quelli che non dispongono di un plugin o connettore specifico.

L'architettura si basa su uno stile RESTful che garantisce una gestione delle risorse intuitiva e conforme agli standard internazionali, semplificando l'integrazione e l'automazione dei processi.

API Key

Per utilizzare le API, è necessario disporre di una API Key privata, che viene assegnata ai canali abilitati.

È possibile trovare l'API Key nel Control Panel nella sezione "Impostazioni" > "Canali" > "Configura" > "Canale" > "API Key Privata".

L'API Key deve essere mantenuta riservata e protetta.
Ogni canale ha una o più API Key private, che definiscono i permessi e gli endpoint accessibili.

API Key

Autenticazione

L'autenticazione avviene tramite il flusso Bearer Token Authentication: scambi la tua API Key con un token JWT, che poi includi in ogni richiesta.

Bearer Token Authentication

Per ottenere un token di accesso, invia una richiesta POST all'endpoint di autenticazione con la tua API Key:

POST https://api.qapla.it/v2/auth/token

La richiesta deve contenere il seguente JSON nel body:

{"api_key":"API_KEY"}
api_key (string) L'API Key del canale Qapla'.
Richiesta cURL del token di accesso:
curl -X POST https://api.qapla.it/v2/auth/token \
        -H "Content-Type: application/json" \
        -d '{"api_key": "API_KEY"}'
Response Body 200

            
Descrizione
token (string) Il token JWT da includere come Bearer nell'header Authorization di tutte le richieste successive.
scopes (array) Elenco dei permessi concessi all'API Key corrente (es. parcels:create, sandbox:read).
token_type (string) Indica il tipo di token (sempre Bearer).
expires_in (int) La durata del token in secondi (86400 = 24 ore).
rate_limit (object) Parametri del Token Bucket configurati per questa API Key.
refill_rate (int) Token aggiunti al bucket ogni minuto.
bucket_size (int) Capacità massima del bucket (numero massimo di richieste in burst).
cache (bool) Indica se la risposta è stata servita dalla cache (true) o generata ex-novo (false).
Errori
400 Bad Request: il campo api_key è mancante o il formato non è valido.
401 Unauthorized: l'API Key non è valida o il canale è inattivo.
429 Too Many Requests: limite di richieste superato.
Utilizzo del token
Il token deve essere incluso nell'header Authorization di tutte le richieste, preceduto dalla stringa Bearer:
curl -X GET https://api.qapla.it/v2/endpoint \
         -H "Authorization: Bearer ACCESS_TOKEN" \
         -H "Content-Type: application/json"

Errori

Tutti gli errori restituiti dalle API Qapla' sono rappresentati tramite codici di stato HTTP standard.

Ogni codice indica il tipo di errore riscontrato durante l'elaborazione della richiesta, fornendo un'indicazione chiara e conforme agli standard su eventuali problemi di autenticazione, validazione o utilizzo non corretto degli endpoint.

Codici HTTP
400 Bad Request: La richiesta non è valida o mancano parametri obbligatori nel body della richiesta.
401 Unauthorized: L'API Key non è valida o non ha i permessi necessari per accedere all'endpoint richiesto.
403 Forbidden: Accesso negato. L'API Key non ha i permessi necessari o l'utente non è autorizzato.
404 Not Found: L'endpoint specificato non esiste o la risorsa richiesta non è stata trovata.
405 Method Not Allowed: Il metodo HTTP utilizzato (GET, POST, PUT, DELETE) non è supportato per questo endpoint.
406 Not Acceptable: Il server non è in grado di generare una risposta nella lingua o nel formato richiesto dal client.
409 Conflict: La richiesta non può essere completata a causa di un conflitto con lo stato attuale della risorsa.
423 Locked: La risorsa richiesta è bloccata e non può essere modificata o accessibile.
429 Too Many Requests: Il numero massimo di richieste è stato superato. Attendere prima di riprovare.
500 Internal Server Error: Errore interno del server durante l'elaborazione della richiesta.
503 Service Unavailable: Il servizio non è al momento disponibile. Riprova più tardi.
Body
Il body JSON dell'errore.

    
status Il tipo di errore.
code Il codice interno dell'errore.
message La descrizione dell'errore.
Header
X-Error-Message Il testo descrittivo dell'errore

Limiti di utilizzo

Il sistema di gestione delle richieste utilizza un algoritmo di Token Bucket per limitare il numero di chiamate API in un determinato intervallo di tempo. Il limite è per canale e vale per tutte le API Key del canale, con i seguenti parametri:

Capacità del bucket 300 Numero massimo di richieste assorbite in un picco, prima che scatti il throttling.
Token al minuto 150 Il bucket si ricarica di 150 token al minuto.
Costo in token 1 Ogni richiesta consuma un token, indipendentemente dal numero di elementi nel body.

I canali con volumi elevati possono ottenere un limite dedicato, più alto di quello standard: contattare il Customer Support. I valori assegnati alla propria API Key sono sempre leggibili nell'oggetto rate_limit restituito da POST /auth/token.

HTTP Response Status Codes

Se viene superato il limite di utilizzo, la risposta sarà:

429 Too Many Requests

La risposta riporta gli header X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Ritentare rispettando l'header Retry-After, con backoff esponenziale.

Abuso

L'abuso ripetuto dell'API (10 o più risposte 429 in 5 minuti) comporta la sospensione automatica dell'API Key per 1 ora (403 Forbidden). La revoca permanente è gestita manualmente dall'amministratore di sistema.

Postman Collection

Postman Una Postman Collection è disponibile.

Swagger UI

Swagger UI È disponibile uno Swagger UI interattivo per esplorare e testare gli endpoint dell'API.

Authentication

Il servizio di autenticazione permette di ottenere un token JWT a partire dalla tua API Key. Il token ha una validità di 24 ore e deve essere incluso come Bearer nell'header Authorization di ogni richiesta.

POSTAuth / Token

Scambia una API Key con un token JWT valido per 24 ore. Il token può essere memorizzato nella cache e riutilizzato fino alla scadenza.
POSThttps://api.qapla.it/v2/auth/token
Body

            

*Parametro obbligatorio

api_key*(string) L'API Key privata del canale Qapla'. Reperibile nel Control Panel in "Impostazioni" > "Canali" > "Configura".

Questo endpoint non richiede autenticazione (nessun header Authorization).

Body 200

            
token(string) Il token JWT da includere come Bearer nell'header Authorization: Bearer {token} di ogni richiesta successiva.
scopes(array) Elenco dei permessi concessi all'API Key. Ogni permesso corrisponde a un'azione specifica sulle risorse.
parcels:create, parcels:read, parcels:update, parcels:delete, sandbox:read, sandbox:write, orders:read, orders:write, labels:read, labels:write, jobs:read, shipments:create, shipments:read
token_type(string) Tipo di token (sempre Bearer).
expires_in(int) Durata del token in secondi. Valore fisso: 86400 (24 ore).
rate_limit(object) Parametri del Token Bucket per questa API Key.
refill_rate(int) Token aggiunti al bucket ogni minuto.
bucket_size(int) Capacità massima del bucket.
cache(bool) true se la risposta è stata servita dalla cache Redis (token già esistente), false se generato ex-novo.
Header di risposta
X-Auth-Cache(string) HIT se il token è stato servito dalla cache, MISS se generato ex-novo.
Errori
400 Bad Request: il campo api_key è mancante o il formato non è valido.
401 Unauthorized: l'API Key non è valida o il canale è inattivo.
429 Too Many Requests: limite di richieste superato.

Sandbox

Le API Sandbox sono endpoint di test che permettono di verificare il funzionamento dell'integrazione senza effetti collaterali su dati reali. Ogni entità sandbox espone tutti i metodi HTTP standard (CRUD) e include valori di ogni tipo (string, int, bool, float, datetime).

Un'entità Sandbox è identificata univocamente dal suo id numerico.

Scope richiesti: sandbox:read per GET, sandbox:write per POST/PUT/PATCH/DELETE.

GETSandbox

Restituisce la lista paginata delle entità Sandbox. Supporta filtri temporali tramite query parameter.
GEThttps://api.qapla.it/v2/sandbox
Query Parameters
page(int) Numero di pagina. Default: 1.
limit(int) Numero di risultati per pagina. Default: 20.
updatedAfter(string) Filtra le entità aggiornate dopo questa data (formato ISO 8601, es. 2024-01-15T00:00:00+01:00).
updatedBefore(string) Filtra le entità aggiornate prima di questa data (formato ISO 8601).
Header
Authorization(string) Bearer ACCESS_TOKEN
Body 200

            
items(array) Elenco delle entità sandbox nella pagina corrente.
total(int) Numero totale di entità.
page(int) Pagina corrente.
limit(int) Elementi per pagina.
pages(int) Numero totale di pagine.
Errori
Tutti gli errori restituiti dalle API Qapla' sono rappresentati tramite codici di stato HTTP standard.

GETSandbox / {id}

Recupera i dati di una singola entità Sandbox a partire dal suo identificativo numerico.
GEThttps://api.qapla.it/v2/sandbox/{id}
Parametri
id(int) L'identificativo numerico dell'entità Sandbox.
Body 200

            
id(int) L'identificativo univoco dell'entità.
string_value(string) Valore stringa.
int_value(int) Valore intero.
bool_value(bool) Valore booleano.
float_value(float) Valore decimale.
date_time_value(string) Valore datetime ISO 8601.
created_at(string) Data di creazione ISO 8601.
updated_at(string) Data di ultima modifica ISO 8601.
Errori
400 Bad Request: l'id deve essere un intero maggiore di zero.
404 Not Found: entità non trovata.

POSTSandbox

Crea una nuova entità Sandbox. Restituisce l'entità creata con HTTP 201 e l'header Location con l'URL della risorsa.
POSThttps://api.qapla.it/v2/sandbox
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

stringValue*(string) Valore stringa. Lunghezza minima: 3 caratteri.
intValue*(int) Valore intero.
boolValue*(bool) Valore booleano.
floatValue*(float) Valore decimale.
dateTimeValue(string) Valore datetime nel formato Y-m-d H:i:s (opzionale).
Body 201

            
Header
Location(string) URL della risorsa creata, es. /v2/sandbox/42.
Errori
422 Unprocessable Entity: errore di validazione sui campi della richiesta.

PUTSandbox / {id}

Sostituisce completamente un'entità Sandbox. Tutti i campi sono obbligatori.
PUThttps://api.qapla.it/v2/sandbox/{id}
Parametri
id(int) L'identificativo numerico dell'entità da sostituire.
Body

            

*Parametro obbligatorio

stringValue*(string) Valore stringa. Lunghezza minima: 3 caratteri.
intValue*(int) Valore intero.
boolValue*(bool) Valore booleano.
floatValue*(float) Valore decimale.
dateTimeValue(string) Valore datetime nel formato Y-m-d H:i:s (opzionale).
Body 200

            
Errori
404 Not Found: entità non trovata.
422 Unprocessable Entity: errore di validazione sui campi della richiesta.

PATCHSandbox / {id}

Aggiorna parzialmente un'entità Sandbox. Solo i campi inclusi nel body vengono modificati.
PATCHhttps://api.qapla.it/v2/sandbox/{id}
Parametri
id(int) L'identificativo numerico dell'entità da aggiornare.
Body
Tutti i campi sono opzionali. Solo i campi presenti nel body vengono aggiornati.

            
stringValue(string) Valore stringa. Lunghezza minima: 3 caratteri.
intValue(int) Valore intero.
boolValue(bool) Valore booleano.
floatValue(float) Valore decimale.
dateTimeValue(string) Valore datetime nel formato Y-m-d H:i:s.
Body 200

            
Errori
404 Not Found: entità non trovata.
422 Unprocessable Entity: errore di validazione sui campi.

DELETESandbox / {id}

Elimina un'entità Sandbox identificata dal suo id. Restituisce HTTP 204 senza body.
DELETEhttps://api.qapla.it/v2/sandbox/{id}
Parametri
id(int) L'identificativo numerico dell'entità da eliminare.
Response

HTTP 204 No Content — nessun body nella risposta.

Errori
404 Not Found: entità non trovata.

Shipments

Le API Shipments coprono l'intero ciclo di vita delle spedizioni: creazione sincrona in bulk (fino a 100 per richiesta), import massivo asincrono (fino a 5000, con job in background), ricerca paginata con filtri combinabili e dettaglio completo con storico di tracking e notifiche. Include inoltre lo svincolo giacenza, che chiede al corriere di agire su una spedizione ferma in deposito: riconsegnarla, riconsegnarla a un nuovo indirizzo, oppure renderla al mittente.

Una spedizione è identificata univocamente dal suo id numerico, restituito in fase di creazione, e appartiene sempre al canale autenticato.

Scope richiesti: shipments:read per la ricerca e il dettaglio, shipments:write per creazione, import e svincolo giacenza.

POSTCrea spedizioni

Crea fino a 100 spedizioni in una singola richiesta sincrona. Ogni spedizione viene validata e creata singolarmente: l'esito è riportato per singolo elemento nell'array items della risposta, nello stesso ordine della richiesta.

La risposta è 201 se tutte le spedizioni sono state create, 207 Multi-Status se una o più spedizioni sono state rifiutate (fallimento parziale o totale: controlla items[].errors). Le violazioni statiche del payload (campi obbligatori mancanti, formati non validi) respingono invece l'intera richiesta con 422 (RFC 7807 con violations).

Per volumi superiori a 100 spedizioni usa l'import asincrono POST /shipments/import.

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: shipments:write. Le spedizioni vengono create sul canale autenticato.

POSThttps://api.qapla.it/v2/shipments
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

shipments*(array) Elenco delle spedizioni da creare (minimo 1, massimo 100). Ogni spedizione contiene i seguenti campi:
trackingNumber*(string) Numero di tracking assegnato dal corriere (max 50 caratteri).
courier*(string) Corriere della spedizione: codice Qapla' (es. UPS), nome, oppure transcodifica specifica del canale. Le varianti corriere devono essere abilitate per il canale, altrimenti l'elemento viene rifiutato con COURIER_NOT_CONFIGURED.
shipDate*(string) Data di spedizione, formato YYYY-MM-DD.
orderReference(string) Riferimento ordine del merchant.
orderDate(string) Data dell'ordine, formato YYYY-MM-DD.
platformOrderId(string) Id dell'ordine sulla piattaforma di origine.
origin(string) Piattaforma di origine dell'ordine (es. magento, shopify, amazon). Se presente deve esistere nel registro delle piattaforme, altrimenti INVALID_ORIGIN.
language(string) Lingua delle notifiche (ISO 639-1, es. it, en). Default: it. Deve essere una lingua supportata, altrimenti INVALID_LANGUAGE.
tag(string) Tag libero della spedizione.
note(string) Nota libera della spedizione.
isRealTrackingNumber(bool) false quando il tracking number è un segnaposto non ancora assegnato dal corriere. Default: true.
isReturnable(bool) Indica se la spedizione può essere resa. Default: true.
commercialContactEmail(string) Email del contatto commerciale dell'ordine.
consignee(object) Destinatario della spedizione. Email e telefono servono solo ad abilitare le notifiche transazionali: una spedizione senza di essi viene comunque creata.
name(string) Nome completo.
street(string) Indirizzo.
city(string) Città.
postcode(string) CAP / codice postale.
state(string) Provincia / stato (es. MI).
country(string) Paese (ISO 3166-1 alpha-2). Default: IT.
email(string) Email del destinatario (abilita le notifiche email).
phone(string) Telefono del destinatario (abilita le notifiche SMS).
monetary(object) Informazioni economiche della spedizione.
totalValue(float) Valore totale dell'ordine.
codAmount(float) Importo del contrassegno. Un valore maggiore di zero marca la spedizione come contrassegno (COD).
shippingCost(float) Costo di spedizione pagato dal cliente.
currency(string) Valuta (ISO 4217). Attualmente è supportato solo EUR.
planning(object) Pianificazione della consegna.
deliveryDate(string) Data di consegna prevista (YYYY-MM-DD).
latestShipDate(string) Ultima data utile di spedizione (YYYY-MM-DD).
latestDeliveryDate(string) Ultima data utile di consegna (YYYY-MM-DD).
customAttributes(object) Attributi custom del merchant, ricercabili tramite GET /shipments.
custom1(string) Campo custom 1.
custom2(string) Campo custom 2.
custom3(string) Campo custom 3.
parcels(array) Colli della spedizione (massimo 100). Per ogni collo: fornisci boxCode (le dimensioni arrivano dal registro scatole dell'azienda; il peso resta obbligatorio), oppure il set completo peso + lunghezza + larghezza + altezza. In caso contrario l'elemento viene rifiutato con INVALID_BOX_CODE o MISSING_PARCEL_DIMENSIONS.
id(string) Identificativo del collo lato client, referenziato da orderItems[].parcelId.
trackingNumber(string) Tracking number specifico del collo, quando il corriere ne assegna uno per collo.
weight*(float) Peso in kg. Sempre obbligatorio.
length(float) Lunghezza in cm. Obbligatoria se boxCode non è fornito.
width(float) Larghezza in cm. Obbligatoria se boxCode non è fornito.
height(float) Altezza in cm. Obbligatoria se boxCode non è fornito.
boxCode(string) Codice di una scatola del registro scatole dell'azienda (fornisce le dimensioni).
content(string) Descrizione libera del contenuto del collo.
originCountry(string) Paese di origine della merce (ISO 3166-1 alpha-2).
orderItems(array) Righe d'ordine della spedizione (massimo 500).
sku*(string) SKU del prodotto.
name*(string) Nome del prodotto.
quantity(int) Quantità. Default: 1.
price(float) Prezzo unitario.
total(float) Totale riga (prezzo × quantità).
weight(float) Peso lordo in kg.
netWeight(float) Peso netto in kg.
unitOfMeasurement(string) Unità di misura (es. pcs).
url(string) URL della pagina prodotto.
imageUrl(string) URL dell'immagine prodotto.
isReturnable(bool) Indica se l'articolo può essere reso. Default: true.
customsCode(string) Codice doganale (HS).
originCountry(string) Paese di origine dell'articolo (ISO 3166-1 alpha-2).
parcelId(string) Id del collo che contiene l'articolo (riferimento a parcels[].id).
transparencyCodes(array) Codici Amazon Transparency (array di stringhe).
notes(string) Note libere della riga.
custom1…custom5(string) Campi custom di riga (da custom1 a custom5).
Body 201 — tutte le spedizioni create

            
summary(object) Riepilogo del batch.
totalRequested(int) Spedizioni presenti nella richiesta.
totalSuccess(int) Spedizioni create.
totalFailed(int) Spedizioni rifiutate.
items(array) Esiti per singola spedizione, nello stesso ordine della richiesta.
status(string) Esito dell'elemento: success o error.
trackingNumber(string) Tracking number dell'elemento della richiesta.
id(int) Id della spedizione creata. null in caso di errore.
trackingUrl(string) URL pubblico della tracking page della spedizione creata. null in caso di errore.
errors(array) Errori dell'elemento, presenti quando status è error.
code(string) Codice errore machine-readable (vedi tabella sotto).
message(string) Messaggio human-readable.
field(string) Campo a cui si riferisce l'errore, quando applicabile.
Body 207 — fallimento parziale o totale (Multi-Status)

            
Codici errore per elemento
INVALID_COURIER Il valore di courier non corrisponde ad alcun corriere attivo (né come codice, né come nome, né come transcodifica canale).
COURIER_NOT_CONFIGURED La variante corriere indicata esiste ma non è abilitata per il canale autenticato.
INVALID_LANGUAGE La lingua indicata in language non è supportata.
INVALID_ORIGIN La piattaforma indicata in origin non esiste nel registro delle piattaforme.
DUPLICATE_SHIPMENT Esiste già una spedizione con la stessa terna canale + corriere + trackingNumber. I duplicati vengono rilevati anche all'interno dello stesso batch.
INVALID_BOX_CODE Il boxCode indicato non esiste nel registro scatole dell'azienda (o il registro è vuoto).
MISSING_PARCEL_DIMENSIONS Un collo senza boxCode non ha il set completo peso + lunghezza + larghezza + altezza.
INTERNAL_ERROR Errore interno inatteso durante la creazione dell'elemento.
Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: contesto canale mancante nel token, oppure il token non possiede lo scope shipments:write.
422 Unprocessable Entity: violazioni statiche del payload (RFC 7807 con violations). L'intera richiesta viene respinta, nessuna spedizione viene creata.
429 Too Many Requests: limite di richieste superato.

POSTImporta spedizioni (asincrono)

Importa fino a 5000 spedizioni in una singola richiesta asincrona. La richiesta accoda un job in background e risponde subito 202 con le coordinate del job; l'esito per singola spedizione si ottiene interrogando il job.

Ogni spedizione ha lo stesso formato di POST /shipments e viene processata con le stesse regole di business. A differenza del sincrono, anche gli errori statici di validazione non bloccano il batch: l'elemento invalido fallisce da solo con codice VALIDATION_ERROR.

L'import è sicuro da ritentare: se il job viene rieseguito dopo un'interruzione, gli elementi già inseriti vengono segnalati come DUPLICATE_SHIPMENT senza doppi inserimenti.

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: shipments:write. Le spedizioni vengono create sul canale autenticato.

POSThttps://api.qapla.it/v2/shipments/import
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

shipments*(array) Elenco delle spedizioni da importare (minimo 1, massimo 5000). Ogni spedizione ha lo stesso formato documentato in POST /shipments.
webhookUrl(string) URL notificato al termine dell'import (opzionale). La notifica è best-effort: usa comunque il polling del job come fonte di verità.
Body 202 — job accettato

            
jobId(string) Identificativo del job asincrono.
status(string) Stato iniziale del job: processing.
statusUrl(string) URL relativo per verificare lo stato del job (/jobs/{jobId}).
totalShipments(int) Numero di spedizioni accodate.
Polling del job

Interroga GET /v2/jobs/{jobId} per seguire l'avanzamento (stati: pending, processing, completed, failed; scope richiesto: jobs:read). A job concluso, il campo result contiene il riepilogo, i successi in forma compatta e gli errori in forma dettagliata:


            
result.summary(object) Riepilogo del batch: totalRequested, totalSuccess, totalFailed.
result.successes(array) Spedizioni create, in forma compatta: index (posizione nell'array della richiesta), id, trackingNumber, trackingUrl (URL pubblico della tracking page).
result.errors(array) Spedizioni rifiutate, in forma dettagliata: index, trackingNumber e l'array errors[] con code, message, field. I codici sono gli stessi di POST /shipments, più VALIDATION_ERROR per gli elementi staticamente invalidi.

Lo stato failed è riservato al caso in cui tutte le spedizioni falliscono (o a un errore infrastrutturale); un fallimento parziale lascia il job completed con gli errori in result.errors.

Webhook

Se hai indicato webhookUrl, al termine del job Qapla' invia una POST best-effort con body {"jobId": "...", "status": "completed|failed", "result": {...}}, dove result ha la stessa struttura mostrata sopra.

Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: contesto canale mancante nel token, oppure il token non possiede lo scope shipments:write.
422 Unprocessable Entity: body malformato, array shipments vuoto o con più di 5000 elementi, webhookUrl non valido (RFC 7807 con violations).
429 Too Many Requests: limite di richieste superato.

GETCerca spedizioni

Restituisce la lista paginata delle spedizioni del canale autenticato. Tutti i filtri sono opzionali e si combinano in AND; senza filtri l'endpoint è un semplice listing paginato del canale.

Suggerimento per il polling
Per sincronizzare gli aggiornamenti di tracking usa il filtro updatedAfter: restituisce solo le spedizioni il cui stato è cambiato dopo quel momento, evitando richieste puntuali ripetute sulla singola spedizione.

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: shipments:read.

GEThttps://api.qapla.it/v2/shipments?updatedAfter={DATETIME}&status={STATUS}&page={PAGE}
Query Parameters
trackingNumber(string) Tracking number, match esatto.
orderReference(string) Riferimento ordine, match esatto.
custom1(string) Attributo custom 1, match esatto.
custom2(string) Attributo custom 2, match esatto.
custom3(string) Attributo custom 3, match esatto.
shipDateFrom(string) Data di spedizione da, inclusiva (YYYY-MM-DD).
shipDateTo(string) Data di spedizione a, inclusiva (YYYY-MM-DD).
status(string) Lista di stati di tracking separati da virgola (es. 3,4,99). Vedi la legenda degli stati qui sotto.
updatedAfter(string) Solo le spedizioni il cui stato di tracking è cambiato in quel momento o dopo (YYYY-MM-DD HH:MM:SS). Le spedizioni mai aggiornate sono escluse. Consigliato per il polling degli aggiornamenti.
page(int) Numero di pagina. Default: 1.
limit(int) Risultati per pagina. Default: 20, massimo: 100.
sortBy(string) Ordinamento: id_desc (default), id_asc, shipDate_desc, shipDate_asc.
Stati di tracking
0 WAITING_TO_COMPUTE — In attesa di elaborazione.
1 PENDING — In attesa del primo evento di tracking.
2 INFO_RECEIVED — Il corriere ha ricevuto i dati della spedizione.
3 IN_TRANSIT — In transito.
4 OUT_FOR_DELIVERY — In consegna.
5 FAILED_ATTEMPT — Tentativo di consegna fallito.
6 EXCEPTION — Eccezione (es. giacenza).
8 DELAY — In ritardo.
10 PICKUP_POINT — Consegnata al punto di ritiro.
20 DEPARTED — Partita.
50 PROCESSING — In lavorazione presso il corriere.
95 RETURNED — Resa al mittente.
99 DELIVERED — Consegnata.
Body 200

            
items(array) Elenco delle spedizioni della pagina corrente (proiezione riassuntiva; per colli, righe d'ordine, storico e notifiche usa GET /shipments/{id}).
id(int) Id della spedizione.
trackingNumber(string) Tracking number del corriere.
trackingUrl(string) URL pubblico della tracking page. null quando il token di tracking non è disponibile.
courier(string) Codice canonico del corriere.
courierName(string) Nome canonico del corriere.
status(int) Stato di tracking (vedi legenda nel tab REQUEST).
statusDescription(string) Descrizione dello stato, localizzata nella lingua della spedizione.
statusDetail(int) Id del dettaglio di stato (0 = nessuno).
statusDetailDescription(string) Descrizione del dettaglio di stato, localizzata.
statusDate(string) Data dell'ultimo evento di tracking riportata dal corriere.
statusUpdatedAt(string) Momento dell'ultimo cambio stato su Qapla'. È il campo su cui agisce il filtro updatedAfter.
statusPlace(string) Luogo dell'ultimo evento di tracking.
shipDate(string) Data di spedizione (YYYY-MM-DD).
orderReference(string) Riferimento ordine del merchant.
platformOrderId(string) Id dell'ordine sulla piattaforma di origine.
orderDate(string) Data dell'ordine (YYYY-MM-DD).
tag(string) Tag libero della spedizione.
note(string) Nota libera della spedizione.
origin(string) Piattaforma di origine dell'ordine.
isReturn(bool) Indica se la spedizione è un reso.
consignee(object) Destinatario: name, street, city, postcode, state, country, email, phone.
monetary(object) Informazioni economiche: totalValue, codAmount, shippingCost, currency.
customAttributes(object) Attributi custom del merchant: custom1, custom2, custom3.
total(int) Numero totale di spedizioni che soddisfano i filtri.
page(int) Pagina corrente.
limit(int) Spedizioni per pagina.
pages(int) Numero totale di pagine.
Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: contesto canale mancante nel token, oppure il token non possiede lo scope shipments:read.
422 Unprocessable Entity: parametri di query non validi (es. status con valori sconosciuti, updatedAfter in formato errato, limit > 100).
429 Too Many Requests: limite di richieste superato.

GETDettaglio spedizione

Restituisce il dettaglio completo di una spedizione: tutti i campi riassuntivi di GET /shipments più pianificazione, colli, righe d'ordine, storico di tracking e notifiche inviate.

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: shipments:read. La spedizione deve appartenere al canale autenticato: una spedizione di un altro canale restituisce 404, indistinguibile da una spedizione inesistente.

GEThttps://api.qapla.it/v2/shipments/{id}
Path
id*(int) Id numerico della spedizione (restituito in fase di creazione o da GET /shipments).
Body 200

            

I campi riassuntivi (id, trackingNumber, trackingUrl, courier, courierName, status, statusDescription, statusDetail, statusDetailDescription, statusDate, statusUpdatedAt, statusPlace, shipDate, orderReference, platformOrderId, orderDate, tag, note, origin, isReturn, consignee, monetary, customAttributes) sono documentati in GET /shipments. In aggiunta, il dettaglio include:

planning(object) Pianificazione della consegna: deliveryDate, latestShipDate, latestDeliveryDate.
parcels(array) Colli della spedizione, così come registrati in fase di creazione.
id(string) Identificativo del collo lato client.
trackingNumber(string) Tracking number specifico del collo.
weight(float) Peso in kg.
length(float) Lunghezza in cm.
width(float) Larghezza in cm.
height(float) Altezza in cm.
boxCode(string) Codice del registro scatole usato in fase di creazione.
content(string) Descrizione del contenuto del collo.
originCountry(string) Paese di origine della merce (ISO 3166-1 alpha-2).
orderItems(array) Righe d'ordine della spedizione: sku, name, quantity, price, total, weight, netWeight, unitOfMeasurement, url, imageUrl, isReturnable, customsCode, originCountry, parcelId, notes, custom1custom5.
history(array) Storico di tracking, dal più recente al più vecchio.
date(string) Data dell'evento (YYYY-MM-DD HH:MM:SS).
courierStatus(string) Stato grezzo comunicato dal corriere.
place(string) Luogo dell'evento.
status(string) Descrizione dello stato Qapla' mappato.
statusCode(string) Codice dello stato Qapla' mappato (es. IN_TRANSIT, DELIVERED).
statusDetail(string) Descrizione del dettaglio di stato, quando presente.
notifications(array) Notifiche inviate per la spedizione.
type(string) Tipo di notifica: email, sms o webhook.
result(string) Esito: OK o KO.
date(string) Data di invio (YYYY-MM-DD HH:MM:SS).
recipient(string) Destinatario (indirizzo email, numero di telefono o URL).
shipmentStatus(string) Stato della spedizione al momento della notifica.
error(string) Dettaglio dell'errore, quando l'esito è KO.
Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: contesto canale mancante nel token, oppure il token non possiede lo scope shipments:read.
404 Not Found: la spedizione non esiste, oppure non appartiene al canale autenticato.
429 Too Many Requests: limite di richieste superato.

POSTRichiedi uno svincolo giacenza

Chiede al corriere di agire su una spedizione attualmente ferma in deposito (giacenza): riconsegnarla, riconsegnarla a un nuovo indirizzo, oppure renderla al mittente.

La risposta viene sempre accettata in modo sincrono (status: "sent"); l'esito reale è indicato da courierOutcome. GLS e TNT rispondono in modo sincrono (ok/error); BRT è differito — la richiesta viene trasmessa in modo asincrono e il suo esito (pending) diventa visibile in seguito tramite gli eventi di tracking della spedizione.

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: shipments:write. La spedizione deve appartenere al canale autenticato ed essere attualmente ferma in deposito.

POSThttps://api.qapla.it/v2/shipments/{id}/stock-release
Path
id*(int) Id numerico della spedizione ferma in deposito.
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

action*(string) Azione canonica: redeliver, redeliver_new_address oppure return_to_sender.
notes(string) Nota libera per il corriere (opzionale).
redeliveryDate(string) Data di riconsegna richiesta, formato ISO (YYYY-MM-DD). Ammessa solo per redeliver e redeliver_new_address (con return_to_sender viene restituito un 422). GLS richiede una data di riconsegna: se omessa viene usato il primo giorno lavorativo successivo (festività italiane escluse). Ignorata dai corrieri che non la supportano.
address(object) Nuovo indirizzo di consegna. Obbligatorio se e solo se action è redeliver_new_address (in caso contrario viene restituito un 422: mancante quando richiesto, oppure presente quando non consentito).
name*(string) Nome del destinatario.
street*(string) Indirizzo.
city*(string) Città.
zip*(string) CAP.
province*(string) Sigla provincia (es. MI).
phone(string) Telefono di contatto (opzionale).
Body 200

            
status(string) Sempre sent — la richiesta è stata accettata e trasmessa al corriere.
courierOutcome(string) Esito reale del corriere: ok o error per i corrieri sincroni (GLS, TNT), pending per i corrieri differiti (BRT).
message(string) Messaggio di esito del corriere, quando disponibile. null altrimenti.
releaseId(int) Id interno della richiesta di svincolo memorizzata.
Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: contesto canale mancante nel token, oppure il token non possiede lo scope shipments:write.
404 Not Found: la spedizione non esiste, oppure non appartiene al canale autenticato.
409 Conflict: la spedizione non è attualmente ferma in deposito (nessuna giacenza da svincolare).
422 Unprocessable Entity: errore di validazione (action non valida, address mancante/non atteso, redeliveryDate non valida o non ammessa), oppure il corriere ha rifiutato la richiesta.
429 Too Many Requests: limite di richieste superato.

Couriers

Le API Couriers forniscono benchmark di consegna sull'intera rete. Dato un CAP di destinazione e un elenco di corrieri, è possibile confrontarne i tempi di consegna e scegliere il corriere più veloce per una specifica tratta, oppure valutarne l'efficienza complessiva su quella tratta.

Il benchmark è anonimo e aggregato su tutti i merchant (nessun dato personale); la macro-area di origine viene dedotta lato server dall'azienda autenticata.

Scope richiesti: delivery-times:read per il confronto dei tempi di consegna, efficiency-index:read per l'indice di efficienza.

POSTConfronta i tempi di consegna dei corrieri

Dato un CAP italiano di destinazione e un elenco di corrieri, restituisce i corrieri ordinati dal più veloce in base al tempo medio di consegna (lead time), così da poter scegliere il corriere più rapido per quella tratta.

L'origine è risolta fino al CAP della sede aziendale, dedotto lato server dall'azienda autenticata, e può essere sovrascritta tramite il parametro originCap. I dati sono un benchmark anonimo aggregato sull'intera rete di merchant (nessun dato personale). Le metriche sono espresse in giorni di calendario: lead = spedito→consegnato (metrica primaria, usata per l'ordinamento), transit = partito→consegnato (solo corriere, storico a partire da ~2026).

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: delivery-times:read.

POSThttps://api.qapla.it/v2/couriers/delivery-times
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

destCap*(string) CAP italiano di destinazione di 5 cifre (es. 20100).
couriers(array) Elenco dei codici corriere da confrontare (massimo 50). Opzionale: se omesso, vengono usati i corrieri del canale autenticato che hanno la generazione etichette abilitata.
weightKg(float) Peso del collo in kg (deve essere > 0). Se valorizzato, seleziona la fascia di peso corrispondente per una stima specifica per peso. Se omesso, viene restituita una stima indipendente dal peso.
originCap(string) CAP di origine opzionale (5 cifre). Sovrascrive il CAP della sede dell'azienda autenticata usato per le grane origine-CAP più fini. Se omesso, viene usato il CAP della sede aziendale.
detail(string) Livello di dettaglio della risposta: summary (predefinito) restituisce il corriere migliore più una classifica snella; full restituisce la classifica completa con tutti i percentili, la granularità, weightBand e i corrieri con dati insufficienti.
Body 200

            
destCap(string) Il CAP di destinazione richiesto.
originArea(string) Macro-area di origine dedotta dall'azienda autenticata: NORD, CENTRO o SUD. null se non determinabile.
originCap(string) CAP di origine usato per le grane origin_cap_dest* più fini (l'originCap della richiesta, altrimenti il CAP della sede aziendale). null quando il CAP della sede non è un CAP italiano valido.
requestedWeightBand(string) La fascia di peso a cui corrisponde weightKg (es. 2-5). null se weightKg è stato omesso.
best(object) Il corriere più veloce. null quando nessun corriere ha dati sufficienti.
courierCode(string) Il codice corriere, così come fornito nella richiesta.
leadMedian(int) Mediana del lead time spedito→consegnato, giorni di calendario.
leadMean(float) Media del lead time spedito→consegnato, giorni di calendario, arrotondata a 1 decimale.
transitMedian(int) Mediana del transit time partito→consegnato, solo corriere, giorni di calendario.
transitMean(float) Media del transit time partito→consegnato, solo corriere, giorni di calendario, arrotondata a 1 decimale.
sampleSize(int) Numero di consegne nella cella di benchmark (ultimi 12 mesi).
ranking(array) Corrieri con dati disponibili, ordinati dal più veloce; i corrieri con dati insufficienti vengono omessi (richiedi detail: "full" per vederli).
position(int) Posizione in classifica a partire da 1 (più veloce = 1).
courierCode(string) Il codice corriere, così come fornito nella richiesta.
leadMedian(int) Mediana del lead time (spedito→consegnato) in giorni di calendario. Metrica primaria di ordinamento.
transitMedian(int) Mediana del transit time (partito→consegnato, solo corriere) in giorni di calendario.
sampleSize(int) Numero di consegne nella cella di benchmark (ultimi 12 mesi).
Dettaglio completo (detail: "full")

Quando la richiesta imposta detail: "full", la risposta restituisce la classifica completa. Ogni riga aggiunge status (ok | insufficient_data), level (la granularità del benchmark, dal più fine al più grossolano: origin_cap_dest_weight | origin_cap_dest | area_cap_weight | cap_weight | area_cap | cap), weightBand, leadMean, transitMean (medie in giorni di calendario, float a 1 decimale), leadP90, transitP90 e transitSampleSize, e i corrieri senza dati sono inclusi in fondo con status: insufficient_data e metriche null. Il ranking è ordinato per lead time: mediana, poi media, poi p90. Nella forma full non è presente il campo best.

Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: il token non possiede lo scope delivery-times:read.
422 Unprocessable Entity: errore di validazione (destCap/originCap non valido), oppure nessun corriere da confrontare (non fornito nella richiesta e il canale non ha corrieri con generazione etichette abilitata).
429 Too Many Requests: limite di richieste superato.

POSTValuta l'efficienza dei corrieri

Dato un CAP italiano di destinazione e un elenco di corrieri, restituisce per ogni corriere un indice di efficienza 0–100 su quella tratta, con voto e posizione (rank, dal migliore), e tre sotto-voti, così da poter scegliere il corriere più performante — non solo il più veloce.

L'indice di efficienza combina tre sotto-voti con i pesi di rete fissi 40/20/40: scoreSpeed (dalla mediana di velocità), scoreConsistency (dallo scarto tra p90 e mediana) e scoreReliability (dai tassi di fallita/giacenza/eccezione della tratta). L'origine è risolta fino al CAP della sede aziendale, dedotto lato server dall'azienda autenticata, e può essere sovrascritta tramite il parametro originCap. I dati sono un benchmark anonimo aggregato sull'intera rete di merchant (nessun dato personale). Le metriche di velocità sono espresse in giorni di calendario (transit se disponibile, altrimenti lead).

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: efficiency-index:read.

POSThttps://api.qapla.it/v2/couriers/efficiency-index
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

destCap*(string) CAP italiano di destinazione di 5 cifre (es. 20100).
couriers(array) Elenco dei codici corriere da valutare (massimo 50). Opzionale: se omesso, vengono usati i corrieri del canale autenticato che hanno la generazione etichette abilitata.
weightKg(float) Peso del collo in kg (deve essere > 0). Se valorizzato, seleziona la fascia di peso corrispondente per un punteggio specifico per peso. Se omesso, viene restituito un punteggio indipendente dal peso.
originCap(string) CAP di origine opzionale (5 cifre). Sovrascrive il CAP della sede dell'azienda autenticata usato per le grane origine-CAP più fini. Se omesso, viene usato il CAP della sede aziendale.
Body 200

            
destCap(string) Il CAP di destinazione richiesto.
originArea(string) Macro-area di origine dedotta dall'azienda autenticata: NORD, CENTRO o SUD. null se non determinabile.
originCap(string) CAP di origine usato per le grane origin_cap_dest* più fini (l'originCap della richiesta, altrimenti il CAP della sede aziendale). null quando il CAP della sede non è un CAP italiano valido.
requestedWeightBand(string) La fascia di peso a cui corrisponde weightKg (es. 2-5). null se weightKg è stato omesso.
ranking(array) Corrieri ordinati dal migliore in base a efficiencyIndex. I corrieri la cui cella di tratta è soppressa (meno di 20 consegne) o senza una velocità utilizzabile vengono inseriti in fondo con status: "insufficient_data", rank null e metriche null.
rank(int) Posizione in base all'indice di efficienza a partire da 1 (migliore = 1); i pari merito condividono la posizione. null per i corrieri con dati insufficienti.
courierCode(string) Il codice corriere, così come fornito nella richiesta.
status(string) ok quando la tratta ha un benchmark utilizzabile, insufficient_data altrimenti.
efficiencyIndex(float) Indice di efficienza complessivo 0–100 (più alto è migliore), arrotondato a 1 decimale. 0.40·scoreSpeed + 0.20·scoreConsistency + 0.40·scoreReliability.
scoreSpeed(float) Sotto-voto di velocità 0–100, dalla mediana di velocità, arrotondato a 1 decimale.
scoreConsistency(float) Sotto-voto di costanza 0–100, dallo scarto tra il p90 e la mediana, arrotondato a 1 decimale.
scoreReliability(float) Sotto-voto di affidabilità 0–100, dai tassi di fallita/giacenza/eccezione della tratta, arrotondato a 1 decimale.
level(string) Granularità del benchmark usata (la più specifica disponibile): origin_cap_dest_weight | origin_cap_dest | area_cap_weight | cap_weight | area_cap | cap.
sampleSize(int) Numero di consegne nella cella di benchmark.
speedMedian(int) Mediana di velocità in giorni di calendario (mediana transit se disponibile, altrimenti mediana lead); base di scoreSpeed.
speedP90(int) P90 di velocità in giorni di calendario (p90 transit se disponibile, altrimenti p90 lead); base di scoreConsistency.
failedRate(float) Tasso di consegne fallite della cella di tratta (frazione 0–1).
stockRate(float) Tasso di giacenza della cella di tratta (frazione 0–1).
exceptionRate(float) Tasso di eccezioni della cella di tratta (frazione 0–1).
Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: il token non possiede lo scope efficiency-index:read.
422 Unprocessable Entity: errore di validazione (destCap/originCap non valido), oppure nessun corriere da valutare (non fornito nella richiesta e il canale non ha corrieri con generazione etichette abilitata).
429 Too Many Requests: limite di richieste superato.

Addresses

Le API Addresses verificano che un indirizzo postale esista e sia scrivibile su un'etichetta, restituendolo normalizzato con un punteggio di affidabilità. Servono a intercettare gli indirizzi sbagliati prima di creare la spedizione, quando correggerli costa ancora poco.

Dietro lo stesso contratto ci sono due provider, selezionabili con il parametro provider: geocode (predefinito) copre tutto il mondo ed è l'unico a restituire le coordinate; gls interroga lo stradario di GLS Italia, copre i soli indirizzi italiani e richiede GLS configurato sul canale, ma riporta ZTL, località disagiata, sede e zona di competenza, e propone gli indirizzi alternativi quando quello inviato non è conforme.

Ogni richiesta accettata viene conteggiata, con qualsiasi provider e qualunque sia l'esito: un indirizzo non trovato non è un errore, è un 200 con match.status uguale a NONE.

Scope richiesto: addresses:check. La funzionalità deve inoltre essere attiva sul contratto e abilitata sul canale.

POSTVerifica un indirizzo

Verifica che un indirizzo postale esista e sia scrivibile su un'etichetta, restituendolo normalizzato con un punteggio di affidabilità. Da usare prima di creare la spedizione, per intercettare gli indirizzi sbagliati quando correggerli costa ancora poco.

Dietro lo stesso contratto ci sono due provider, selezionabili con il parametro provider. geocode (predefinito) interroga il servizio di geocoding: copre tutto il mondo ed è l'unico che restituisce le coordinate. gls interroga lo stradario di GLS Italia: copre i soli indirizzi italiani e richiede che GLS sia configurato sul canale, ma in cambio riporta ZTL, località disagiata, sede e zona di competenza, e quando l'indirizzo non è conforme propone gli indirizzi che accetterebbe.

Un indirizzo che non trova corrispondenza non è un errore: la risposta è 200 con match.status uguale a NONE. La verifica è stata eseguita, il risultato è che quell'indirizzo non esiste.

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: addresses:check.
Ogni richiesta accettata viene conteggiata, con qualsiasi provider e qualunque sia l'esito — anche quando l'indirizzo non viene trovato. Non vengono conteggiate le richieste rifiutate prima della verifica (403 e 422).

POSThttps://api.qapla.it/v2/addresses/check
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

address*(object) L'indirizzo da verificare.
street*(string) Indirizzo con il numero civico (es. Via Roma 1). Massimo 255 caratteri.
city*(string) Città. Massimo 255 caratteri.
postcode(string) CAP. Massimo 20 caratteri.
state(string) Sigla della provincia (es. MI). Massimo 50 caratteri.
country(string) Paese in formato ISO 3166-1 alpha-2 (2 caratteri). Se omesso vale IT.
provider(string) Provider da interrogare: geocode (predefinito) oppure gls. gls accetta solo indirizzi con country uguale a IT e richiede GLS configurato sul canale.
Body 200 — provider geocode

            
provider(string) Il provider che ha risposto: geocode o gls.
match(object) Quanto l'indirizzo restituito corrisponde a quello inviato.
status(string) FULL con confidence maggiore o uguale a 90, WARNING da 80 in su, NONE sotto 80 o quando non c'è stata alcuna corrispondenza.
confidence(float) Punteggio 0–100, confrontabile tra i due provider: vale 100 quando il provider dichiara una corrispondenza esatta, altrimenti misura quanto l'indirizzo restituito si discosta da quello inviato. null quando non c'è stata corrispondenza.
partial(bool) true quando il provider ha trovato solo una corrispondenza parziale.
formatted(string) L'indirizzo normalizzato su una riga sola. null quando non c'è stata corrispondenza.
components(object) L'indirizzo normalizzato, pezzo per pezzo: street, city, postcode, state, region, country. null quando non c'è stata corrispondenza. region è valorizzato solo dai provider che conoscono le regioni amministrative.
coordinates(object) Coordinate geografiche (latitude, longitude) dell'indirizzo trovato. Valorizzato solo dal provider geocode: lo stradario GLS non geocodifica.
candidates(array) Indirizzi alternativi proposti dal provider, con gli stessi campi di components. Valorizzato solo dal provider gls, quando l'indirizzo inviato non è conforme allo stradario. Array vuoto negli altri casi.
delivery(object) Vincoli di consegna che il corriere conosce per quell'indirizzo. Valorizzato solo dal provider gls, null altrimenti.
restrictedTrafficZone(bool) L'indirizzo si trova in una ZTL.
difficultArea(bool) L'indirizzo è in località disagiata: di norma comporta un supplemento. Una ZTL è sempre anche località disagiata.
branch(string) Sede del corriere che serve l'indirizzo.
zone(string) Zona di consegna del corriere.
Body 200 — provider gls, indirizzo conforme

Nessuna coordinata, ma il blocco delivery è valorizzato: qui l'indirizzo è in ZTL, quindi anche difficultArea è true.


            
Body 200 — provider gls, indirizzo non conforme

L'indirizzo non è nello stradario GLS: components è null e in candidates ci sono gli indirizzi che GLS accetterebbe.


            
Errori
401 Unauthorized: token mancante o non valido.
403 Forbidden: il token non possiede lo scope addresses:check, la verifica indirizzi non è attiva sul tuo contratto, oppure non è abilitata sul canale.
422 Unprocessable Entity: errore di validazione, oppure il provider richiesto non può servire la richiesta (gls con un indirizzo non italiano, o su un canale senza GLS configurato).
429 Too Many Requests: limite di richieste superato.
502 Bad Gateway: il provider di verifica non è raggiungibile o ha risposto in modo illeggibile.

Parcels

Le API Parcels permettono di caricare preventivamente i colli di un ordine prima che venga creata la spedizione (etichetta). I colli caricati vengono poi "ereditati" automaticamente dall'ordine o dalla spedizione.

Un collo è identificato univocamente da un hash e appartiene a un ordine tramite la coppia orderReference + orderOrigin.

Scope richiesti: parcels:create, parcels:read, parcels:update, parcels:delete.

POSTParcels

Crea uno o più colli per un ordine. La risposta è sincrona (≤10 colli, HTTP 201) o asincrona (>10 colli, HTTP 202 con jobId).

NB
L'autenticazione avviene tramite il Bearer Token ottenuto con il servizio di autenticazione. Scope richiesto: parcels:create.

POSThttps://api.qapla.it/v2/parcels
Body
Il body della richiesta deve essere un JSON contenente i seguenti parametri:

            

*Parametro obbligatorio

order*(object) L'ordine a cui appartengono i colli.
reference*(string) Il riferimento univoco dell'ordine.
origin*(string) L'origine dell'ordine (es. shopify, amazon, woocommerce).
parcels*(array) Elenco dei colli (minimo 1, massimo 100).
originCountryIso*(string) Codice ISO 3166-1 alpha-2 del paese di origine (es. IT, ES).
weightKg*(float) Peso in kg, max 2 decimali. Massimo 99 kg.
lengthCm(float) Lunghezza in cm, max 2 decimali.
widthCm(float) Larghezza in cm, max 2 decimali.
heightCm(float) Altezza in cm, max 2 decimali.
contentsDescription(string) Descrizione del contenuto del collo.
clientInternalCode(string) Codice interno del cliente.
shippingNotes(string) Note da stampare sull'etichetta.
webhookUrl(string) URL di callback per notifiche asincrone (opzionale).
Header
x-label-format(string) PDF (default) oppure ZPL per ottenere l'etichetta nel formato desiderato.
Body 201 — Risposta sincrona (≤10 colli)

            
parcelHash(string) Hash univoco del collo creato. Utilizzato per identificare il collo nelle chiamate GET, PATCH e DELETE.
parcelNumber(int) Numero progressivo del collo.
label L'etichetta nel formato richiesto.
format(string) Formato dell'etichetta (PDF o ZPL).
label(string) Contenuto dell'etichetta in Base64 (PDF) o testo ZPL.
totalParcelCount(int) Numero totale di colli dell'ordine.
Body 202 — Risposta asincrona (>10 colli)

            
jobId(string) Identificativo del job asincrono. Usa GET /v2/jobs/{jobId} per monitorare lo stato.
status(string) Stato del job: pending, processing, completed, failed.
statusUrl(string) URL per verificare lo stato del job.
hashes(array) Hash pre-assegnati ai colli.
totalParcels(int) Numero totale di colli da processare.
Errori
422 Unprocessable Entity: errore di validazione (es. array parcels vuoto o più di 100 colli).
429 Too Many Requests: limite di richieste superato.

GETParcels

Restituisce la lista paginata dei colli di un ordine, identificato dalla coppia orderReference + orderOrigin passata come query parameter. Scope richiesto: parcels:read.
GEThttps://api.qapla.it/v2/parcels?orderReference={REFERENCE}&orderOrigin={ORIGIN}
Query Parameters
orderReference*(string) Il riferimento dell'ordine.
orderOrigin*(string) L'origine dell'ordine (es. shopify, amazon).
page(int) Numero di pagina. Default: 1.
limit(int) Risultati per pagina. Default: 20.

*Parametro obbligatorio

Body 200

            
items(array) Elenco dei colli dell'ordine.
total(int) Numero totale di colli.
page(int) Pagina corrente.
limit(int) Colli per pagina.
pages(int) Numero totale di pagine.
Errori
Tutti gli errori restituiti dalle API Qapla' sono rappresentati tramite codici di stato HTTP standard.

GETParcels / {hash}

Recupera i dati di un singolo collo a partire dal suo hash identificativo. Scope richiesto: parcels:read.
GEThttps://api.qapla.it/v2/parcels/{PARCEL-HASH}
Parametri
hash(string) L'hash identificativo del collo, ottenuto al momento della creazione.
Body 200

            
parcelHash(string) L'hash univoco del collo.
parcelNumber(int) Il numero progressivo del collo nell'ordine.
label L'etichetta associata al collo (format + contenuto in Base64 o ZPL).
originCountryIso(string) Codice ISO del paese di origine.
clientInternalCode(string) Codice interno del cliente.
weightKg(float) Peso in kg.
lengthCm(float) Lunghezza in cm.
widthCm(float) Larghezza in cm.
heightCm(float) Altezza in cm.
contentsDescription(string) Descrizione del contenuto.
shippingNotes(string) Note sull'etichetta.
createdAt(string) Data di creazione ISO 8601.
updatedAt(string) Data di ultima modifica ISO 8601.
Errori
404 Not Found: collo non trovato.

PATCHParcels / {hash}

Aggiorna parzialmente un collo. Solo i campi inclusi nel body vengono modificati. Scope richiesto: parcels:update.
PATCHhttps://api.qapla.it/v2/parcels/{PARCEL-HASH}
Parametri
hash(string) L'hash identificativo del collo da aggiornare.
Body
Tutti i campi sono opzionali. Solo i campi presenti nel body vengono aggiornati.

            
weightKg(float) Peso in kg, max 2 decimali.
lengthCm(float) Lunghezza in cm.
widthCm(float) Larghezza in cm.
heightCm(float) Altezza in cm.
originCountryIso(string) Codice ISO del paese di origine.
contentsDescription(string) Descrizione del contenuto.
clientInternalCode(string) Codice interno del cliente.
shippingNotes(string) Note sull'etichetta.
Body 200

            
Errori
404 Not Found: collo non trovato.
422 Unprocessable Entity: errore di validazione sui campi.

DELETEParcels / {hash}

Elimina un singolo collo identificato dal suo hash. Restituisce HTTP 204 senza body. Scope richiesto: parcels:delete.
DELETEhttps://api.qapla.it/v2/parcels/{PARCEL-HASH}
Parametri
hash(string) L'hash identificativo del collo da eliminare.
Response

HTTP 204 No Content — nessun body nella risposta.

Errori
404 Not Found: collo non trovato.

DELETEParcels (bulk)

Elimina tutti i colli di un ordine, identificato dalla coppia orderReference + orderOrigin passata come query parameter. Restituisce HTTP 204 senza body. Scope richiesto: parcels:delete.
DELETEhttps://api.qapla.it/v2/parcels?orderReference={REFERENCE}&orderOrigin={ORIGIN}
Query Parameters
orderReference*(string) Il riferimento dell'ordine.
orderOrigin*(string) L'origine dell'ordine.

*Parametro obbligatorio

Response

HTTP 204 No Content — nessun body nella risposta.

Errori
404 Not Found: nessun collo trovato per l'ordine specificato.