API Android Developer Console

L'API Android Developer Console è un servizio RESTful che consente agli sviluppatori verificati di automatizzare i flussi di lavoro di verifica degli sviluppatori Android in Android Developer Console, tra cui il recupero degli account sviluppatore, il controllo dei requisiti di idoneità delle chiavi, la registrazione dei nomi dei pacchetti Android, la registrazione delle chiavi di firma dell'app e la verifica della proprietà delle chiavi.

Panoramica, casi d'uso e contesto di implementazione

Casi d'uso e funzionalità principali

  • Registrazione automatica dei nomi dei pacchetti CI/CD:registra decine o centinaia di nomi di pacchetti Android in modo programmatico (CreateAndroidPackage).
  • Ispezione pre-flight della policy delle chiavi storiche:controlla in modo programmatico se Google ha già osservato un nome di pacchetto nell'ecosistema e se la registrazione di un certificato di firma specifico richiede la verifica della proprietà della chiave (GetAndroidPackageRegistrationPolicy).
  • Registrazione automatica della chiave di firma dell'app e verifica della proprietà:registra le fingerprint SHA-256 del certificato di firma pubblico (CreateAndroidPackageKey), recupera i token di verifica univoci (verificationToken) e automatizza la prova di possesso della chiave privata utilizzando caricamenti di APK firmati con richiesta singola o ripristinabili (VerifyAndroidPackageKeyOwnership).
  • Invio della motivazione programmatica:invia le motivazioni della proprietà (JustifyAndroidPackageKeyRegistration).
  • Monitoraggio dello stato:monitora lo stato della registrazione negli account sviluppatore, nei nomi dei pacchetti e nelle chiavi di firma dell'app (GetDeveloperAccount, ListDeveloperAccounts, GetAndroidPackage, ListAndroidPackages, GetAndroidPackageKey, ListAndroidPackageKeys).

Workflow di implementazione end-to-end

  1. Verifica l'identità dello sviluppatore una volta nell'UI:completa la verifica dell'identità dello sviluppatore (INDIVIDUAL o ORGANIZATION) in Android Developer Console in modo che verificationState sia VERIFIED.
  2. Abilita l'API ed esegui l'autenticazione: abilita androiddeveloperconsole.googleapis.com nel tuo progetto Google Cloud e ottieni un token di accesso di connessione OAuth 2.0 con delega utente con ambito https://www.googleapis.com/auth/androiddeveloperconsole.
  3. Scopri il nome della risorsa del tuo account sviluppatore:chiama GET /v1/developerAccounts (ListDeveloperAccounts) per recuperare developerAccounts/{developer_account} e verificare che verificationState sia VERIFIED.
  4. Controlla la policy di registrazione per il nome di pacchetto:chiama GET /v1/developerAccounts/{id}/androidPackages/{pkg}/registrationPolicy (GetAndroidPackageRegistrationPolicy) per ispezionare keySelectionStrategy (SELECT_KEY_FROM_LIST o USE_ANY_KEY) ed eventuali chiavi di firma storiche note (knownKeys).
  5. Crea la risorsa del pacchetto Android: chiama POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg} (CreateAndroidPackage) con il corpo {"name": ""} (crea la risorsa nello stato DRAFT).
  6. Registra l'impronta della chiave di firma dell'app:chiama POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys (CreateAndroidPackageKey) con il corpo JSON {"certificateFingerprintSha256": "..."}. Esamina lo stato restituito:
    • DRAFT: è richiesta la prova della proprietà della chiave privata e la risposta include un verificationToken univoco per il passaggio 7.
    • IN_REVIEW: la prova di proprietà e la giustificazione vengono ignorate automaticamente (ad esempio, quando registri un nuovo nome di pacchetto che non è mai stato visto su Android o quando hai già verificato la proprietà di questa chiave di firma per un altro nome di pacchetto nello stesso DeveloperAccount). Salta il passaggio 7 e la chiamata di giustificazione nel passaggio 8 e procedi direttamente al polling di GetAndroidPackage e GetAndroidPackageKey.
  7. Crea e carica l'APK di verifica (se lo stato è DRAFT): incorpora la stringa verificationToken restituita in assets/adi-registration.properties all'interno di un APK minimo corrispondente a packageName, firmalo con la tua chiave di firma dell'app privata e caricalo utilizzando POST /upload/v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:verify (VerifyAndroidPackageKeyOwnership).
  8. Invia la motivazione (se richiesta) ed esegui il polling dello stato di registrazione: se la chiave è nello stato OWNERSHIP_VERIFIED e registrationJustificationRequired è true, chiama POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration). Esegui il polling di GetAndroidPackage e GetAndroidPackageKey finché state non raggiunge REGISTERED.

