API de Android Developer Console

La API de Android Developer Console es un servicio RESTful que permite a los desarrolladores verificados automatizar los flujos de trabajo de la verificación de desarrolladores de Android en Android Developer Console, lo que incluye recuperar cuentas de desarrollador, comprobar los requisitos de elegibilidad clave, registrar nombres de paquetes de Android, registrar claves de firma de apps y verificar la propiedad de las claves.

Descripción general, casos de uso y contexto de implementación

Casos de uso y funciones clave

  • Registro automatizado de nombres de paquetes de CI/CD: Registra decenas o cientos de nombres de paquetes de Android de forma programática (CreateAndroidPackage).
  • Inspección previa de la política de claves históricas: Inspecciona de forma programática si Google observó anteriormente un nombre de paquete en el ecosistema y si el registro de un certificado de firma específico requiere la verificación de la propiedad de la clave (GetAndroidPackageRegistrationPolicy).
  • Registro automatizado de la clave de firma de la app y verificación de propiedad: Registra las huellas digitales SHA-256 del certificado de firma público (CreateAndroidPackageKey), recupera tokens de desafío de verificación únicos (verificationToken) y automatiza la prueba de posesión de la clave privada con las cargas de APK firmadas de solicitud única o reanudables (VerifyAndroidPackageKeyOwnership).
  • Envío de justificación programática: Envía justificaciones de propiedad (JustifyAndroidPackageKeyRegistration).
  • Supervisión de estado: Supervisa el estado de registro en las cuentas de desarrollador, los nombres de paquetes y las claves de firma de la app (GetDeveloperAccount, ListDeveloperAccounts, GetAndroidPackage, ListAndroidPackages, GetAndroidPackageKey, ListAndroidPackageKeys).

Flujo de trabajo de implementación de extremo a extremo

  1. Verifica la identidad del desarrollador una vez en la IU: Completa la verificación de identidad del desarrollador (INDIVIDUAL o ORGANIZATION) en Android Developer Console para que verificationState sea VERIFIED.
  2. Habilita la API y autentica: Habilita androiddeveloperconsole.googleapis.com en tu proyecto de Google Cloud y obtén un token de acceso del portador de OAuth 2.0 delegado por el usuario con el permiso https://www.googleapis.com/auth/androiddeveloperconsole.
  3. Descubre el nombre del recurso de tu cuenta de desarrollador: Llama a GET /v1/developerAccounts (ListDeveloperAccounts) para recuperar developerAccounts/{developer_account} y verificar que verificationState sea VERIFIED.
  4. Verifica la política de registro para el nombre del paquete: Llama a GET /v1/developerAccounts/{id}/androidPackages/{pkg}/registrationPolicy (GetAndroidPackageRegistrationPolicy) para inspeccionar keySelectionStrategy (SELECT_KEY_FROM_LIST o USE_ANY_KEY) y cualquier clave de firma histórica conocida (knownKeys).
  5. Crea el recurso del paquete de Android: Llama a POST /v1/developerAccounts/{id}/androidPackages?androidPackageId={pkg} (CreateAndroidPackage) con el cuerpo {"name": ""} (crea el recurso en el estado DRAFT).
  6. Registra la huella digital de la clave de firma de la app: Llama a POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys (CreateAndroidPackageKey) con el cuerpo JSON {"certificateFingerprintSha256": "..."}. Inspecciona el estado que se muestra:
    • DRAFT: Se requiere un comprobante de propiedad de la clave privada, y la respuesta incluye un verificationToken único para el paso 7.
    • IN_REVIEW: La prueba de propiedad y la justificación se omiten automáticamente (por ejemplo, cuando se registra un nombre de paquete nuevo que nunca se vio en Android o cuando ya verificaste la propiedad de esta clave de firma para otro nombre de paquete en el mismo DeveloperAccount). Omite el paso 7 y la llamada de justificación en el paso 8, y continúa directamente con el sondeo de GetAndroidPackage y GetAndroidPackageKey.
  7. Compila y sube el APK de verificación (si el estado es DRAFT): Incorpora la cadena verificationToken que se muestra en assets/adi-registration.properties dentro de un APK mínimo que coincida con packageName, fírmalo con tu clave de firma de la app privada y súbelo con POST /upload/v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:verify (VerifyAndroidPackageKeyOwnership).
  8. Envía la justificación (si es necesario) y sondea el estado del registro: Si la clave está en el estado OWNERSHIP_VERIFIED y registrationJustificationRequired es true, llama a POST /v1/developerAccounts/{id}/androidPackages/{pkg}/keys/{sha256}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration). Sondea GetAndroidPackage y GetAndroidPackageKey hasta que state alcance REGISTERED.

