Lettura
Consente gli endpoint GET. Scegli questo permesso se l’integrazione deve solo mostrare o esportare i dati dell’account.
Collega un’integrazione server ai dati già sincronizzati con un account Lunidex. Crea una chiave e invia una prima richiesta, poi esplora carte, prodotti sigillati, paginazione e scritture sicure.
Non inserire mai una chiave API nel codice del browser, in un’app mobile, in un repository pubblico, in un URL, in uno screenshot o in un log condiviso. Conservala in un gestore di segreti lato server e inviala solo nell’intestazione Authorization.
L’integrazione richiede una chiave, un segreto conservato sul server e una richiesta HTTPS all’URL di base dell’API.
Apri la scheda delle chiavi API nella dashboard Lunidex. Assegna un nome e scegli sola lettura oppure lettura e scrittura. Il segreto completo viene mostrato una sola volta: copialo prima di chiudere il messaggio.
Salva la chiave come LUNIDEX_API_KEY nel gestore di segreti del tuo provider. Non inserirla nel repository e non inviarla al browser.
Chiama GET /me dal tuo server. Gli endpoint privati richiedono l’intestazione Authorization: Bearer seguita dalla chiave.
curl --fail-with-body \
-H "Authorization: Bearer $LUNIDEX_API_KEY" \
https://lunidex.app/api/v1/meconst API_BASE_URL = "https://lunidex.app/api/v1";
const apiKey = process.env.LUNIDEX_API_KEY;
if (!apiKey) throw new Error("Missing LUNIDEX_API_KEY");
const response = await fetch(API_BASE_URL + "/me", {
headers: { Authorization: "Bearer " + apiKey },
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error?.code ?? "REQUEST_FAILED");
}
console.log(result.data);Invia la chiave nell’intestazione HTTP Authorization per ogni richiesta privata /api/v1. L’API restituisce JSON nell’involucro data; le risposte private usano Cache-Control: private, no-store.
Consente gli endpoint GET. Scegli questo permesso se l’integrazione deve solo mostrare o esportare i dati dell’account.
Consente sia gli endpoint GET sia quelli di scrittura. Usalo solo per un’integrazione server affidabile che deve modificare la raccolta o il registro dei prodotti sigillati.
L’API vede solo i dati sincronizzati con l’account Lunidex in Neon. I dati presenti soltanto su un dispositivo non sono disponibili. L’identità dell’account non include l’indirizzo email.
Gli elenchi restituiscono data e meta.nextCursor. Passa il cursore senza modificarlo per chiedere la pagina successiva e termina quando è null.
const API_BASE_URL = "https://lunidex.app/api/v1";
const apiKey = process.env.LUNIDEX_API_KEY;
let cursor = null;
if (!apiKey) throw new Error("Missing LUNIDEX_API_KEY");
do {
const query = new URLSearchParams({ limit: "100" });
if (cursor) query.set("cursor", cursor);
const response = await fetch(API_BASE_URL + "/cards?" + query, {
headers: { Authorization: "Bearer " + apiKey },
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? "REQUEST_FAILED");
console.log(result.data);
cursor = result.meta?.nextCursor ?? null;
} while (cursor);I percorsi sono relativi all’URL di base dell’API. Ogni riga indica il livello di accesso richiesto e i parametri elencati nel contratto OpenAPI. La specifica leggibile dalle macchine contiene gli schemi completi, esempi di richieste e risposte ed errori per operazione; le sezioni seguenti spiegano i flussi principali.
/openapi.jsonContratto pubblico leggibile dalle macchine; non richiede una chiave API.
/meIdentità limitata dell’account, senza indirizzo email.
/summaryStatistiche principali, conteggi fisici e distinti delle carte e totali sigillati in centesimi EUR.
/cardsPossedimenti paginati con filtri facoltativi per lingua e set.
cursor(query)limit(query)language(query)set(query)/cards/{cardId}Metadati TCGdex e possedimenti dell’account, senza valutazioni delle carte.
cardId(percorso)· obbligatoriolanguage(query)/cards/{cardId}Imposta la quantità assoluta per lingua e variante della carta.
cardId(percorso)· obbligatorio/sealed/catalogueCerca nel catalogo Cardmarket esistente di prodotti sigillati.
q(query)cursor(query)/sealed/positionsPosizioni correnti paginate, costo e valore di mercato memorizzato.
cursor(query)limit(query)language(query)productId(query)/sealed/positions/{productId}Posizioni per lingua di un prodotto posseduto.
productId(percorso)· obbligatorio/sealed/transactionsRegistro privato delle transazioni con revisioni e filtri.
cursor(query)limit(query)language(query)productId(query)type(query)includeVoided(query)voided(query)/sealed/transactionsCrea acquisto, vendita o scambio; chiave di idempotenza obbligatoria.
Idempotency-Key(header)· obbligatorio/sealed/transactions/{id}Legge una transazione appartenente all’account.
id(percorso)· obbligatorio/sealed/transactions/{id}Modifica una transazione con controllo delle revisioni.
id(percorso)· obbligatorio/sealed/transactions/{id}/voidAnnulla una transazione con controllo delle revisioni.
id(percorso)· obbligatorioGET /cards elenca le varianti possedute senza caricare l’intero catalogo TCGdex. Ogni possesso include cardId, setId, language, variant e quantity; i filtri facoltativi sono language e set.
GET /cards/{cardId} restituisce metadati TCGdex utili e i possedimenti di questa carta nell’account. Aggiungi il parametro language per restringere i possedimenti.
PUT /cards/{cardId} accetta language, variant (unspecified, normal, reverse o holo) e una quantità assoluta da 0 a 10.000. Il valore 0 rimuove la variante.
{
"language": "en",
"variant": "reverse",
"quantity": 2
}I vecchi possedimenti senza lingua restano visibili; language può essere null e possono essere contrassegnati legacy.
Questa API non restituisce mai il valore delle carte.
Le posizioni includono quantità per lingua, costo e valore corrente calcolato dai prezzi già memorizzati in Lunidex. Gli importi sono centesimi interi di EUR. Se manca un prezzo, valueCents è null e missingPrice lo indica; il riepilogo conta anche missingPrices.
In GET /summary, il valore dei prodotti sigillati è null se manca il prezzo di almeno un prodotto posseduto; missingPrices indica il totale.
Cerca prodotti già presenti nel catalogo Cardmarket con q (massimo 150 caratteri) e cursor. Ogni pagina contiene al massimo 24 prodotti; usa il loro ID nelle richieste successive.
GET /sealed/positions accetta i filtri language e productId. GET /sealed/positions/{productId} restituisce la posizione corrente di un prodotto. Questi endpoint mostrano i totali correnti, non l’intera serie dello storico prezzi.
Il registro privato accetta i filtri language, productId, type (buy, sell, exchange), includeVoided e voided. Include revisioni per consentire modifiche sicure.
PUT /cards/{cardId} imposta la quantità invece di aggiungere un incremento. Ripetere la stessa richiesta lascia invariata la quantità; invia 0 per rimuovere la variante. Prima di scrivere, l’API verifica carta, set, lingua e variante disponibile.
POST /sealed/transactions accetta movimenti buy, sell ed exchange. Richiede l’intestazione Idempotency-Key (8–200 caratteri) ed expectedRevision. Riutilizza la stessa chiave quando ripeti la stessa richiesta per evitare un secondo movimento. La prima richiesta crea la transazione; una ripetizione restituisce il risultato originale.
curl --request POST "https://lunidex.app/api/v1/sealed/transactions" \
-H "Authorization: Bearer $LUNIDEX_API_KEY" \
-H "Idempotency-Key: lunidex-import-example-001" \
-H "Content-Type: application/json" \
--data '{
"expectedRevision": 0,
"kind": "buy",
"cardmarketProductId": 12345,
"language": "en",
"date": "2026-09-27",
"quantity": 1,
"unitPriceCents": 2500
}'Prima di scrivere, leggi l’ultima revisione del registro nei metadati di GET /sealed/transactions e usala come expectedRevision. PATCH /sealed/transactions/{id} richiede anche la revision della transazione. Una revisione obsoleta restituisce 409; ricarica transazione e registro prima di decidere se riprovare.
PATCH /sealed/transactions/{id}
POST /sealed/transactions/{id}/void
POST /sealed/transactions/{id}/void richiede revision ed expectedRevision. Creazione, modifica e annullamento riutilizzano le stesse convalide, allocazioni e audit delle transazioni Lunidex.
{
"revision": 1,
"expectedRevision": 0
}Le risposte riuscite usano { "data": ..., "meta": ... } (meta è facoltativo). Gli errori usano { "error": { "code": ..., "message": ..., "details": ... } } (details è facoltativo).
Risposte comuni: 400 dati della transazione non validi; 401 chiave non valida; 403 permesso insufficiente; 404 risorsa assente o non posseduta; 409 cursore o revisione obsoleti; 410 account in eliminazione; 422 parametro di query o corpo della richiesta non valido; 429 quota raggiunta; 500 errore server imprevisto; 502 dati della carta non disponibili; 503 API non disponibile.
Con 409, recupera la risorsa aggiornata o riavvia l’elenco senza cursore. Non trasformare alla cieca un conflitto in una nuova transazione.
Una risposta 429 include Retry-After. Attendi almeno il numero di secondi indicato prima di riprovare.
Tutte le risposte private dell’API usano Cache-Control: private, no-store. Il documento OpenAPI pubblico è disponibile separatamente su /api/v1/openapi.json.
I limiti si applicano per account Lunidex e sono condivisi dalle sue chiavi API.
| Letture al minuto | 60 |
|---|---|
| Scritture al minuto | 10 |
| Letture al giorno | 1000 |
| Scritture al giorno | 100 |
| Dettagli carte per account al giorno | 100 |
| Calcoli sigillati per account al giorno | 100 |
| Limite globale giornaliero per categoria costosa | 5000 |
I dettagli delle carte e i calcoli dei prodotti sigillati hanno anche limiti globali distinti di 5.000 operazioni al giorno per categoria. Una risposta 429 include Retry-After.
Apri la specifica OpenAPI