Comandi dell'interfaccia a riga di comando locale per la preparazione delle fingerprint delle chiavi e degli APK di verifica

  • Estrai il fingerprint del certificato SHA-256 da un archivio chiavi (keytool):

    keytool -list -v -keystore release-key.jks -alias my-key-alias
  • Verifica il digest del certificato di firma SHA-256 su un APK creato (apksigner):

    apksigner verify --print-certs app-release.apk
  • Ispeziona il nome del pacchetto APK e il file del token incorporato prima del caricamento (aapt2 e unzip):

    aapt2 dump badging app-release.apk | head -n 1
    unzip -p app-release.apk assets/adi-registration.properties

Funzionalità dell'interfaccia utente e dell'API di Android Developer Console

Attività UI web di Android Developer Console (android.google.com/developerconsole) API Android Developer Console
Verifica dell'identità dello sviluppatore (KYC/KYB) e pagamento della commissione Supportato (prerequisito una tantum obbligatorio) Non supportato tramite l'API (controllo dello stato di sola lettura tramite GetDeveloperAccount e ListDeveloperAccounts)
Visualizza gli account sviluppatore collegati Selettore dell'account nell'intestazione della console GET /v1/developerAccounts (ListDeveloperAccounts)
Ispeziona le chiavi di firma storiche e la policy per un nome di pacchetto Visualizzato durante la procedura guidata "Registra il nome di pacchetto" GET /v1/.../registrationPolicy (GetAndroidPackageRegistrationPolicy)
Registra un nuovo nome di pacchetto Android Nomi pacchetto > Registra il nome di pacchetto POST /v1/{parent}/androidPackages?androidPackageId=... (CreateAndroidPackage)
Visualizza o elenca i nomi dei pacchetti registrati e in bozza Tabella della dashboard Nomi pacchetto GET /v1/{name} (GetAndroidPackage), GET /v1/{parent}/androidPackages (ListAndroidPackages)
Aggiungi una chiave di firma dell'app e genera un token di verifica Dettagli pacchetto > Aggiungi chiave di firma POST /v1/{parent}/keys (CreateAndroidPackageKey)
Dimostra la proprietà della chiave privata (adi-registration.properties) Carica l'APK dello snippet firmato nell'interfaccia utente della console POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership)
Invia la motivazione quando la chiave richiede una revisione manuale Prompt testuale durante il workflow di registrazione della chiave POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration)

Configurazione e autenticazione del servizio

Tutte le richieste API devono utilizzare HTTPS e includere un'intestazione Authorization: Bearer ACCESS_TOKEN ottenuta utilizzando il flusso del server web OAuth 2.0 per un Account Google che ha completato la verifica dell'identità dello sviluppatore in Android Developer Console.

Proprietà Valore
Endpoint REST di base https://androiddeveloperconsole.googleapis.com
Endpoint di caricamento dei contenuti multimediali https://androiddeveloperconsole.googleapis.com/upload
Versione API v1
Ambito OAuth 2.0 richiesto https://www.googleapis.com/auth/androiddeveloperconsole
Limite di quota predefinito 2,000 richieste al giorno per progetto Google Cloud per metodo

Risorse ed endpoint API