Comandos de la CLI local para preparar huellas digitales de claves y APKs de verificación

  • Extrae la huella digital del certificado SHA-256 de un almacén de claves (keytool):

    keytool -list -v -keystore release-key.jks -alias my-key-alias
  • Verifica el resumen del certificado de firma SHA-256 en un APK compilado (apksigner):

    apksigner verify --print-certs app-release.apk
  • Inspecciona el nombre del paquete del APK y el archivo de token incorporado antes de subirlo (aapt2 y unzip):

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

Funciones de la IU y la API de Android Developer Console

Tarea IU web de Android Developer Console (android.google.com/developerconsole) API de Android Developer Console
Verificación de identidad del desarrollador (KYC/KYB) y pago de la tarifa Compatible (se requiere un requisito previo único) No se admite con la API (verificación de estado de solo lectura con GetDeveloperAccount y ListDeveloperAccounts)
Cómo ver las cuentas de desarrollador vinculadas Selector de cuentas en el encabezado de Console GET /v1/developerAccounts (ListDeveloperAccounts)
Inspecciona las claves de firma históricas y la política de un nombre de paquete Se muestra durante el asistente "Registrar nombre de paquete" GET /v1/.../registrationPolicy (GetAndroidPackageRegistrationPolicy)
Cómo registrar un nuevo nombre de paquete de Android Nombres de paquetes > Registrar nombre de paquete POST /v1/{parent}/androidPackages?androidPackageId=... (CreateAndroidPackage)
Ver o enumerar los nombres de paquetes registrados y en borrador Tabla del panel Nombres de paquete GET /v1/{name} (GetAndroidPackage), GET /v1/{parent}/androidPackages (ListAndroidPackages)
Agrega una clave de firma de la app y genera un token de desafío Detalles del paquete > Agregar clave de firma POST /v1/{parent}/keys (CreateAndroidPackageKey)
Demuestra la propiedad de la clave privada (adi-registration.properties) Sube el APK del fragmento firmado en la IU de la consola POST /upload/v1/{name}:verify (VerifyAndroidPackageKeyOwnership)
Envía una justificación cuando la clave requiera una revisión manual Instrucción de texto durante el flujo de trabajo de registro de claves POST /v1/{name}:justifyAndroidPackageKeyRegistration (JustifyAndroidPackageKeyRegistration)

Configuración y autenticación del servicio

Todas las solicitudes a la API deben usar HTTPS y, además, incluir un encabezado Authorization: Bearer ACCESS_TOKEN obtenido con el flujo del servidor web de OAuth 2.0 para una Cuenta de Google que haya completado la verificación de identidad del desarrollador en Android Developer Console.

Propiedad Valor
Extremo de REST base https://androiddeveloperconsole.googleapis.com
Extremo de carga de contenido multimedia https://androiddeveloperconsole.googleapis.com/upload
Versión de API v1
Permiso de OAuth 2.0 obligatorio https://www.googleapis.com/auth/androiddeveloperconsole
Límite de cuota predeterminado 2,000 solicitudes por día por proyecto de Google Cloud por método

Recursos y extremos de la API

La API de Android Developer Console organiza los recursos en la siguiente jerarquía:

  • 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})

Recurso: DeveloperAccount

Representa una cuenta en Android Developer Console asociada con una identidad de desarrollador.

