{"openapi":"3.1.0","info":{"title":"Richiami Alimenti API","version":"1.0.0","description":"API B2B dei richiami alimentari pubblicati dal Ministero della Salute, con campi separati e normalizzati. Documentazione completa in italiano: https://richiamialimenti.it/professionisti/api\n\nFonte dei dati: Ministero della Salute (CC BY 4.0). Richiami Alimenti non è affiliato al Ministero; in caso di dubbio vale sempre l'avviso ufficiale, linkato in ogni record.","contact":{"name":"Richiami Alimenti","email":"info@richiamialimenti.it","url":"https://richiamialimenti.it/professionisti"}},"servers":[{"url":"https://richiamialimenti.it/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Account","description":"Stato della prova e limiti della chiave."},{"name":"Aziende","description":"Le attività alimentari tue clienti. Ogni azienda ha un id (UUID) da mandare nell'header X-Company-Id delle chiamate ai dati."},{"name":"Lista di sorveglianza","description":"Marchi, produttori, prodotti, GTIN, lotti e fornitori da tenere d'occhio per ogni azienda."},{"name":"Richiami","description":"Il feed dei richiami: solo richiami attivi, con link all'avviso ufficiale."},{"name":"Abbinamenti","description":"Richiami che toccano la lista di sorveglianza di un'azienda."},{"name":"Webhook","description":"Eventi firmati inviati al tuo server."}],"paths":{"/account":{"get":{"tags":["Account"],"summary":"Stato dell'accesso e limiti","operationId":"getAccount","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Account"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/companies":{"get":{"tags":["Aziende"],"summary":"Elenco delle tue aziende","operationId":"listCompanies","parameters":[{"name":"active","in":"query","schema":{"type":"boolean"}},{"name":"external_id","in":"query","schema":{"type":"string"}},{"name":"vat_number","in":"query","schema":{"type":"string"}},{"$ref":"#/components/parameters/PerPage"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Company"}},"meta":{"$ref":"#/components/schemas/PageMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"tags":["Aziende"],"summary":"Crea un'azienda","description":"Serve un'azienda per ogni cliente finale reale, con ragione sociale e partita IVA o codice fiscale validi. Restituisce l'id da usare in X-Company-Id. La partita IVA viene verificata su VIES in un secondo momento.","operationId":"createCompany","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/CompanyInput"},{"required":["name"]}]},"example":{"name":"Trattoria da Mario srl","vat_number":"IT01234567890","external_id":"CLI-042","province":"BN"}}}},"responses":{"201":{"description":"Azienda creata","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Company"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/companies/{company_id}":{"parameters":[{"$ref":"#/components/parameters/CompanyId"}],"get":{"tags":["Aziende"],"summary":"Un'azienda","operationId":"getCompany","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Company"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"patch":{"tags":["Aziende"],"summary":"Modifica o riattiva un'azienda","description":"Partita IVA e codice fiscale non si possono cambiare (solo aggiungere se mancano).","operationId":"updateCompany","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyPatch"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Company"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"delete":{"tags":["Aziende"],"summary":"Disattiva un'azienda","description":"I dati restano; le chiamate con questa azienda vengono rifiutate finché non la riattivi.","operationId":"deactivateCompany","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Company"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/companies/{company_id}/watchlist":{"parameters":[{"$ref":"#/components/parameters/CompanyId"}],"get":{"tags":["Lista di sorveglianza"],"summary":"Voci della lista","operationId":"listWatchlist","parameters":[{"$ref":"#/components/parameters/PerPage"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WatchlistItem"}},"meta":{"$ref":"#/components/schemas/PageMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"tags":["Lista di sorveglianza"],"summary":"Aggiunge una voce o più voci","description":"Una voce, oppure {\"items\": [...]} con al massimo 500 voci. La risposta elenca i richiami già in archivio che toccano ogni voce.","operationId":"addWatchlistItems","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/WatchlistItemInput"},{"type":"object","required":["items"],"properties":{"items":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/WatchlistItemInput"}}}}]},"example":{"items":[{"brand":"Salumi Rossi","lot":"L24A123","label":"Salame del banco"},{"gtin":"8001234567897","external_id":"ART-9"}]}}}},"responses":{"201":{"description":"Voci create","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"oneOf":[{"$ref":"#/components/schemas/WatchlistItemCreated"},{"type":"array","items":{"$ref":"#/components/schemas/WatchlistItemCreated"}}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/companies/{company_id}/watchlist/{item_id}":{"parameters":[{"$ref":"#/components/parameters/CompanyId"},{"$ref":"#/components/parameters/ItemId"}],"patch":{"tags":["Lista di sorveglianza"],"summary":"Modifica una voce","operationId":"updateWatchlistItem","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistItemInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WatchlistItemCreated"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"delete":{"tags":["Lista di sorveglianza"],"summary":"Toglie una voce","operationId":"deleteWatchlistItem","responses":{"204":{"description":"Voce tolta, con i suoi abbinamenti"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/recalls":{"get":{"tags":["Richiami"],"summary":"Feed dei richiami","description":"Solo richiami attivi. Senza updated_since: dal più recente (sort=recall_date). Con updated_since: in ordine di modifica (sort=updated_at), il modo consigliato per sincronizzare: salva meta.last_update e usalo come updated_since alla chiamata successiva.","operationId":"listRecalls","parameters":[{"$ref":"#/components/parameters/CompanyHeader"},{"name":"updated_since","in":"query","description":"Record modificati da questa data/ora (ISO 8601).","schema":{"type":"string","format":"date-time"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["recall_date","updated_at"]}},{"name":"brand","in":"query","description":"Slug del marchio o testo nel marchio.","schema":{"type":"string"}},{"name":"producer","in":"query","description":"Testo nel produttore.","schema":{"type":"string"}},{"name":"product","in":"query","description":"Testo nel nome del prodotto.","schema":{"type":"string"}},{"name":"lot","in":"query","description":"Testo nel lotto.","schema":{"type":"string"}},{"name":"gtin","in":"query","description":"GTIN completo (8-14 cifre).","schema":{"type":"string"}},{"name":"hazard","in":"query","description":"Slug del motivo (es. listeria, salmonella).","schema":{"type":"string"}},{"name":"chain","in":"query","description":"Slug della catena (marca del distributore, venditore o segnalazioni nei suoi negozi).","schema":{"type":"string"}},{"name":"revoked","in":"query","schema":{"type":"boolean"}},{"name":"from","in":"query","description":"Data del richiamo dal (AAAA-MM-GG).","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"Data del richiamo fino al (AAAA-MM-GG).","schema":{"type":"string","format":"date"}},{"$ref":"#/components/parameters/PerPage"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Recall"}},"meta":{"$ref":"#/components/schemas/RecallsMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/recalls/removed":{"get":{"tags":["Richiami"],"summary":"Richiami tolti dal feed","description":"Doppioni uniti a un altro richiamo o avvisi ritirati: cancellali dalla tua copia (o sostituiscili con replaced_by).","operationId":"listRemovedRecalls","parameters":[{"$ref":"#/components/parameters/CompanyHeader"},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"$ref":"#/components/parameters/PerPage"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RemovedRecall"}},"meta":{"$ref":"#/components/schemas/PageMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/recalls/{recall_id}":{"get":{"tags":["Richiami"],"summary":"Un richiamo","operationId":"getRecall","parameters":[{"$ref":"#/components/parameters/CompanyHeader"},{"$ref":"#/components/parameters/RecallId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Recall"},"meta":{"$ref":"#/components/schemas/Freshness"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"410":{"$ref":"#/components/responses/Gone"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/matches":{"get":{"tags":["Abbinamenti"],"summary":"Richiami che toccano la lista dell'azienda","description":"Dal più recente. Ogni elemento dice quali voci della lista corrispondono e con quali valori.","operationId":"listMatches","parameters":[{"$ref":"#/components/parameters/CompanyHeader"},{"name":"since","in":"query","description":"Abbinamenti trovati da questa data/ora.","schema":{"type":"string","format":"date-time"}},{"name":"revoked","in":"query","schema":{"type":"boolean"}},{"$ref":"#/components/parameters/PerPage"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Match"}},"meta":{"$ref":"#/components/schemas/RecallsMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/webhook":{"get":{"tags":["Webhook"],"summary":"Configurazione del webhook","operationId":"getWebhook","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"put":{"tags":["Webhook"],"summary":"Imposta l'URL del webhook","description":"La prima volta genera il secret per le firme e lo restituisce: è l'unica volta in cui si vede.","operationId":"setWebhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"delete":{"tags":["Webhook"],"summary":"Disattiva il webhook","operationId":"deleteWebhook","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/webhook/secret":{"post":{"tags":["Webhook"],"summary":"Nuovo secret","description":"Il secret precedente smette subito di valere.","operationId":"rotateWebhookSecret","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/webhook/test":{"post":{"tags":["Webhook"],"summary":"Invia un evento di prova","description":"Evento con \"test\": true e un richiamo finto con id 0. Al massimo 5 al minuto e 100 al giorno.","operationId":"testWebhook","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","enum":["recall.created","recall.updated","recall.revoked","recall.removed","match.created"],"default":"recall.created"}}}}}},"responses":{"202":{"description":"Evento in coda","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Delivery"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/webhook/deliveries":{"get":{"tags":["Webhook"],"summary":"Ultime consegne","operationId":"listDeliveries","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivered","failed"]}},{"$ref":"#/components/parameters/PerPage"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},"meta":{"$ref":"#/components/schemas/PageMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}},"webhooks":{"recall.created":{"post":{"summary":"recall.created","description":"Nuovo richiamo (o tornato attivo).","parameters":[{"name":"X-Richiami-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Richiami-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Richiami-Signature","in":"header","required":true,"description":"t=<timestamp unix>,v1=<hex di HMAC-SHA256(secret, timestamp + \".\" + corpo)>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EventEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"recall":{"$ref":"#/components/schemas/Recall"}}}}}]}}}},"responses":{"2XX":{"description":"Ricevuto. Ogni altra risposta (o nessuna entro 10 secondi) fa ripetere l'invio per circa un giorno."}},"operationId":"onRecallCreated"}},"recall.updated":{"post":{"summary":"recall.updated","description":"È cambiato almeno un campo del record; changed elenca quali.","parameters":[{"name":"X-Richiami-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Richiami-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Richiami-Signature","in":"header","required":true,"description":"t=<timestamp unix>,v1=<hex di HMAC-SHA256(secret, timestamp + \".\" + corpo)>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EventEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"recall":{"$ref":"#/components/schemas/Recall"},"changed":{"type":"array","items":{"type":"string"}}}}}}]}}}},"responses":{"2XX":{"description":"Ricevuto. Ogni altra risposta (o nessuna entro 10 secondi) fa ripetere l'invio per circa un giorno."}},"operationId":"onRecallUpdated"}},"recall.revoked":{"post":{"summary":"recall.revoked","description":"Il Ministero ha revocato il richiamo.","parameters":[{"name":"X-Richiami-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Richiami-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Richiami-Signature","in":"header","required":true,"description":"t=<timestamp unix>,v1=<hex di HMAC-SHA256(secret, timestamp + \".\" + corpo)>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EventEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"recall":{"$ref":"#/components/schemas/Recall"}}}}}]}}}},"responses":{"2XX":{"description":"Ricevuto. Ogni altra risposta (o nessuna entro 10 secondi) fa ripetere l'invio per circa un giorno."}},"operationId":"onRecallRevoked"}},"recall.removed":{"post":{"summary":"recall.removed","description":"Richiamo tolto dal feed (doppione unito o avviso ritirato).","parameters":[{"name":"X-Richiami-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Richiami-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Richiami-Signature","in":"header","required":true,"description":"t=<timestamp unix>,v1=<hex di HMAC-SHA256(secret, timestamp + \".\" + corpo)>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EventEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RemovedRecall"}}}]}}}},"responses":{"2XX":{"description":"Ricevuto. Ogni altra risposta (o nessuna entro 10 secondi) fa ripetere l'invio per circa un giorno."}},"operationId":"onRecallRemoved"}},"match.created":{"post":{"summary":"match.created","description":"Un richiamo nuovo o aggiornato tocca la lista di sorveglianza di una tua azienda.","parameters":[{"name":"X-Richiami-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Richiami-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Richiami-Signature","in":"header","required":true,"description":"t=<timestamp unix>,v1=<hex di HMAC-SHA256(secret, timestamp + \".\" + corpo)>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EventEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"company":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"external_id":{"type":["string","null"]}}},"matched_at":{"type":"string","format":"date-time"},"items":{"type":"array","items":{"$ref":"#/components/schemas/MatchItem"}},"recall":{"$ref":"#/components/schemas/Recall"}}}}}]}}}},"responses":{"2XX":{"description":"Ricevuto. Ogni altra risposta (o nessuna entro 10 secondi) fa ripetere l'invio per circa un giorno."}},"operationId":"onMatchCreated"}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Chiave API personale (inizia con rk_live_). Si vede una sola volta alla consegna: conservala come una password."}},"parameters":{"CompanyHeader":{"name":"X-Company-Id","in":"header","required":true,"description":"Id (UUID) di una tua azienda attiva, restituito da POST /companies.","schema":{"type":"string","format":"uuid"}},"CompanyId":{"name":"company_id","in":"path","required":true,"description":"Id (UUID) dell'azienda.","schema":{"type":"string","format":"uuid"}},"ItemId":{"name":"item_id","in":"path","required":true,"schema":{"type":"integer"}},"RecallId":{"name":"recall_id","in":"path","required":true,"schema":{"type":"integer"}},"Cursor":{"name":"cursor","in":"query","description":"Valore di meta.next_cursor della pagina precedente.","schema":{"type":"string"}},"PerPage":{"name":"per_page","in":"query","description":"Elementi per pagina (default 50, massimo 200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}},"responses":{"BadRequest":{"description":"Manca l'header X-Company-Id (code company_required).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"…","code":"company_required"}}}},"Unauthorized":{"description":"Chiave mancante, revocata o non valida (code invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"…","code":"invalid_api_key"}}}},"Forbidden":{"description":"Prova terminata (trial_expired), accesso sospeso (account_suspended) o terminato (account_ended), azienda disattivata (company_deactivated), limite di aziende (company_limit).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"…","code":"trial_expired"}}}},"NotFound":{"description":"Risorsa non trovata tra le tue (company_not_found, recall_not_found, watchlist_item_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"…","code":"company_not_found"}}}},"Conflict":{"description":"Esiste già un'azienda con questa partita IVA o codice fiscale (company_exists, con company_id), oppure webhook non configurato (webhook_not_configured).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"…","code":"company_exists"}}}},"Gone":{"description":"Richiamo tolto dal feed (code recall_removed); replaced_by è l'id del richiamo che lo sostituisce, se c'è.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"replaced_by":{"type":["integer","null"]}}}]}}}},"ValidationError":{"description":"Dati non validi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"TooManyRequests":{"description":"Limite di richieste superato (code rate_limited). Riprova dopo Retry-After secondi.","headers":{"Retry-After":{"schema":{"type":"integer"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["message","code"],"properties":{"message":{"type":"string"},"code":{"type":"string"}}},"ValidationError":{"type":"object","required":["message","errors"],"properties":{"message":{"type":"string"},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"PageMeta":{"type":"object","required":["per_page","next_cursor"],"properties":{"per_page":{"type":"integer"},"next_cursor":{"type":["string","null"],"description":"Cursore della pagina successiva; null all'ultima pagina."}}},"Freshness":{"type":"object","properties":{"last_update":{"type":["string","null"],"format":"date-time","description":"Ultima modifica di un record del feed."},"last_check":{"type":["string","null"],"format":"date-time","description":"Ultimo controllo degli avvisi del Ministero (circa ogni 2 ore)."}}},"RecallsMeta":{"allOf":[{"$ref":"#/components/schemas/PageMeta"},{"$ref":"#/components/schemas/Freshness"},{"type":"object","properties":{"sort":{"type":"string","enum":["recall_date","updated_at"]}}}]},"Account":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["trial","active","suspended","ended"]},"trial_ends_at":{"type":["string","null"],"format":"date-time","description":"Fine della prova gratuita: poi l'accesso si chiude da solo, senza addebiti."},"limits":{"type":"object","properties":{"requests_per_minute":{"type":"integer"},"requests_per_day":{"type":"integer"},"companies":{"type":["integer","null"]},"watchlist_items_per_company":{"type":"integer"}}},"companies":{"type":"object","properties":{"active":{"type":"integer"},"total":{"type":"integer"}}},"webhook":{"type":"object","properties":{"configured":{"type":"boolean"},"events":{"type":["array","null"],"items":{"type":"string"}}}}}},"CompanyInput":{"type":"object","properties":{"name":{"type":"string","description":"Ragione sociale.","maxLength":255},"vat_number":{"type":"string","description":"Partita IVA italiana (11 cifre, accettato anche con IT davanti). Obbligatoria se manca tax_code. Non si può cambiare dopo la creazione."},"tax_code":{"type":"string","description":"Codice fiscale (16 caratteri o 11 cifre). Obbligatorio se manca vat_number. Non si può cambiare dopo la creazione."},"external_id":{"type":"string","maxLength":100,"description":"Il tuo codice cliente, per ritrovare l'azienda."},"city":{"type":"string"},"province":{"type":"string","maxLength":4,"description":"Sigla della provincia."}}},"CompanyPatch":{"allOf":[{"$ref":"#/components/schemas/CompanyInput"},{"type":"object","properties":{"active":{"type":"boolean","description":"true riattiva un'azienda disattivata."}}}]},"Company":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"vat_number":{"type":["string","null"]},"tax_code":{"type":["string","null"]},"external_id":{"type":["string","null"]},"city":{"type":["string","null"]},"province":{"type":["string","null"]},"active":{"type":"boolean"},"vat_check":{"type":"object","description":"Verifica facoltativa della partita IVA su VIES, fatta da noi dopo la creazione.","properties":{"status":{"type":"string","enum":["unchecked","valid","invalid","unavailable"]},"checked_at":{"type":["string","null"],"format":"date-time"},"registered_name":{"type":["string","null"]}}},"watchlist_items":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"deactivated_at":{"type":["string","null"],"format":"date-time"}}},"WatchlistItemInput":{"type":"object","description":"Almeno un criterio. Una voce corrisponde a un richiamo quando corrispondono TUTTI i suoi criteri compilati.","properties":{"brand":{"type":"string","description":"Marchio: stesso marchio del nostro catalogo, o il nome come parole intere nel marchio dell'avviso."},"producer":{"type":"string","description":"Produttore: stessa azienda del catalogo, o il nome (senza forma societaria) nel produttore dell'avviso."},"product":{"type":"string","description":"Prodotto: tutte le parole (singolare o plurale) nel nome del prodotto richiamato."},"gtin":{"type":"string","description":"GTIN/EAN di 8, 12, 13 o 14 cifre con cifra di controllo corretta."},"lot":{"type":"string","description":"Lotto: uno dei codici di lotto dell'avviso (lettere e cifre, senza spazi e punteggiatura)."},"supplier":{"type":"string","description":"Fornitore: il nome nel distributore, nel produttore o nella catena del marchio."},"label":{"type":"string","description":"Descrizione libera, ripetuta negli abbinamenti."},"external_id":{"type":"string","maxLength":100,"description":"Il tuo codice articolo."}}},"WatchlistItem":{"type":"object","properties":{"id":{"type":"integer"},"brand":{"type":["string","null"],"description":"Marchio: stesso marchio del nostro catalogo, o il nome come parole intere nel marchio dell'avviso."},"producer":{"type":["string","null"],"description":"Produttore: stessa azienda del catalogo, o il nome (senza forma societaria) nel produttore dell'avviso."},"product":{"type":["string","null"],"description":"Prodotto: tutte le parole (singolare o plurale) nel nome del prodotto richiamato."},"gtin":{"type":["string","null"],"description":"GTIN/EAN di 8, 12, 13 o 14 cifre con cifra di controllo corretta."},"lot":{"type":["string","null"],"description":"Lotto: uno dei codici di lotto dell'avviso (lettere e cifre, senza spazi e punteggiatura)."},"supplier":{"type":["string","null"],"description":"Fornitore: il nome nel distributore, nel produttore o nella catena del marchio."},"label":{"type":["string","null"]},"external_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}},"WatchlistItemCreated":{"allOf":[{"$ref":"#/components/schemas/WatchlistItem"},{"type":"object","properties":{"matches":{"type":"array","items":{"type":"integer"},"description":"Id dei richiami già in archivio che toccano la voce (senza webhook)."}}}]},"MatchItem":{"type":"object","properties":{"watchlist_item_id":{"type":"integer"},"label":{"type":["string","null"]},"external_id":{"type":["string","null"]},"matched":{"type":"object","description":"Criteri che corrispondono, con il valore trovato nel richiamo.","additionalProperties":{"type":"string"}}}},"Match":{"type":"object","properties":{"matched_at":{"type":"string","format":"date-time"},"source":{"type":"string","enum":["new_recall","recall_updated","watchlist"],"description":"new_recall/recall_updated: arrivato con il feed (anche via webhook match.created); watchlist: trovato in archivio quando hai aggiunto la voce."},"items":{"type":"array","items":{"$ref":"#/components/schemas/MatchItem"}},"recall":{"$ref":"#/components/schemas/Recall"}}},"Recall":{"type":"object","description":"Record di un richiamo. Nessuna foto delle confezioni: per immagini e testo integrale vale l'avviso ufficiale (official_notice).","properties":{"id":{"type":"integer","description":"Id stabile del richiamo (0 solo negli eventi di prova)."},"url":{"type":"string","format":"uri","description":"Pagina del richiamo su richiamialimenti.it."},"recall_date":{"type":"string","format":"date"},"updated_at":{"type":"string","format":"date-time","description":"Ultima modifica di un campo di questo record (non cambia per modifiche interne)."},"product":{"type":"string"},"brand":{"type":["object","null"],"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"description":"Marchio normalizzato del nostro catalogo."},"brand_raw":{"type":["string","null"],"description":"Marchio come scritto nell'avviso."},"company":{"type":["object","null"],"properties":{"name":{"type":"string"},"city":{"type":["string","null"]}},"description":"Produttore normalizzato."},"producer_raw":{"type":["string","null"],"description":"Produttore come scritto nell'avviso."},"private_label_of":{"type":["string","null"],"description":"Catena di cui il marchio è marca del distributore."},"hazards":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"}}}},"reason":{"type":["string","null"]},"warnings":{"type":["string","null"],"description":"Avvertenze per chi ha il prodotto."},"lot":{"type":["string","null"],"description":"Lotti come scritti nell'avviso."},"lot_codes":{"type":"array","items":{"type":"string"},"description":"Codici di lotto estratti (lettere e cifre maiuscole)."},"expiry":{"type":["string","null"],"description":"Scadenza o TMC come scritti nell'avviso."},"expiry_dates":{"type":"array","items":{"type":"string"},"description":"Date leggibili in ISO 8601: AAAA-MM-GG, oppure AAAA-MM quando l'avviso indica solo mese e anno."},"plant":{"type":["string","null"],"description":"Stabilimento o bollo CE."},"format":{"type":["string","null"]},"distributor":{"type":["string","null"]},"gtin":{"type":"array","items":{"type":"string"},"description":"Codici GTIN/EAN, solo con cifra di controllo corretta. Presenti in una minoranza dei richiami: il modulo del Ministero non prevede il campo."},"gtin_source":{"type":["string","null"],"enum":["avviso","foto","manuale",null],"description":"avviso: scritto nel testo; foto: letto dal codice a barre nelle foto; manuale: inserito da noi."},"revoked":{"type":"boolean"},"revocation":{"type":["object","null"],"properties":{"date":{"type":["string","null"],"format":"date"},"reason":{"type":"string"},"page_url":{"type":["string","null"],"format":"uri"}},"description":"Revoca del richiamo pubblicata dal Ministero."},"official_notice":{"type":"object","properties":{"page_url":{"type":["string","null"],"format":"uri","description":"Scheda dell'avviso sul sito del Ministero."},"pdf_url":{"type":["string","null"],"format":"uri","description":"PDF ufficiale dell'avviso."}}},"source":{"type":"object","properties":{"name":{"type":"string"},"license":{"type":"string"},"license_url":{"type":"string","format":"uri"},"attribution":{"type":"string"}}}}},"RemovedRecall":{"type":"object","properties":{"recall_id":{"type":"integer"},"removed_at":{"type":"string","format":"date-time"},"replaced_by":{"type":["integer","null"]}}},"WebhookConfig":{"type":"object","properties":{"url":{"type":["string","null"],"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["recall.created","recall.updated","recall.revoked","recall.removed","match.created"]}},"secret":{"type":["string","null"],"description":"Secret per verificare la firma X-Richiami-Signature. Presente solo nella risposta che lo crea (prima PUT /webhook, POST /webhook/secret): conservalo."},"secret_hint":{"type":["string","null"],"description":"Ultime 4 cifre del secret in uso."}}},"WebhookInput":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"URL https pubblico sulla porta 443."},"events":{"type":"array","items":{"type":"string","enum":["recall.created","recall.updated","recall.revoked","recall.removed","match.created"]},"description":"Eventi da ricevere; vuoto = tutti."}}},"Delivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Uguale all'header X-Richiami-Delivery e all'id dell'evento."},"event":{"type":"string"},"test":{"type":"boolean"},"status":{"type":"string","enum":["pending","delivered","failed"]},"attempts":{"type":"integer"},"last_status_code":{"type":["integer","null"]},"last_error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"}}},"EventEnvelope":{"type":"object","required":["id","event","created_at","api_version","test","data"],"properties":{"id":{"type":"string","format":"uuid"},"event":{"type":"string","enum":["recall.created","recall.updated","recall.revoked","recall.removed","match.created"]},"created_at":{"type":"string","format":"date-time"},"api_version":{"type":"string","const":"v1"},"test":{"type":"boolean","description":"true solo per gli eventi inviati con POST /webhook/test: non sono richiami veri."},"data":{"type":"object"}}}}}}