{"revision":"0ed62d2c742f8e20","language":"it","entry":{"id":"publish-person","kind":"endpoint","group":"manage","title":"Pubblica la versione successiva di una persona","method":"POST","path":"/v1/identities/{n}/versions","paths":[],"summary":"Modifica chiavi, account collegati, alias o altri campi firmati della scheda.","response":"201 con n, id, url, token, version, commitment, logIndex, publishedAt e checkpoint. La risposta segue la pubblicazione controfirmata.","parameters":[{"name":"n","description":"Numero permanente positivo della scheda.","in":"path","required":true}],"sample":"/v1/identities/1/versions","access":"signed","base":"directory","notes":["Su un registro in formato 2 il corpo è {label, body, signature, pictureData?}, con clientSalt e saltTicket obbligatori per la versione 1; un record si rifiuta con wrong_format.","Dal 29 ottobre 2026 il corpo di una persona può portare addExternalKey {type, pub, fp, label, proof: {anchor, at, by, sig, variant?}} e removeExternalKey {fp}: chiavi pubbliche di altri sistemi con la loro prova di possesso. proof.variant dice la forma della sfida firmata quando non sono i byte offerti (crlf, bom, noeol e le loro combinazioni). La sfida e i controlli sono nella voce delle chiavi pubbliche di altri sistemi (external-keys-file) e in docs/formato-v2.md, sezione 4."],"errors":["400 invalid_alias","400 invalid_json","400 invalid_name","400 invalid_nonce","400 invalid_parameter","400 invalid_signature_alg","400 invalid_timestamp","400 wrong_format","401 invalid_signature","401 missing_signature","401 stale_timestamp","403 identity_banned","403 key_banned","403 key_mismatch","403 recovery_key_only","403 role_not_allowed","403 signer_not_authorised","404 not_found","409 account_locked","409 alias_quarantined","409 alias_reserved","409 alias_taken","409 already_member","409 erase_pending","409 grant_used","409 invitation_withdrawn","409 key_already_used","409 replayed_nonce","409 takeover_already_open","409 version_conflict","410 erased","413 payload_too_large","422 cannot_revoke_self","422 external_limit","422 grant_expired","422 invalid_grant","422 invalid_logo","422 invalid_op","422 invalid_record","422 invalid_record_signature","422 key_expired","422 key_extra_packets","422 key_revoked","422 key_unsupported","422 key_weak","422 keys_limit","422 label_mismatch","422 last_owner","422 links_need_verification","422 membership_needs_grant","422 not_a_person","422 private_key_material","422 proof_anchor","422 proof_invalid","422 proof_stale","429 rate_limited","500 internal_error","502 log_mismatch","503 busy","503 log_unavailable"],"related":["signed-requests","external-keys-file"],"sections":[{"kind":"code","language":"shell","code":"curl -fsS -X POST \\\n  -H \"X-Public-Key: $PUBLIC_KEY\" \\\n  -H \"X-Signature: $REQUEST_SIGNATURE\" --json @request.json \\\n  \"https://veil.rip/v1/identities/1/versions\""}],"bodyFields":[{"name":"record","description":"Il record canonico completo della persona o organizzazione, inclusi i campi della storia.","in":"body","required":true},{"name":"signature","description":"La firma del record, distinta dall’intestazione di firma della richiesta.","in":"body","required":true},{"name":"logoData","description":"L’immagine che record.logo nomina per hash, in base64 standard con padding su una riga. Obbligatorio quando la versione porta un’immagine nuova. Con un’immagine invariata si può omettere, e se arriva deve corrispondere.","in":"body","required":false},{"name":"nonce","description":"Un nonce nuovo da 16 a 128 caratteri con lettere, cifre, trattino basso o trattino.","in":"body","required":true},{"name":"timestamp","description":"Millisecondi Unix entro due minuti dall’orologio del server.","in":"body","required":true},{"name":"label","description":"Formato 2: l’intestazione come oggetto JSON; il server la codifica in forma canonica e controlla la firma su quei byte.","in":"body","required":false},{"name":"body","description":"Formato 2: il corpo come oggetto JSON, con il suo hash in label.body.","in":"body","required":false},{"name":"pictureData","description":"Formato 2: i byte di una nuova immagine che il corpo nomina per hash, in base64 standard con padding.","in":"body","required":false}],"live":false,"responses":[{"status":201,"contentType":"application/json","description":"201 con n, id, url, token, version, commitment, logIndex, publishedAt e checkpoint. La risposta segue la pubblicazione controfirmata.","fields":[{"name":"n","type":"integer","description":"Numero permanente della scheda."},{"name":"id","type":"string","description":"Impegno della prima versione in hex."},{"name":"url","type":"string","description":"URL permanente della scheda."},{"name":"token","type":"string","description":"Pseudonimo stabile nel registro in base64url."},{"name":"version","type":"integer","description":"Numero della versione pubblicata."},{"name":"commitment","type":"string","description":"Impegno di questa versione in hex."},{"name":"logIndex","type":"integer","description":"Indice nel registro a partire da zero."},{"name":"publishedAt","type":"string","description":"Prima data e ora di controfirma alla pubblicazione."},{"name":"checkpoint","type":"Checkpoint","description":"Primo checkpoint che copre la versione."}]}],"responseObjects":[{"id":"checkpoint","title":"Checkpoint","fields":[{"name":"size","type":"integer","description":"Numero di foglie nell’albero firmato."},{"name":"root","type":"string","description":"Hash della radice in base64."},{"name":"note","type":"string","description":"Nota firmata completa, incluse le firme del registro e dei testimoni."}],"typeName":"Checkpoint"}],"errorFormat":"json","errorDetails":[{"status":400,"code":"invalid_alias","description":"L’alias non rispetta le regole ASCII del nome.","action":"Usa da 3 a 32 lettere ASCII minuscole, cifre, trattini o trattini bassi; inizia con una lettera e termina con una lettera o cifra.","scope":"endpoint"},{"status":400,"code":"invalid_json","description":"Il corpo non è un oggetto JSON, contiene chiavi duplicate o dati finali.","action":"Invia un solo oggetto JSON valido con `Content-Type` application/json.","scope":"endpoint"},{"status":400,"code":"invalid_name","description":"Un nome contiene caratteri invisibili, controlli di direzione o caratteri di formato non ammessi.","action":"Usa un nome visibile nella forma Unicode ammessa e firma la richiesta corretta.","scope":"endpoint"},{"status":400,"code":"invalid_nonce","description":"Il nonce della richiesta firmata ha un formato errato.","action":"Genera un nuovo nonce da 16 a 128 caratteri usando lettere, cifre, _ o -.","scope":"common"},{"status":400,"code":"invalid_parameter","description":"Un campo del percorso, della query o del corpo manca, è malformato o fuori intervallo.","action":"Correggi il campo indicato in `error.message` prima di inviare di nuovo.","scope":"endpoint"},{"status":400,"code":"invalid_signature_alg","description":"`X-Signature-Alg` non è supportato.","action":"Usa un algoritmo di firma supportato e la codifica corretta per chiave e firma.","scope":"common"},{"status":400,"code":"invalid_timestamp","description":"Il timestamp della richiesta firmata non è espresso in millisecondi Unix.","action":"Usa un timestamp Unix intero in millisecondi e firma la richiesta corretta.","scope":"common"},{"status":400,"code":"wrong_format","description":"La richiesta o la lettura appartiene all’altro formato del registro di questo server: un record v1 su un registro in formato 2, o una lettura del formato 2 su un registro in formato 1.","action":"Leggi `format` in GET /v1/log (assente vuol dire 1) e manda la forma di quel formato.","scope":"endpoint"},{"status":401,"code":"invalid_signature","description":"La firma della richiesta HTTP non è valida.","action":"Firma metodo, percorso e byte del corpo esatti, senza modificarli dopo.","scope":"common"},{"status":401,"code":"missing_signature","description":"La richiesta richiede una firma del dispositivo e le intestazioni mancano o non sono leggibili.","action":"Invia `X-Public-Key`, `X-Signature` e i metadati della richiesta firmata. Una chiave API non sostituisce la firma del dispositivo.","scope":"common"},{"status":401,"code":"stale_timestamp","description":"Il timestamp firmato è fuori dalla finestra temporale ammessa.","action":"Confronta l’intestazione Date del server con il tuo orologio, poi genera nuovi nonce, timestamp e firma.","scope":"common"},{"status":403,"code":"identity_banned","description":"La scheda che agisce è sospesa dallo staff di Veil.","action":"Attendi la fine della restrizione o chiedi allo staff di riesaminarla.","scope":"endpoint"},{"status":403,"code":"key_banned","description":"La chiave del dispositivo che firma è sospesa dallo staff di Veil.","action":"Usa una chiave attiva autorizzata o chiedi allo staff di riesaminare la restrizione.","scope":"common"},{"status":403,"code":"key_mismatch","description":"La chiave di firma non è autorizzata per questa scheda o operazione.","action":"Usa una chiave di dispositivo attiva con il ruolo di titolare o membro richiesto.","scope":"endpoint"},{"status":403,"code":"recovery_key_only","description":"Un’operazione riservata al recupero è stata firmata con un altro ruolo.","action":"Usa la chiave di recupero nel flusso documentato.","scope":"endpoint"},{"status":403,"code":"role_not_allowed","description":"Il ruolo che firma non può eseguire questa modifica.","action":"Usa una chiave con il ruolo richiesto.","scope":"endpoint"},{"status":403,"code":"signer_not_authorised","description":"Il membro dell’organizzazione o il ruolo di firma non può pubblicare questa modifica.","action":"Controlla l’affiliazione accettata e il ruolo richiesto per la modifica.","scope":"endpoint"},{"status":404,"code":"not_found","description":"La scheda, la chiave, l’alias, il codice o la risorsa richiesti non sono stati trovati.","action":"Controlla l’identificatore. Codici e anteprime temporanei potrebbero essere scaduti o già usati.","scope":"endpoint"},{"status":409,"code":"account_locked","description":"La moderazione impedisce di richiedere questo account.","action":"Controlla lo stato pubblico di moderazione della scheda corrente.","scope":"endpoint"},{"status":409,"code":"alias_quarantined","description":"L’alias è nei 30 giorni di quarantena dopo il rilascio.","action":"Leggi `reusableAt` e il titolare precedente tramite l’endpoint degli alias.","scope":"endpoint"},{"status":409,"code":"alias_reserved","description":"L’alias scelto è riservato al servizio.","action":"Scegli un altro alias.","scope":"endpoint"},{"status":409,"code":"alias_taken","description":"L’alias è assegnato oppure riservato da una pubblicazione in corso.","action":"Scegli un altro alias oppure ricontrolla la disponibilità dopo la pubblicazione.","scope":"endpoint"},{"status":409,"code":"already_member","description":"Questa affiliazione esiste già.","action":"Leggi le affiliazioni correnti prima di pubblicare un altro invito.","scope":"endpoint"},{"status":409,"code":"erase_pending","description":"Su un registro in formato 2 la scheda ha una cancellazione in attesa. La sua chiusura firmata nomina la versione corrente, quindi la scheda non pubblica finché la cancellazione non è annullata.","action":"Annulla la cancellazione con POST /v1/identities/{n}/erase/cancel, poi pubblica la versione.","scope":"endpoint"},{"status":409,"code":"grant_used","description":"Un grant di verifica o affiliazione è già stato usato.","action":"Controlla la versione risultante della scheda, poi ottieni un nuovo grant se serve ancora.","scope":"endpoint"},{"status":409,"code":"invitation_withdrawn","description":"L’organizzazione non offre più l’invito.","action":"Chiedi un nuovo invito.","scope":"endpoint"},{"status":409,"code":"key_already_used","description":"Una chiave del dispositivo appartiene già a un’identità e non può essere riusata da un’altra.","action":"Usa la scheda esistente oppure genera una nuova chiave del dispositivo.","scope":"endpoint"},{"status":409,"code":"replayed_nonce","description":"La chiave di firma ha già usato questo nonce.","action":"Controlla se la richiesta precedente è riuscita prima di crearne una nuova firmata.","scope":"common"},{"status":409,"code":"takeover_already_open","description":"Un subentro per questo account collegato è già aperto.","action":"Leggi il subentro in attesa invece di aprirne un altro.","scope":"endpoint"},{"status":409,"code":"version_conflict","description":"La versione non può essere pubblicata rispetto allo stato corrente della scheda.","action":"Leggi la scheda più recente, riconcilia la modifica e firma una nuova versione.","scope":"endpoint"},{"status":410,"code":"erased","description":"La scheda esisteva ed è stata cancellata o rimossa. La risposta contiene anche la ricevuta pubblica di cancellazione.","action":"Smetti di usare questa scheda come autorità corrente. Conserva soltanto la ricevuta pubblica se serve.","scope":"endpoint"},{"status":413,"code":"payload_too_large","description":"Il corpo della richiesta supera il limite in byte dell’endpoint.","action":"Riduci il corpo codificato. La gestione delle chiavi API ammette al massimo 8 KiB.","scope":"endpoint"},{"status":422,"code":"cannot_revoke_self","description":"La revoca della propria chiave lascerebbe la scheda senza una chiave attiva, oppure la chiave di recupero viene revocata senza sostituirla.","action":"Mantieni un’altra chiave attiva. Sostituisci la chiave di recupero nella stessa versione che la revoca.","scope":"endpoint"},{"status":422,"code":"external_limit","description":"La scheda terrebbe più di 16 chiavi pubbliche di altri sistemi, o un’operazione addExternalKey supera 16 KiB in JSON canonico.","action":"Togli prima una chiave. Anche una rimozione nella stessa versione libera un posto.","scope":"endpoint"},{"status":422,"code":"grant_expired","description":"Il grant di verifica o affiliazione è scaduto.","action":"Ottieni un nuovo grant prima di pubblicare la versione.","scope":"endpoint"},{"status":422,"code":"invalid_grant","description":"Il grant di verifica o affiliazione non è valido oppure appartiene a un’altra operazione.","action":"Usa il grant emesso per questa specifica scheda, account o affiliazione.","scope":"endpoint"},{"status":422,"code":"invalid_logo","description":"L’immagine non supera i controlli su tipo, dimensione, risoluzione o contenuto.","action":"Correggi l’immagine secondo `error.message` prima di caricarla di nuovo.","scope":"endpoint"},{"status":422,"code":"invalid_op","description":"Un’operazione è sconosciuta, malformata, non è del tipo o della versione della scheda, oppure non cambia niente.","action":"Correggi l’operazione indicata in `error.message`.","scope":"endpoint"},{"status":422,"code":"invalid_record","description":"La versione dell’identità viola le regole del record firmato.","action":"Correggi il problema di convalida, rendi canonico il record e firmalo di nuovo.","scope":"endpoint"},{"status":422,"code":"invalid_record_signature","description":"La firma della versione dell’identità non è valida.","action":"Firma il record canonico esatto con il prefisso identity-version e la chiave dichiarata.","scope":"endpoint"},{"status":422,"code":"key_expired","description":"La chiave OpenPGP o la sua sottochiave di firma è scaduta.","action":"Prolungane la scadenza sul tuo computer (gpg --quick-set-expire), poi incolla di nuovo la chiave e firma una sfida nuova.","scope":"endpoint"},{"status":422,"code":"key_extra_packets","description":"La chiave OpenPGP porta ancora una foto, la certificazione di un’altra persona o altro materiale che la scheda non tiene.","action":"Aggiungi la chiave dalla pagina della tua scheda, che tiene solo quello che una scheda porta: la chiave, le sue sottochiavi di firma e gli user ID che scegli.","scope":"endpoint"},{"status":422,"code":"key_revoked","description":"La chiave OpenPGP porta una firma di revoca.","action":"Una chiave revocata non va su una scheda. Porta una chiave che usi ancora.","scope":"endpoint"},{"status":422,"code":"key_unsupported","description":"Un tipo di chiave che Veil non tiene: chiavi SSH su chiave di sicurezza (sk-…), ECDSA P-521, certificati SSH, una chiave OpenPGP che non è di versione 4, o un algoritmo OpenPGP diverso da RSA, ECDSA P-256 o P-384 ed Ed25519.","action":"Usa uno dei tipi elencati: ssh-ed25519, ssh-ecdsa-p256, ssh-ecdsa-p384, ssh-rsa, pgp, minisign, ed25519, ml-dsa-44, ml-dsa-65, ml-dsa-87.","scope":"endpoint"},{"status":422,"code":"key_weak","description":"RSA sotto 2048 bit o DSA, in SSH o in OpenPGP, un punto Ed25519 di ordine piccolo, o una firma RSA fatta con SHA-1 (ssh-rsa).","action":"Porta una chiave più forte. ssh-keygen -Y sign firma RSA con rsa-sha2-512 per impostazione predefinita.","scope":"endpoint"},{"status":422,"code":"keys_limit","description":"Su un registro in formato 2 la versione lascerebbe a una persona più di 64 chiavi attive.","action":"Revoca prima una chiave. Anche una revoca nella stessa versione libera un posto.","scope":"endpoint"},{"status":422,"code":"label_mismatch","description":"prev, body, auth o state dell’intestazione non sono quelli che danno la catena, il corpo e le operazioni.","action":"Rileggi la scheda, pianifica le operazioni sul suo stato corrente e firma la nuova intestazione.","scope":"endpoint"},{"status":422,"code":"last_owner","description":"La modifica lascerebbe un’organizzazione senza un proprietario accettato.","action":"Aggiungi o accetta un altro proprietario prima di rimuovere l’ultimo.","scope":"endpoint"},{"status":422,"code":"links_need_verification","description":"Un nuovo collegamento di account non ha un grant di verifica accettabile.","action":"Completa la prova dell’account prima di pubblicarne il collegamento.","scope":"endpoint"},{"status":422,"code":"membership_needs_grant","description":"Un’affiliazione all’organizzazione non ha il grant di accettazione.","action":"Accetta l’invito e includi il grant nella prossima versione firmata.","scope":"endpoint"},{"status":422,"code":"not_a_person","description":"La scheda è un’organizzazione dove è richiesta una persona.","action":"Usa l’endpoint delle organizzazioni oppure la scheda di una persona idonea.","scope":"endpoint"},{"status":422,"code":"private_key_material","description":"Un testo di un’operazione addExternalKey contiene materiale privato: una chiave privata PEM o OpenSSH, un blocco privato PGP o un pacchetto di chiave segreta, una chiave segreta minisign, una chiave segreta Ed25519 di 64 byte, o il seme o la chiave segreta di ML-DSA. Non si salva niente e la risposta non ripete il testo.","action":"Considera quella chiave esposta e sostituiscila. Manda solo la chiave pubblica e la firma della sfida.","scope":"endpoint"},{"status":422,"code":"proof_anchor","description":"Il checkpoint citato non è di questo registro, non ha la firma del registro o il quorum delle controfirme, o la sua radice non è quella del registro a quella taglia.","action":"Cita intera la nota del checkpoint controfirmato come la scheda la dà in index.checkpoint.note.","scope":"endpoint"},{"status":422,"code":"proof_invalid","description":"La sfida nomina un’altra chiave di dispositivo di quella che firma la versione, o la firma non è la firma della chiave sulla sfida di questa scheda. Il messaggio dice la causa: un’altra chiave, un altro namespace SSH, un hash che non vale, la sfida salvata in UTF-16 o con una riga vuota dopo, un altro testo, o una forma diversa da quella che dice proof.variant.","action":"Firma di nuovo i byte esatti della sfida dal browser che pubblica la versione: con namespace veil per SSH, con una firma staccata o in chiaro del file per OpenPGP. Una copia salvata su Windows (CRLF, un BOM UTF-8, senza l’ultimo a capo) vale se proof.variant ne dice la forma.","scope":"endpoint"},{"status":422,"code":"proof_stale","description":"Il checkpoint citato dalla sfida è stato controfirmato più di 7 giorni fa, o l’ora dichiarata at è più vecchia di 7 giorni o avanti rispetto all’orologio del server.","action":"Prepara una sfida nuova dall’ultimo checkpoint della scheda e firmala di nuovo.","scope":"endpoint"},{"status":429,"code":"rate_limited","description":"È stato superato un limite anonimo, delle richieste firmate o della chiave API.","action":"Attendi almeno i secondi indicati da `Retry-After`. Condividi coda e budget dei tentativi tra i tuoi processi.","scope":"common"},{"status":500,"code":"internal_error","description":"Si è verificato un errore imprevisto del server. I dettagli interni non vengono restituiti.","action":"Riprova le letture con attese crescenti e un limite. Controlla l’esito delle scritture prima di inviare una nuova operazione firmata.","scope":"common"},{"status":502,"code":"log_mismatch","description":"La risposta del registro non corrisponde alla voce firmata o alla prova attese.","action":"Non considerare verificata la pubblicazione. Controlla scheda e registro prima di riprovare.","scope":"endpoint"},{"status":503,"code":"busy","description":"L’applicazione ha raggiunto un limite temporaneo di concorrenza o del database.","action":"Attendi i secondi indicati da `Retry-After` e riprova con attese crescenti e un limite.","scope":"common"},{"status":503,"code":"log_unavailable","description":"Al momento il registro pubblico non può essere letto, verificato o usato per pubblicare.","action":"Per le letture, considera il risultato non verificato e riprova più tardi. Prima di ripetere una scrittura, leggi la scheda per controllare se la pubblicazione è terminata.","scope":"endpoint"}],"responseHeaders":[{"name":"Content-Type","value":"application/json","description":"Usa il tipo dichiarato per scegliere come leggere il corpo."},{"name":"Date","value":"HTTP date","description":"Ora del server. Confrontala con il tuo orologio per firmare le richieste."},{"name":"Location","value":"relative URL","description":"Indirizzo della scheda o prova pubblicata, oppure destinazione permanente del widget."},{"name":"Retry-After","value":"integer seconds, on rate_limited or busy","description":"Attendi almeno questo intervallo prima di riprovare. Altri codici 429/503 non lo includono necessariamente."}],"documentationUrl":"https://veil.rip/docs/publish-person?lang=it","supportsBrowserFetch":false,"browserMode":"local-or-server"}}