{"openapi":"3.1.0","info":{"title":"ERERE — API per aziende e sviluppatori","version":"2026-11-03","description":"API pubbliche e B2B di ERERE. Nessuna API restituisce dati personali in chiaro: identità come impronte (user_hash), dati aggregati solo sopra le soglie di anonimato, file condivisi solo cifrati. Guida con esempi: /sviluppatori. Contatto: punto di contatto indicato nei Termini."},"servers":[{"url":"/"}],"components":{"securitySchemes":{"chiaveB2B":{"type":"apiKey","in":"header","name":"x-erere-key","description":"Chiave B2B rilasciata dal Custode"},"chiaveAgente":{"type":"apiKey","in":"header","name":"x-agent-key","description":"Chiave dell'agente (Agent Gateway)"}}},"paths":{"/api/verify":{"post":{"summary":"Verifica comportamentale di un'identità","security":[{"chiaveB2B":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["user_hash"],"additionalProperties":false,"properties":{"user_hash":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"},"min_accuracy":{"type":"integer","minimum":1,"maximum":100,"default":60}}}}}},"responses":{"200":{"description":"Esito","content":{"application/json":{"schema":{"type":"object","required":["verified","accuracy","neurons","timestamp"],"properties":{"verified":{"type":"boolean"},"accuracy":{"type":"integer","minimum":0,"maximum":100},"neurons":{"type":"integer","minimum":0},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"401":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/aggregate":{"get":{"summary":"Dati aggregati e anonimi","security":[{"chiaveB2B":[]}],"responses":{"200":{"description":"Totali e conteggi per gruppo, mai contesti individuali","content":{"application/json":{"schema":{"type":"object","required":["total_neurons","patterns","note","timestamp"],"properties":{"total_neurons":{"type":"integer","minimum":0},"patterns":{"type":"array","maxItems":20,"items":{"type":"object","required":["count"],"properties":{"count":{"type":"integer","minimum":0}}}},"note":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/agent/pricing":{"get":{"summary":"Listino dell'Agent Gateway","responses":{"200":{"description":"Prezzi per chiamata (centesimi) e abbonamenti","content":{"application/json":{"schema":{"type":"object","required":["per_call","subscriptions","rate_limit_per_second"],"properties":{"per_call":{"type":"object","additionalProperties":{"type":"integer","minimum":0,"description":"centesimi di euro, IVA inclusa"}},"subscriptions":{"type":"object","additionalProperties":{"type":"object","required":["name","calls_per_month","price_cents_month","overage_cents"],"properties":{"name":{"type":"string"},"calls_per_month":{"type":"integer","minimum":1},"price_cents_month":{"type":"integer","minimum":0,"description":"centesimi di euro, IVA inclusa"},"overage_cents":{"type":"integer","minimum":0,"description":"centesimi di euro, IVA inclusa"}}}},"rate_limit_per_second":{"type":"integer","minimum":1}}}}}}}}},"/api/agent/me":{"get":{"summary":"Stato dell'agente e consumo","security":[{"chiaveAgente":[]}],"responses":{"200":{"description":"Abbonamento e chiamate degli ultimi 30 giorni","content":{"application/json":{"schema":{"type":"object","required":["agent_id","name","status","kind","total_calls","total_revenue_eur","subscription","calls_last_30d_by_kind"],"properties":{"agent_id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"kind":{"type":"string"},"total_calls":{"type":"integer","minimum":0},"total_revenue_eur":{"type":"string","pattern":"^\\d+\\.\\d{2}$","description":"euro con due decimali"},"subscription":{"type":["object","null"],"properties":{"tier":{"type":"string"},"calls_used":{"type":"integer"},"calls_included":{"type":"integer"},"utilization_pct":{"type":"string"},"period_end":{"type":"integer"}}},"calls_last_30d_by_kind":{"type":"array","items":{"type":"object","required":["call_kind","cnt","total"],"properties":{"call_kind":{"type":"string"},"cnt":{"type":"integer"},"total":{"type":["integer","null"]}}}}}}}}},"401":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/pricing/catalogue":{"get":{"summary":"Listino pubblico: piani, pacchetti di spazio, pacchetti store","responses":{"200":{"description":"Listino, prezzi in centesimi di euro IVA inclusa","content":{"application/json":{"schema":{"type":"object","required":["ok","plans","packs","spazio_gratuito_gb","spazio","platform_fee_pct"],"properties":{"ok":{"const":true},"plans":{"type":"array","items":{"type":"object","required":["id","name","monthly_cent","yearly_cent","includes","monthly_eur","yearly_eur","purchasable"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"monthly_cent":{"type":"integer","minimum":0,"description":"centesimi di euro, IVA inclusa"},"yearly_cent":{"type":"integer","minimum":0,"description":"centesimi di euro, IVA inclusa"},"audience":{"type":"string"},"includes":{"type":"array","items":{"type":"string"}},"excludes":{"type":"array","items":{"type":"string"}},"rationale":{"type":"string"},"yearly_discount_pct":{"type":"number","minimum":0,"maximum":100},"monthly_eur":{"type":"string","pattern":"^\\d+\\.\\d{2}$","description":"euro con due decimali"},"yearly_eur":{"type":"string","pattern":"^\\d+\\.\\d{2}$","description":"euro con due decimali"},"stripe_price_id_monthly":{"type":["string","null"]},"stripe_price_id_yearly":{"type":["string","null"]},"purchasable":{"type":"boolean"}}}},"packs":{"type":"array","items":{"type":"object","required":["id","plan","price_cent"],"properties":{"id":{"type":"string"},"seats":{"type":["integer","null"],"minimum":1},"plan":{"type":"string"},"discount_pct":{"type":"number","minimum":0,"maximum":100},"note":{"type":"string"},"unit_full_cent":{"type":["integer","null"],"minimum":0,"description":"centesimi; null = su preventivo"},"full_cent":{"type":["integer","null"],"minimum":0,"description":"centesimi; null = su preventivo"},"price_cent":{"type":["integer","null"],"minimum":0,"description":"centesimi; null = su preventivo"},"saving_cent":{"type":["integer","null"],"minimum":0,"description":"centesimi; null = su preventivo"}}}},"spazio_gratuito_gb":{"type":"integer","minimum":0},"spazio":{"type":"array","items":{"type":"object","required":["id","nome","gb","monthly_cent","monthly_eur","stripe_price_id_monthly","purchasable"],"properties":{"id":{"type":"string"},"nome":{"type":"string"},"gb":{"type":"integer","minimum":1},"monthly_cent":{"type":"integer","minimum":0,"description":"centesimi di euro, IVA inclusa"},"monthly_eur":{"type":"string","pattern":"^\\d+\\.\\d{2}$","description":"euro con due decimali"},"stripe_price_id_monthly":{"type":["string","null"]},"purchasable":{"type":"boolean"}}}},"platform_fee_pct":{"type":"number","minimum":0,"maximum":100}}}}}}}}},"/api/patto":{"get":{"summary":"Il Patto chiaro: versione, scelte e regole","responses":{"200":{"description":"Testo del Patto","content":{"application/json":{"schema":{"type":"object","required":["ok","patto"],"properties":{"ok":{"const":true},"patto":{"type":"object","required":["versione","principio","regole","scelte"],"properties":{"versione":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"principio":{"type":"string"},"regole":{"type":"array","minItems":1,"items":{"type":"string"}},"scelte":{"type":"object"},"livelli":{"type":"object"}}}}}}}}}}},"/api/patto/verifica":{"post":{"summary":"Verifica una ricevuta firmata del Patto (Ed25519)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ricevuta"],"properties":{"ricevuta":{"type":"object"}}}}}},"responses":{"200":{"description":"Esito della verifica","content":{"application/json":{"schema":{"type":"object","required":["ok","valida"],"properties":{"ok":{"type":"boolean"},"valida":{"type":"boolean"},"motivo":{"type":"string"}}}}}},"400":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/stato":{"get":{"summary":"Stato pubblico del servizio (senza dati di persone)","responses":{"200":{"description":"true = funziona, false = non configurato o guasto, null = mai provato","content":{"application/json":{"schema":{"type":"object","required":["ok","servizi"],"properties":{"ok":{"const":true},"servizi":{"type":"object","additionalProperties":{"type":["boolean","null"]}}}}}}}}}},"/api/condiviso/{id}":{"get":{"summary":"File o cartella condivisi con un link: metadati cifrati","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{22}$"},"description":"identificativo del link (16 byte casuali, base64url)"}],"responses":{"200":{"description":"La chiave è solo nel link di chi ha condiviso (dopo #): il server non la riceve mai","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"},"tipo":{"enum":["file","cartella"]},"nome_cifrato":{"type":"string"},"blocchi":{"type":"integer","minimum":1},"dimensione":{"type":"integer","minimum":0},"scade":{"type":"integer","description":"ms dall'epoca"},"file":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{32}$"},"nome_cifrato":{"type":"string"},"blocchi":{"type":"integer"},"dimensione":{"type":"integer"},"chiave_avvolta":{"type":"string"}}}}}}}}},"404":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"410":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/condiviso/{id}/blocco/{n}":{"get":{"summary":"Blocco cifrato di un file condiviso","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{22}$"},"description":"identificativo del link (16 byte casuali, base64url)"},{"name":"n","in":"path","required":true,"schema":{"type":"integer","minimum":0,"maximum":99999},"description":"indice del blocco (0 … blocchi-1)"}],"responses":{"200":{"description":"Blocco cifrato: nonce 24 byte ‖ XChaCha20-Poly1305; AAD = sale ‖ indice ‖ totale","content":{"application/json":{"schema":{"type":"object","required":["dati"],"properties":{"dati":{"type":"string","contentEncoding":"base64"}}}}}},"404":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"410":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/condiviso/{id}/file/{fid}/blocco/{n}":{"get":{"summary":"Blocco cifrato di un file dentro una cartella condivisa","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{22}$"},"description":"identificativo del link (16 byte casuali, base64url)"},{"name":"fid","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-f]{32}$"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer","minimum":0,"maximum":99999},"description":"indice del blocco (0 … blocchi-1)"}],"responses":{"200":{"description":"Blocco cifrato: nonce 24 byte ‖ XChaCha20-Poly1305; AAD = sale ‖ indice ‖ totale — solo file presenti nella cartella al momento del link","content":{"application/json":{"schema":{"type":"object","required":["dati"],"properties":{"dati":{"type":"string","contentEncoding":"base64"}}}}}},"404":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"410":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/passkey/accedi/opzioni":{"post":{"summary":"Accesso con passkey (WebAuthn): sfida monouso, 5 minuti","responses":{"200":{"description":"Opzioni per navigator.credentials.get","content":{"application/json":{"schema":{"type":"object","required":["ok","sfida_id","opzioni"],"properties":{"ok":{"const":true},"sfida_id":{"type":"string","pattern":"^[A-Za-z0-9_-]{22}$"},"opzioni":{"type":"object","required":["rpId","challenge","userVerification"],"properties":{"rpId":{"type":"string"},"challenge":{"type":"string"},"timeout":{"type":"integer"},"userVerification":{"const":"required"}}}}}}}},"429":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/passkey/accedi/verifica":{"post":{"summary":"Accesso con passkey: verifica e sessione (cookie)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sfida_id","risposta"],"properties":{"sfida_id":{"type":"string"},"risposta":{"type":"object"}}}}}},"responses":{"200":{"description":"Sessione aperta (cookie HttpOnly)","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"401":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Errore","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/.well-known/erere-ricevute.json":{"get":{"summary":"Chiavi pubbliche Ed25519 con cui chiunque verifica le ricevute firmate di ERERE (Patto, non-tradimento)","responses":{"200":{"description":"Chiave attuale e precedenti dopo una rotazione","content":{"application/json":{"schema":{"type":"object","required":["emittente","uso","chiavi"],"properties":{"emittente":{"const":"ERERE"},"uso":{"type":"string"},"chiavi":{"type":"array","minItems":1,"items":{"type":"object","required":["key_id","alg","pem","attuale"],"properties":{"key_id":{"type":"string","pattern":"^ed25519:[0-9a-f]{16}$"},"alg":{"const":"Ed25519"},"pem":{"type":"string","pattern":"^-----BEGIN PUBLIC KEY-----"},"attuale":{"type":"boolean"}}}}}}}}}}}},"/api/health":{"get":{"summary":"Il server risponde","responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"const":"ok"}}}}}}}}}}}