Campo Tipo Descripción
name string Es el identificador. Es el nombre del recurso en el formato developerAccounts/{developer_account}.
displayName string Solo salida. Es el nombre legible por humanos asociado a la cuenta de desarrollador (nombre individual o de la organización).
verificationState enum (VerificationState) Solo salida. Es el estado actual de la verificación de identidad del desarrollador de la cuenta.

Enum: DeveloperAccount.VerificationState

Valor Descripción
VERIFIED Se completó la verificación de identidad del desarrollador. La cuenta puede registrar nombres de paquetes y claves de firma de la app.
NOT_VERIFIED No se completó la verificación de identidad del desarrollador en Android Developer Console.

Métodos: DeveloperAccount

Método Solicitud HTTP Descripción
GetDeveloperAccount GET /v1/{name=developerAccounts/*} Recupera los metadatos y el estado de verificación de un solo DeveloperAccount.
ListDeveloperAccounts GET /v1/developerAccounts Enumera todos los objetos DeveloperAccount a los que puede acceder la Cuenta de Google autenticada (sin paginación).

Recurso: AndroidPackage

Representa un nombre de paquete de Android registrado o que se está registrando en un DeveloperAccount.

Campo Tipo Descripción
name string Es el identificador. Es el nombre del recurso en el formato developerAccounts/{developer_account}/androidPackages/{android_package}, en el que {android_package} es el nombre del paquete de Android (por ejemplo, com.example.myapp).
packageName string Solo salida. El nombre del paquete de Android (por ejemplo, com.example.myapp)
state enum (AndroidPackage.State) Solo salida. Es el estado actual del ciclo de vida del registro del nombre del paquete.
registeredAppStore boolean Solo salida. Indica si este nombre de paquete está activo como tienda de aplicaciones registrada.

Enum: AndroidPackage.State

Valor Descripción
DRAFT Se creó el recurso del nombre del paquete, y el registro de la clave de firma de la app o la verificación de propiedad aún están en curso.
IN_REVIEW Se envió el registro del nombre del paquete y cualquier justificación de clave requerida, y Google los está revisando. Un paquete pasa de DRAFT a IN_REVIEW inmediatamente después de CreateAndroidPackageKey (cuando se omite la verificación de la propiedad de la clave, incluso cuando la clave ya se verificó para otro nombre de paquete en el mismo DeveloperAccount) o después de completar VerifyAndroidPackageKeyOwnership y, si es necesario, JustifyAndroidPackageKeyRegistration.
REGISTERED El nombre del paquete está registrado activamente en esta cuenta de desarrollador para la verificación de desarrolladores de Android.
PENDING_TRANSFER El nombre de paquete está esperando que se complete la transferencia de propiedad a otra cuenta de desarrollador.

Recurso: AndroidPackageRegistrationPolicy

Es el recurso singleton que muestra GetAndroidPackageRegistrationPolicy y que describe las claves de firma públicas históricas detectadas para un nombre de paquete y si registrar el nombre del paquete con una clave de firma determinada requiere una justificación por escrito.

Campo Tipo Descripción
name string Es el identificador. Es el nombre del recurso en el formato developerAccounts/{developer_account}/androidPackages/{android_package}/registrationPolicy.
knownKeys[] object (KnownKey) Es la lista de claves de firma de la app históricas que se observaron anteriormente distribuyendo apps con este nombre de paquete, ordenadas lexicográficamente por certificateFingerprintSha256.
knownKeys[].certificateFingerprintSha256 string Solo salida. Huella digital SHA-256 hexadecimal en minúsculas de 64 caracteres normalizada del certificado de firma histórico (sin dos puntos).
knownKeys[].justificationRequirement enum (JustificationRequirement) Solo salida. Indica si el registro de esta clave requiere llamar a JustifyAndroidPackageKeyRegistration (REQUIRED o NOT_REQUIRED). Si la clave de firma se verificó anteriormente en otro nombre de paquete con el mismo DeveloperAccount, se omiten VerifyAndroidPackageKeyOwnership y JustifyAndroidPackageKeyRegistration, incluso cuando justificationRequirement es REQUIRED.
keySelectionStrategy enum (KeySelectionStrategy) Solo salida. Política de selección de claves para registrar este nombre de paquete: SELECT_KEY_FROM_LIST (se debe registrar una clave de knownKeys) o USE_ANY_KEY (se puede registrar cualquier clave de firma de la app válida que pertenezca al desarrollador).

Enum: KnownKey.JustificationRequirement

Valor Descripción
REQUIRED Para registrar esta clave conocida, se debe enviar una justificación por escrito con JustifyAndroidPackageKeyRegistration después de completar VerifyAndroidPackageKeyOwnership (a menos que la clave se haya verificado previamente en otro nombre de paquete con el mismo DeveloperAccount, en cuyo caso se omiten VerifyAndroidPackageKeyOwnership y JustifyAndroidPackageKeyRegistration).
NOT_REQUIRED No es necesario que justifiques el registro de esta clave conocida. La clave pasa directamente a IN_REVIEW después de VerifyAndroidPackageKeyOwnership (o inmediatamente después de CreateAndroidPackageKey si la clave se verificó previamente en otro nombre de paquete con el mismo DeveloperAccount).

Enum: AndroidPackageRegistrationPolicy.KeySelectionStrategy

Valor Descripción
SELECT_KEY_FROM_LIST El emisor debe registrar una de las claves históricas que se indican en knownKeys.
USE_ANY_KEY Además de las claves en knownKeys, el emisor puede registrar cualquier clave de firma de la app válida que no se haya observado anteriormente en el ecosistema Android.

Métodos: AndroidPackage

Método Solicitud HTTP Descripción
GetAndroidPackageRegistrationPolicy GET /v1/{name=developerAccounts/*/androidPackages/*/registrationPolicy} Recupera la estrategia de selección de claves y las claves de firma históricas conocidas para un nombre de paquete.
CreateAndroidPackage POST /v1/{parent=developerAccounts/*}/androidPackages?androidPackageId={package_name} Crea un recurso AndroidPackage nuevo en el estado DRAFT para comenzar a registrar un nombre de paquete.
GetAndroidPackage GET /v1/{name=developerAccounts/*/androidPackages/*} Recupera los detalles y el estado de registro actual de un AndroidPackage existente.
ListAndroidPackages GET /v1/{parent=developerAccounts/*}/androidPackages Enumera objetos AndroidPackage en un DeveloperAccount (pageSize máximo 1000, pageToken).

Recurso: AndroidPackageKey

Representa una huella digital del certificado de firma de apps pública asociada con un AndroidPackage y hace un seguimiento de la verificación de propiedad y el estado de revisión del registro.

Campo Tipo Descripción
name string Es el identificador. Es el nombre del recurso asignado por el servidor en el formato developerAccounts/{developer_account}/androidPackages/{android_package}/keys/{key}, en el que {key} es una huella digital SHA-256 hexadecimal en minúsculas de 64 caracteres normalizada sin dos puntos. Se debe omitir o dejar vacío cuando se llama a CreateAndroidPackageKey.
certificateFingerprintSha256 string Obligatorio. Inmutable. Es el hash SHA-256 del certificado de firma de apps. En la entrada en CreateAndroidPackageKey, acepta un formato hexadecimal simple de 64 caracteres (60e860e8...) o un formato hexadecimal separado por dos puntos (60:E8:60:E8:...). En la salida, siempre se normaliza a un formato hexadecimal en minúsculas de 64 caracteres sin dos puntos.
state enum (AndroidPackageKey.State) Solo salida. Es el estado actual del ciclo de vida de verificación y registro de la clave.
verificationToken string Solo salida. Es el token de desafío único que genera Google. Se usa solo cuando el estado es DRAFT (se puede ignorar cuando CreateAndroidPackageKey hace la transición de la clave directamente a IN_REVIEW). Cuando el estado es DRAFT, incorpora esta cadena dentro de assets/adi-registration.properties en un APK firmado para completar VerifyAndroidPackageKeyOwnership.
registrationJustificationRequired boolean Solo salida. Si es true y la clave está en estado OWNERSHIP_VERIFIED, debes enviar una justificación por escrito con JustifyAndroidPackageKeyRegistration antes de que el registro continúe a IN_REVIEW. Si CreateAndroidPackageKey cambia la clave directamente a IN_REVIEW (porque la clave se verificó anteriormente en otro nombre de paquete en el mismo DeveloperAccount), se omite la justificación.

Enum: AndroidPackageKey.State

Valor Descripción
DRAFT Se creó el recurso de clave, y aún se requiere una prueba de posesión de la clave privada mediante la carga del APK firmado (VerifyAndroidPackageKeyOwnership) porque aún no se verificó la propiedad de esta clave en ningún nombre de paquete de este DeveloperAccount.
OWNERSHIP_VERIFIED Se verificó la propiedad de la clave privada con la carga de un APK firmado. Si registrationJustificationRequired es true, se requiere una justificación antes de que comience la revisión.
IN_REVIEW Google está revisando el registro de la clave. Una clave pasa a este estado inmediatamente después de CreateAndroidPackageKey cuando no se requiere una prueba de propiedad (por ejemplo, en un nombre de paquete nuevo que nunca se haya visto en Android o cuando la clave se haya verificado previamente en otro nombre de paquete con el mismo DeveloperAccount, lo que también omite JustifyAndroidPackageKeyRegistration), directamente después de VerifyAndroidPackageKeyOwnership (si registrationJustificationRequired es false) o después de JustifyAndroidPackageKeyRegistration (si registrationJustificationRequired es true).
REGISTERED La clave de firma de la app está registrada activamente con este nombre de paquete para la verificación de desarrolladores de Android.
PENDING_TRANSFER El registro de la clave de firma de la app está esperando que se complete una transferencia.

Métodos: AndroidPackageKey

Método Solicitud HTTP Descripción
CreateAndroidPackageKey POST /v1/{parent=developerAccounts/*/androidPackages/*}/keys Registra una nueva huella digital SHA-256 del certificado de firma de apps en un AndroidPackage. Devuelve la clave en el estado DRAFT (cuando se requiere una prueba de propiedad con VerifyAndroidPackageKeyOwnership) o directamente en el estado IN_REVIEW (cuando se omite la verificación de propiedad, como en el caso de un nombre de paquete nuevo que nunca se haya visto en Android o una clave ya verificada en otro nombre de paquete en el mismo DeveloperAccount).
GetAndroidPackageKey GET /v1/{name=developerAccounts/*/androidPackages/*/keys/*} Recupera el estado, la huella digital y los metadatos de verificación de un AndroidPackageKey específico.
ListAndroidPackageKeys GET /v1/{parent=developerAccounts/*/androidPackages/*}/keys Enumera todos los objetos AndroidPackageKey registrados en un AndroidPackage (pageSize máx. 1000, pageToken).
VerifyAndroidPackageKeyOwnership POST /upload/v1/{name=developerAccounts/*/androidPackages/*/keys/*}:verify Sube un APK mínimo firmado que contenga verificationToken en assets/adi-registration.properties para verificar la propiedad de la clave privada y enviar las claves listas para su revisión.
JustifyAndroidPackageKeyRegistration POST /v1/{name=developerAccounts/*/androidPackages/*/keys/*}:justifyAndroidPackageKeyRegistration Envía contexto de justificación adicional cuando registrationJustificationRequired es true y envía claves verificadas para su revisión.

Manejo de errores

Cuando falla una solicitud a la API, la API de Android Developer Console devuelve un código de estado HTTP 4xx o 5xx y un cuerpo de error JSON google.rpc.Status estándar:

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

Códigos de estado HTTP y resoluciones comunes

Código HTTP Estado de gRPC Causas habituales Solución
400 Bad Request INVALID_ARGUMENT Falta el androidPackageId de estilo Java o no es válido; el formato de certificateFingerprintSha256 no es válido; el campo name no está vacío en CreateAndroidPackage o CreateAndroidPackageKey; el APK subido no está firmado, está dañado, le falta el assets/adi-registration.properties, le falta el verificationToken correspondiente o está firmado con un certificado que no coincide. Valida los formatos de las solicitudes con los esquemas de recursos, omite o vacía name en las llamadas de creación, y verifica la firma de tu APK y el token incorporado con apksigner verify --print-certs y unzip -p app-release.apk assets/adi-registration.properties antes de subirlo.
400 Bad Request FAILED_PRECONDITION DeveloperAccount tiene verificationState: NOT_VERIFIED; la selección de claves infringe AndroidPackageRegistrationPolicy (SELECT_KEY_FROM_LIST); se llama a VerifyAndroidPackageKeyOwnership o JustifyAndroidPackageKeyRegistration en un estado no apto. Completa la verificación de identidad del desarrollador en Android Developer Console, primero verifica GetAndroidPackageRegistrationPolicy y, luego, inspecciona el state actual del recurso.
401 Unauthorized UNAUTHENTICATED Falta el token de acceso del portador de OAuth 2.0, venció o no es válido, o se intentó autenticar con una clave de API o una cuenta de servicio. Obtén un token de acceso de portador de OAuth 2.0 delegado por el usuario nuevo con el permiso https://www.googleapis.com/auth/androiddeveloperconsole.
403 Forbidden PERMISSION_DENIED El usuario autenticado no tiene permiso en el DeveloperAccount o AndroidPackage de destino, o la API de Android Developer Console no está habilitada en el proyecto de Google Cloud. Verifica la membresía de la cuenta con ListDeveloperAccounts y asegúrate de que androiddeveloperconsole.googleapis.com esté habilitado en la consola de Google Cloud.
404 Not Found NOT_FOUND La ruta de acceso del recurso DeveloperAccount, AndroidPackage o AndroidPackageKey especificada no existe. Confirma las rutas de acceso de los recursos con ListDeveloperAccounts, ListAndroidPackages o ListAndroidPackageKeys. Asegúrate de que los IDs de {key} usen valores hexadecimales en minúsculas sin dos puntos.
409 Conflict ALREADY_EXISTS El nombre del paquete o la huella digital del certificado SHA-256 ya están registrados en esta cuenta de desarrollador o en otra. Inspecciona los registros existentes con GetAndroidPackage o GetAndroidPackageKey, o bien verifica la propiedad histórica con GetAndroidPackageRegistrationPolicy.
429 Too Many Requests RESOURCE_EXHAUSTED Se superó la cuota por método de 2,000 solicitudes por día por proyecto de Google Cloud. Implementa la retirada exponencial con fluctuación y evita los bucles de sondeo de alta frecuencia.
500/503 INTERNAL/UNAVAILABLE Error transitorio del backend o falta de disponibilidad temporal del servicio. Vuelve a intentar las solicitudes idempotentes con una retirada exponencial truncada.

Ejemplos de solicitudes y respuestas HTTP

Reemplaza los valores de marcador de posición, como ACCESS_TOKEN, 1234567890, com.example.myapp y 60e860e8..., por tus propios valores.

1. GetDeveloperAccount

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

Respuesta:

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

2. ListDeveloperAccounts

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

Respuesta:

{
  "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"

Respuesta:

{
  "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"

Respuesta:

{
  "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"

Respuesta:

{
  "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"

Respuesta:

{
  "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"

Respuesta:

{
  "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"

Respuesta:

{
  "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"

Respuesta:

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

10. VerifyAndroidPackageKeyOwnership

Opción A: Carga de contenido multimedia de una sola solicitud

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"

Opción B: Protocolo de carga reanudable (recomendado para APKs grandes o CI/CD)

Paso 1: Inicia la sesión de carga reanudable y extrae el encabezado X-Goog-Upload-URL que se muestra:

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"
  }'

Paso 2: Sube el objeto binario del APK firmado a UPLOAD_SESSION_URI y finaliza la sesión:

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"

Respuesta:

{
  "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"

Respuesta:

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

Recursos adicionales