L'API Android Developer Console organizza le risorse nella seguente gerarchia:

  • DeveloperAccount (developerAccounts/{developer_account})
    • AndroidPackage (developerAccounts/{developer_account}/androidPackages/{android_package})
      • AndroidPackageRegistrationPolicy (developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy)
      • AndroidPackageKey (developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key})

Risorsa: DeveloperAccount

Rappresenta un account in Android Developer Console associato a un'identità sviluppatore.

Campo Tipo Descrizione
name string Identificatore. Nome della risorsa nel formato developerAccounts/{developer_account}.
displayName string Solo output. Nome leggibile associato all'account sviluppatore (nome del privato o dell'organizzazione).
verificationState enum (VerificationState) Solo output. Stato attuale della verifica dell'identità dello sviluppatore dell'account.

Enum: DeveloperAccount.VerificationState

Valore Descrizione
VERIFIED La verifica dell'identità dello sviluppatore è stata completata. L'account può registrare i nomi dei pacchetti e le chiavi di firma dell'app.
NOT_VERIFIED La verifica dell'identità dello sviluppatore non è stata completata in Android Developer Console.

Metodi: DeveloperAccount

Metodo Richiesta HTTP Descrizione
GetDeveloperAccount GET /v1/{name=developerAccounts/*} Recupera i metadati e lo stato di verifica per un singolo DeveloperAccount.
ListDeveloperAccounts GET /v1/developerAccounts Elenca tutti gli oggetti DeveloperAccount accessibili all'Account Google autenticato (senza impaginazione).

Risorsa: AndroidPackage

Rappresenta un nome di pacchetto Android registrato o in fase di registrazione in un DeveloperAccount.

Campo Tipo Descrizione
name string Identificatore. Nome della risorsa nel formato developerAccounts/{developer_account}/androidPackages/{android_package}, dove {android_package} è il nome del pacchetto Android (ad esempio com.example.myapp).
packageName string Solo output. Il nome del pacchetto Android (ad esempio, com.example.myapp).
state enum (AndroidPackage.State) Solo output. Stato attuale del ciclo di vita della registrazione del nome del pacchetto.
registeredAppStore boolean Solo output. Indica se questo nome del pacchetto è attualmente attivo come store registrato.

Enum: AndroidPackage.State

Valore Descrizione
DRAFT La risorsa del nome del pacchetto è stata creata e la registrazione della chiave di firma dell'app o la verifica della proprietà sono ancora in corso.
IN_REVIEW La registrazione del nome del pacchetto e l'eventuale motivazione della chiave richiesta sono state inviate e sono in fase di revisione da parte di Google. Un pacchetto passa da DRAFT a IN_REVIEW immediatamente dopo CreateAndroidPackageKey (quando la verifica della proprietà della chiave viene saltata, anche se la chiave è già stata verificata per un altro nome di pacchetto nello stesso DeveloperAccount) o dopo aver completato VerifyAndroidPackageKeyOwnership e, se necessario, JustifyAndroidPackageKeyRegistration.
REGISTERED Il nome del pacchetto è registrato attivamente in questo account sviluppatore per la verifica dello sviluppatore Android.
PENDING_TRANSFER Il nome del pacchetto è in attesa del completamento di un trasferimento di proprietà a un altro account sviluppatore.

Risorsa: AndroidPackageRegistrationPolicy

Risorsa singleton restituita da GetAndroidPackageRegistrationPolicy che descrive le chiavi di firma pubbliche storiche rilevate per un nome di pacchetto e se la registrazione del nome di pacchetto con una determinata chiave di firma richiede una giustificazione scritta.

Campo Tipo Descrizione
name string Identificatore. Nome della risorsa nel formato developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy.
knownKeys[] object (KnownKey) Elenco delle chiavi di firma dell'app storiche precedentemente osservate durante la distribuzione di app con questo nome di pacchetto, ordinate in ordine lessicografico per certificateFingerprintSha256.
knownKeys[].certificateFingerprintSha256 string Solo output. Fingerprint SHA-256 esadecimale in minuscolo normalizzata di 64 caratteri del certificato di firma storico (senza due punti).
knownKeys[].justificationRequirement enum (JustificationRequirement) Solo output. Indica se la registrazione di questa chiave richiede la chiamata di JustifyAndroidPackageKeyRegistration (REQUIRED o NOT_REQUIRED). Se la chiave di firma è stata precedentemente verificata su un altro nome di pacchetto nello stesso DeveloperAccount, sia VerifyAndroidPackageKeyOwnership che JustifyAndroidPackageKeyRegistration vengono ignorati anche quando justificationRequirement è REQUIRED.
keySelectionStrategy enum (KeySelectionStrategy) Solo output. Criterio di selezione della chiave per la registrazione di questo nome pacchetto: SELECT_KEY_FROM_LIST (è necessario registrare una chiave da knownKeys) o USE_ANY_KEY (è possibile registrare qualsiasi chiave di firma dell'app valida di proprietà dello sviluppatore).

Enum: KnownKey.JustificationRequirement

Valore Descrizione
REQUIRED La registrazione di questa chiave nota richiede l'invio di una giustificazione scritta utilizzando JustifyAndroidPackageKeyRegistration dopo aver completato VerifyAndroidPackageKeyOwnership (a meno che la chiave non sia stata precedentemente verificata su un altro nome di pacchetto nello stesso DeveloperAccount, nel qual caso sia VerifyAndroidPackageKeyOwnership sia JustifyAndroidPackageKeyRegistration vengono saltati).
NOT_REQUIRED La registrazione di questa chiave nota non richiede una giustificazione. La chiave passa direttamente a IN_REVIEW dopo VerifyAndroidPackageKeyOwnership (o immediatamente dopo CreateAndroidPackageKey se la chiave è stata precedentemente verificata su un altro nome del pacchetto con lo stesso DeveloperAccount).

Enum: AndroidPackageRegistrationPolicy.KeySelectionStrategy

Valore Descrizione
SELECT_KEY_FROM_LIST Il chiamante deve registrare una delle chiavi storiche elencate in knownKeys.
USE_ANY_KEY Oltre alle chiavi in knownKeys, il chiamante può registrare qualsiasi chiave di firma dell'app valida non osservata in precedenza nell'ecosistema Android.

Metodi: AndroidPackage

Metodo Richiesta HTTP Descrizione
GetAndroidPackageRegistrationPolicy GET /v1/{name=developerAccounts/*/androidPackages/*/registrationPolicy} Recupera la strategia di selezione delle chiavi e le chiavi di firma storiche note per un nome di pacchetto.
CreateAndroidPackage POST /v1/{parent=developerAccounts/*}/androidPackages?androidPackageId={package_name} Crea una nuova risorsa AndroidPackage nello stato DRAFT per iniziare a registrare un nome di pacchetto.
GetAndroidPackage GET /v1/{name=developerAccounts/*/androidPackages/*} Recupera i dettagli e lo stato di registrazione attuale di un AndroidPackage esistente.
ListAndroidPackages GET /v1/{parent=developerAccounts/*}/androidPackages Elenca gli oggetti AndroidPackage in un DeveloperAccount (pageSize max 1000, pageToken).

Risorsa: AndroidPackageKey

Rappresenta un fingerprint del certificato di firma dell'app pubblico associato a un AndroidPackage e monitora lo stato della verifica della proprietà e della revisione della registrazione.

Campo Tipo Descrizione
name string Identificatore. Nome della risorsa assegnato dal server nel formato developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key}, dove {key} è un'impronta SHA-256 esadecimale normalizzata di 64 caratteri minuscoli senza due punti. Deve essere omesso o vuoto quando viene chiamato CreateAndroidPackageKey.
certificateFingerprintSha256 string Obbligatorio. Immutabile. Hash SHA-256 del certificato di firma dell'app. In input in CreateAndroidPackageKey, accetta un valore esadecimale semplice di 64 caratteri (60e860e8...) o un valore esadecimale separato da due punti (60:E8:60:E8:...). In output, viene sempre normalizzato in un valore esadecimale minuscolo di 64 caratteri senza due punti.
state enum (AndroidPackageKey.State) Solo output. Stato attuale del ciclo di vita di verifica e registrazione della chiave.
verificationToken string Solo output. Token di verifica univoco generato da Google. Utilizzato solo quando lo stato è DRAFT (può essere ignorato quando CreateAndroidPackageKey esegue la transizione della chiave direttamente a IN_REVIEW). Quando lo stato è DRAFT, incorpora questa stringa all'interno di assets/adi-registration.properties in un APK firmato per completare VerifyAndroidPackageKeyOwnership.
registrationJustificationRequired boolean Solo output. Se true e la chiave è nello stato OWNERSHIP_VERIFIED, devi inviare una giustificazione scritta utilizzando JustifyAndroidPackageKeyRegistration prima che la registrazione proceda a IN_REVIEW. Se CreateAndroidPackageKey esegue la transizione della chiave direttamente a IN_REVIEW (perché la chiave è stata precedentemente verificata su un altro nome del pacchetto nello stesso DeveloperAccount), la motivazione viene saltata.

Enum: AndroidPackageKey.State

Valore Descrizione
DRAFT La risorsa chiave è stata creata e la dimostrazione del possesso della chiave privata tramite il caricamento dell'APK firmato (VerifyAndroidPackageKeyOwnership) è ancora obbligatoria perché la proprietà di questa chiave non è ancora stata verificata su nessun nome di pacchetto in questo DeveloperAccount.
OWNERSHIP_VERIFIED La proprietà della chiave privata è stata verificata utilizzando un caricamento dell'APK firmato. Se registrationJustificationRequired è true, è comunque necessaria una giustificazione prima dell'inizio della revisione.
IN_REVIEW La registrazione della chiave è in corso di revisione da parte di Google. Una chiave passa qui immediatamente dopo CreateAndroidPackageKey quando non è richiesta la prova di proprietà (ad esempio, su un nuovo nome di pacchetto mai visto su Android o quando la chiave è stata precedentemente verificata su un altro nome di pacchetto con lo stesso DeveloperAccount, che salta anche JustifyAndroidPackageKeyRegistration), direttamente dopo VerifyAndroidPackageKeyOwnership (se registrationJustificationRequired è false) o dopo JustifyAndroidPackageKeyRegistration (se registrationJustificationRequired è true).
REGISTERED La chiave di firma dell'app è registrata attivamente per questo nome pacchetto per la verifica dello sviluppatore Android.
PENDING_TRANSFER La registrazione della chiave di firma dell'app è in attesa del completamento di un trasferimento.

Metodi: AndroidPackageKey

Metodo Richiesta HTTP Descrizione
CreateAndroidPackageKey POST /v1/{parent=developerAccounts/*/androidPackages/*}/keys Registra una nuova fingerprint SHA-256 del certificato di firma dell'app in un AndroidPackage. Restituisce la chiave nello stato DRAFT (quando è richiesta la prova di proprietà utilizzando VerifyAndroidPackageKeyOwnership) o direttamente nello stato IN_REVIEW (quando la verifica della proprietà viene saltata, ad esempio per un nuovo nome di pacchetto mai visto su Android o una chiave già verificata su un altro nome di pacchetto nello stesso DeveloperAccount).
GetAndroidPackageKey GET /v1/{name=developerAccounts/*/androidPackages/*/keys/*} Recupera lo stato, la fingerprint e i metadati di verifica di un AndroidPackageKey specifico.
ListAndroidPackageKeys GET /v1/{parent=developerAccounts/*/androidPackages/*}/keys Elenca tutti gli oggetti AndroidPackageKey registrati in un AndroidPackage (pageSize max 1000, pageToken).
VerifyAndroidPackageKeyOwnership POST /upload/v1/{name=developerAccounts/*/androidPackages/*/keys/*}:verify Carica un APK minimo firmato contenente verificationToken in assets/adi-registration.properties per verificare la proprietà della chiave privata e inviare le chiavi pronte per la revisione.
JustifyAndroidPackageKeyRegistration POST /v1/{name=developerAccounts/*/androidPackages/*/keys/*}:justifyAndroidPackageKeyRegistration Invia un contesto di giustificazione aggiuntivo quando registrationJustificationRequired è true e invia le chiavi verificate per la revisione.

Gestione degli errori

Quando una richiesta API non va a buon fine, l'API Android Developer Console restituisce un codice di stato HTTP 4xx o 5xx e un corpo di errore JSON google.rpc.Status standard:

{
  "error": {
    "code": 400,
    "message": "Invalid certificate fingerprint SHA256 format.",
    "status": "INVALID_ARGUMENT",
    "details": []
  }
}

Codici di stato HTTP e soluzioni comuni

Codice HTTP Stato gRPC Cause comuni Risoluzione
400 Bad Request INVALID_ARGUMENT androidPackageId in stile Java mancante o non valido; formato certificateFingerprintSha256 non valido; campo name non vuoto su CreateAndroidPackage o CreateAndroidPackageKey; l'APK caricato non è firmato, è danneggiato, manca di assets/adi-registration.properties, manca di verificationToken corrispondente o è firmato con un certificato non corrispondente. Convalida i formati delle richieste in base agli schemi delle risorse, ometti o svuota name nelle chiamate di creazione e verifica la firma dell'APK e il token incorporato utilizzando apksigner verify --print-certs e unzip -p app-release.apk assets/adi-registration.properties prima del caricamento.
400 Bad Request FAILED_PRECONDITION DeveloperAccount ha verificationState: NOT_VERIFIED; la selezione della chiave viola AndroidPackageRegistrationPolicy (SELECT_KEY_FROM_LIST); chiamata a VerifyAndroidPackageKeyOwnership o JustifyAndroidPackageKeyRegistration in uno stato non idoneo. Completa la verifica dell'identità dello sviluppatore in Android Developer Console, controlla prima GetAndroidPackageRegistrationPolicy e ispeziona l'attuale state della risorsa.
401 Unauthorized UNAUTHENTICATED Token di accesso Bearer OAuth 2.0 mancante, scaduto o non valido oppure tentativo di autenticazione utilizzando una chiave API o un service account. Ottieni un nuovo token di accesso Bearer OAuth 2.0 delegato dall'utente con ambito https://www.googleapis.com/auth/androiddeveloperconsole.
403 Forbidden PERMISSION_DENIED L'utente autenticato non dispone dell'autorizzazione per DeveloperAccount o AndroidPackage di destinazione oppure l'API Android Developer Console non è abilitata nel progetto Google Cloud. Verifica l'appartenenza all'account utilizzando ListDeveloperAccounts e assicurati che androiddeveloperconsole.googleapis.com sia abilitato nella console Google Cloud.
404 Not Found NOT_FOUND Il percorso della risorsa DeveloperAccount, AndroidPackage o AndroidPackageKey specificato non esiste. Conferma i percorsi delle risorse utilizzando ListDeveloperAccounts, ListAndroidPackages o ListAndroidPackageKeys. Assicurati che gli ID {key} utilizzino valori esadecimali in minuscolo senza due punti.
409 Conflict ALREADY_EXISTS Il nome del pacchetto o la fingerprint del certificato SHA-256 sono già registrati in questo o in un altro account sviluppatore. Esamina le registrazioni esistenti utilizzando GetAndroidPackage o GetAndroidPackageKey oppure controlla la proprietà storica utilizzando GetAndroidPackageRegistrationPolicy.
429 Too Many Requests RESOURCE_EXHAUSTED Quota per metodo di 2,000 richieste al giorno per progetto Google Cloud superata. Implementa il backoff esponenziale con jitter ed evita i loop di polling ad alta frequenza.
500/503 INTERNAL/UNAVAILABLE Errore temporaneo del backend o indisponibilità temporanea del servizio. Riprova le richieste idempotenti con backoff esponenziale troncato.

Esempi di richieste e risposte HTTP

Sostituisci i valori segnaposto come ACCESS_TOKEN, 1234567890, com.example.myapp e 60e860e8... con i tuoi valori.

1. GetDeveloperAccount

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890"

Risposta:

{
  "name": "developerAccounts/1234567890",
  "displayName": "Example Developer",
  "verificationState": "VERIFIED"
}

2. ListDeveloperAccounts

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts"

Risposta:

{
  "developerAccounts": [
    {
      "name": "developerAccounts/1234567890",
      "displayName": "Example Developer",
      "verificationState": "VERIFIED"
    }
  ]
}

3. GetAndroidPackageRegistrationPolicy

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/registrationPolicy"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/registrationPolicy",
  "knownKeys": [
    {
      "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
      "justificationRequirement": "NOT_REQUIRED"
    }
  ],
  "keySelectionStrategy": "SELECT_KEY_FROM_LIST"
}

4. CreateAndroidPackage

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"name": ""}' \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages?androidPackageId=com.example.myapp"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp",
  "packageName": "com.example.myapp",
  "state": "DRAFT",
  "registeredAppStore": false
}

5. GetAndroidPackage

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp",
  "packageName": "com.example.myapp",
  "state": "REGISTERED",
  "registeredAppStore": false
}

6. ListAndroidPackages

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages?pageSize=100"

Risposta:

{
  "androidPackages": [
    {
      "name": "developerAccounts/1234567890/androidPackages/com.example.myapp",
      "packageName": "com.example.myapp",
      "state": "REGISTERED",
      "registeredAppStore": false
    }
  ],
  "nextPageToken": ""
}

7. CreateAndroidPackageKey

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{
    "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123"
  }' \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "DRAFT",
  "verificationToken": "token_xyz987654321"
}

8. GetAndroidPackageKey

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "REGISTERED"
}

9. ListAndroidPackageKeys

curl -X GET \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys?pageSize=100"

Risposta:

{
  "androidPackageKeys": [
    {
      "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
      "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
      "state": "REGISTERED"
    }
  ],
  "nextPageToken": ""
}

10. VerifyAndroidPackageKeyOwnership

Opzione A: caricamento di contenuti multimediali con richiesta singola

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @app-release.apk \
  "https://androiddeveloperconsole.googleapis.com/upload/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123:verify?uploadType=media"

Opzione B: protocollo di caricamento ripristinabile (consigliato per APK di grandi dimensioni o CI/CD)

Passaggio 1: avvia la sessione di caricamento ripristinabile ed estrai l'intestazione X-Goog-Upload-URL restituita:

curl -i -X POST \
  "https://androiddeveloperconsole.googleapis.com/upload/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123:verify" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: FILE_SIZE_IN_BYTES" \
  -H "X-Goog-Upload-Header-Content-Type: application/vnd.android.package-archive" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123"
  }'

Passaggio 2: carica il file binario dell'APK firmato su UPLOAD_SESSION_URI e finalizza la sessione:

curl -X PUT \
  "UPLOAD_SESSION_URI" \
  -H "Content-Length: FILE_SIZE_IN_BYTES" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@app-release.apk"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "IN_REVIEW"
}

11. JustifyAndroidPackageKeyRegistration

curl -X POST \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{
    "justification": "We previously distributed com.example.myapp directly from https://downloads.example.com and are migrating to our rotated production key."
  }' \
  "https://androiddeveloperconsole.googleapis.com/v1/developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123:justifyAndroidPackageKeyRegistration"

Risposta:

{
  "name": "developerAccounts/1234567890/androidPackages/com.example.myapp/keys/60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "certificateFingerprintSha256": "60e860e8d77251234567890abcdef1234567890abcdef1234567890abcdef123",
  "state": "IN_REVIEW",
  "registrationJustificationRequired": true
}

Risorse aggiuntive