HideMyAndroid Headless API

Pilotez HideMyAndroid entièrement depuis ADB ou n'importe quel outil d'automatisation — créez, configurez et activez des profils sans ouvrir l'application. Premium, application 1.2.8+.

Dernière mise à jour: Septembre 2026

Prérequis

La Headless API vous permet de piloter HideMyAndroid entièrement depuis ADB ou n’importe quel outil d’automatisation — sans passer par l’interface de l’application. C’est une fonctionnalité Premium.

  • Compte Premium — la Headless API est réservée aux comptes Premium.
  • Version de l’application 1.2.8 ou ultérieure. Tout ce qui a été ajouté depuis est un champ ou une méthode supplémentaire, donc la 1.2.8 fonctionne toujours — mais les éléments plus récents exigent une version plus récente : hook_spoof_uptime requiert la 1.3.4+, geo et profile.duplicate requièrent la 1.4.5+, tout le groupe sauvegarde / restauration requiert la 1.5.3+, le générateur SIM & appareil (simCountries, deviceTemplate, sim.countries, device.templates) requiert la 1.5.9+, hook_sensor_gyroscope requiert la 1.6.3+, hook_sensor_light requiert la 1.6.4+, et les quatre flags de cohérence des capteurs (hook_sensor_magnetometer, hook_sensor_fused, hook_sensor_pressure, hook_sensor_roster) requièrent la 1.6.9+. Une version plus ancienne ignore un champ qu’elle ne connaît pas et répond quand même ok=true — mais une méthode inconnue se remarque davantage : appeler le groupe sauvegarde / restauration sur une version antérieure à 1.5.3, ou sim.countries / device.templates avant la 1.5.9, renvoie BAD_REQUEST avec l’error_message « Unknown method: … ». Si un réglage semble sans effet, vérifiez la version en cours d’exécution avec status — une version publiée l’indique fidèlement, tandis qu’une version compilée par vos soins avant l’incrément du numéro de version peut contenir une fonctionnalité tout en affichant encore l’ancien numéro.
  • Root + LSPosed — la même configuration que celle dont HideMyAndroid a déjà besoin. Consultez le guide d’installation.
  • ADB connecté à votre appareil (adb devices le liste).
  • Internet sur l’appareil — nécessaire uniquement lorsque vous activez un proxy (il est testé en direct).

⚠️ L’autorisation VPN n’est nécessaire que pour les profils qui utilisent un proxy. Le mode headless ne peut pas afficher la boîte de dialogue système de consentement VPN ; accordez-la donc une fois depuis l’écran Headless API de l’application. Sans elle, activer un profil avec proxy active tout de même le profil — mais le proxy ne se connectera pas et l’appel renvoie INTERNAL en l’indiquant explicitement.

Authentification

Ouvrez Paramètres → Développeur → Headless API dans l’application et activez Activer. Une clé est générée automatiquement — appuyez sur Copier. Chaque requête envoie cette clé dans le paramètre token.

Gardez-la confidentielle — toute personne disposant de la clé et d’un accès ADB peut contrôler vos profils. Régénérer émet une nouvelle clé (l’ancienne cesse de fonctionner) ; la déconnexion l’efface.

Dans toute cette référence, remplacez <your_access_token> par votre clé et <profile_id> par l’id renvoyé par profile.create.

Envoyer des requêtes

Deux transports, choisis selon qu’une valeur contient ou non un deux-points :

Transport À utiliser pour Commande
content call Les lectures, et les valeurs sans : (name, gmails, noms de paquets, simCountries, ids deviceTemplate intégrés)adb shell content call
am broadcast Les objets JSON (hookFlags, proxy, deviceMock, sim) et les ids de modèle custom: — ils contiennent :adb shell am broadcast

content call découpe chaque --extra au niveau du deux-points, il ne peut donc pas transporter de JSON — c’est pourquoi les valeurs JSON passent plutôt par le broadcast.

Seules trois méthodes existent sous forme de broadcast : HEADLESS_UPDATE (profile.update), HEADLESS_SET_ACTIVE et HEADLESS_DEACTIVATE. Les dix-sept autres — status, toutes les lectures (y compris sim.countries et device.templates), profile.create, profile.duplicate, profile.delete, les appels sur les applications cibles et tout le groupe sauvegarde / restauration — sont uniquement en content call. Inutile de chercher un HEADLESS_CREATE — ou un HEADLESS_BACKUP — : il n’en existe pas.

Le broadcast n’est pas réservé au JSON. HEADLESS_UPDATE transmet exactement neuf extras — name, hookFlags, proxy, geo, deviceMock, sim, gmails, et depuis la 1.5.9 simCountries et deviceTemplate — donc name, gmails et simCountries passent par l’un ou l’autre transport. Le tableau ci-dessus indique lequel est le plus pratique, pas lequel est possible. Tout extra dont le nom ne figure pas dans cette liste de neuf est ignoré sans erreur.

Réponses. Un succès renvoie ok=true (content call) ou result=0 (broadcast) ; un échec ajoute error_code et error_message. Voir Codes d’erreur. Chaque méthode prend également token. Cliquez sur une opération ci-dessous pour afficher ses paramètres, sa requête et sa réponse.

Statut

READ status Vérifier que l’API est prête content call

Parameters

No parameters.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method status --extra token:s:<your_access_token>

Response ok=true

Bundle[{data={"premium":true,"featureEnabled":true,"freshnessOk":true,"activeProfileId":"a1b2c3d4-...","version":"1.5.9"}, ok=true}]

Champs : premium, featureEnabled, freshnessOk, activeProfileId (ou null), version. freshnessOk vaut true lorsque l’application a effectué une validation de licence en ligne au cours des dernières 24 heures. La vérification elle-même se fait hors ligne — une requête headless n’accède jamais au réseau, elle lit seulement le résultat enregistré, et premium est lu hors ligne lui aussi. Ouvrez l’application au moins une fois par jour pour que freshnessOk reste à true.

💡 status est la seule méthode qui répond encore lorsque la licence est expirée ou périmée — tout autre appel renvoie LICENSE_EXPIRED ou LICENSE_STALE et rien d’autre. C’est donc le moyen de distinguer les deux lorsqu’une requête est refusée : lisez premium pour savoir si le Premium a réellement expiré, et freshnessOk pour savoir s’il suffit d’ouvrir l’application une fois. status reste soumis à FEATURE_DISABLED et UNAUTHORIZED ; une API désactivée ou un token incorrect se présentent donc ici comme partout ailleurs.

Profils

READ profile.list Lister tous les profils content call

Parameters

No parameters.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.list --extra token:s:<your_access_token>

Response ok=true

Bundle[{data=[{"id":"a1b2...","name":"Demo","isActive":true,"createdAt":1717000000000,"updatedAt":1717000500000}], ok=true}]
READ profile.get Lire un profil en entier content call

Parameters

Name Type Required Description
id string required L’id du profil.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id>

Response ok=true

Bundle[{data={"id":"a1b2...","name":"Demo","isActive":false,"hookFlags":{"hook_wifi":true,...},"proxy":{"enabled":false,...},"geo":{"source":"PROXY",...},"deviceMock":{"enabled":false,...},"sim":{"enabled":false,"simCards":[]},"gmails":[],"targetApps":["com.whatsapp"]}, ok=true}]
CREATE profile.create Créer un profil (renvoie son id) content call

Parameters

Name Type Required Description
name string required Un libellé pour le profil.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.create --extra token:s:<your_access_token> --extra name:s:Demo

Response ok=true

Bundle[{data={"id":"a1b2c3d4-..."}, ok=true}]

Reprenez cet id comme <profile_id> pour les appels suivants.

CREATE profile.duplicate Cloner un profil avec une nouvelle identité content call

Parameters

Name Type Required Description
id string required L’id du profil à copier.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.duplicate --extra token:s:<your_access_token> --extra id:s:<profile_id>

Response ok=true

Bundle[{data={"id":"e5f6a7b8-...","name":"Brave Falcon 42"}, ok=true}]

Le nouvel id et le nom généré sont renvoyés tous les deux — profile.create ne renvoie qu’un id, ne vous attendez donc pas à ce que les deux réponses aient la même forme.

⚠️ Le nom est généré pour vous et ne peut pas être choisi dans l’appel. Renommez la copie avec profile.update juste après si vous voulez le vôtre.

Ce que conserve une copie

Clone un profil comme le fait le menu Dupliquer dans l’application — requiert l’application 1.4.5+. Les réglages sont conservés, mais chaque valeur d’identification est régénérée, si bien que la copie possède sa propre empreinte au lieu d’être la jumelle de l’original. Il n’existe pas de forme broadcast : un broadcast « fire-and-forget » ne pourrait pas vous transmettre le nouvel id, ce qui est tout l’intérêt de l’appel.

Élément Dans la copie
Applications cibles, hookFlags, proxy (y compris sa géolocalisation validée), geo, paquets masqués Conservés à l’identique
Chaque identifiant d’appareil, au niveau du profil et pour chaque application du profil Réémis, de sorte que la copie possède sa propre empreinte au lieu d’être la jumelle de l’original
deviceMock (s’il est activé) Tiré au sort sur un autre modèle d’appareil
sim Même pays, nouveaux numéros
Paquets sauvegardés Non copiés — les sauvegardes sont indexées par {package}-{profileId}, la copie n’en possède donc aucune et démarre vide
Comptes Gmail virtuels Une nouvelle adresse si hook_virtual_accounts était activé sur la source ; une liste vide sinon
Nom Généré et garanti unique, sous la forme Brave Falcon 42 — vous ne pouvez pas le choisir, c’est pourquoi il vous est renvoyé
État actif Toujours isActive: false — dupliquer n’active jamais

Pour obtenir un nom de votre choix, dupliquez d’abord, puis renommez dans un second appel :

bash
# 1. duplicate — the new id and its generated name come back together
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.duplicate --extra token:s:<your_access_token> --extra id:s:<source_profile_id>

# 2. rename the copy — profile.duplicate never takes a name of your own
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<new_profile_id> --extra name:s:"My Profile"
UPDATE profile.update Modifier les réglages d’un profil content call / broadcast

Parameters

Name Type Required Description
id string required L’id du profil.
name string optional Nouveau libellé du profil (content call).
gmails string[] optional Comptes @gmail.com virtuels (content call).
hookFlags object optional Interrupteurs marche/arrêt de l’usurpation (broadcast).
proxy object optional Configuration du proxy (broadcast).
geo object optional Source de localisation — proxy ou personnalisée (broadcast). Requiert l’application 1.4.5+.
deviceMock object optional Usurpation du modèle d’appareil (broadcast).
sim object optional Usurpation SIM / opérateur (broadcast).
simCountries string[] optional Générer les cartes SIM à partir de 1 à 2 codes pays au lieu d’écrire sim à la main (l’un ou l’autre transport). Requiert l’application 1.5.9+ — voir Générateur SIM & appareil.
deviceTemplate string optional Générer deviceMock à partir d’un modèle — random ou un id issu de device.templates (content call ; broadcast pour les ids custom:). Requiert l’application 1.5.9+.

Request

content call — valeurs simples

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra name:s:"My Profile"

broadcast — configurations JSON

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e hookFlags '{"hook_wifi":false,"hook_nearby_bluetooth":false}'

Response ok=true

Les deux formes renvoient le profil complet mis à jour. Voir Configuration pour chaque champ JSON.

⚠️ hookFlags remplace l’ensemble complet — tout flag omis revient à sa valeur par défaut, qui est ON pour chaque flag sauf hook_spoof_uptime, où elle est OFF. Une mise à jour qui omet hook_spoof_uptime le désactive donc sans prévenir. Pour en modifier quelques-uns et conserver les autres, exécutez d’abord profile.get, modifiez la table complète, puis renvoyez-la en entier.

DELETE profile.delete Supprimer définitivement un profil content call

Parameters

Name Type Required Description
id string required L’id du profil.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.delete --extra token:s:<your_access_token> --extra id:s:<profile_id>

Response ok=true

Bundle[{data={}, ok=true}]

⚠️ Supprimer un profil supprime aussi ses sauvegardes de données d’applications sous /sdcard/HideMyAndroid_Backups/ — copiez-les hors de l’appareil au préalable si vous en avez besoin. Et depuis la 1.5.3, profile.delete répond BUSY tant qu’une tâche de sauvegarde / restauration occupe encore le créneau — même une tâche déjà annulée ; réessayez jusqu’à ce que BUSY cesse.

Activation

Un profil n’usurpe qu’une fois actif, et un seul profil est actif à la fois. profile.setActive bascule le profil actif — le profil précédemment actif est désactivé pour vous ; inutile donc d’appeler profile.deactivate au préalable.

⚠️ L’activation efface les données des applications cibles. profile.setActive ne se contente pas de les redémarrer : il force l’arrêt de chaque application cible et efface ses données, afin qu’elle redémarre à neuf et prenne réellement en compte la nouvelle identité. C’est voulu — mais cela signifie que tout ce qui se trouve dans ces applications disparaît, sessions connectées comprises. Dans l’application, la même action vous demande d’abord une confirmation et vous oriente vers la fonction de sauvegarde ; un appel headless n’affiche aucune boîte de dialogue et s’exécute directement, cet avertissement est donc le seul que vous recevrez. En mode headless, le filet de sécurité est backup.start (1.5.3+) avant de basculer. Et depuis la 1.5.3, tant qu’une tâche de sauvegarde / restauration occupe encore le créneau, profile.setActive et profile.deactivate répondent BUSY — même pour une tâche déjà annulée ; réessayez jusqu’à ce que BUSY cesse.

ACTION profile.setActive Activer un profil — démarrer l’usurpation content call / broadcast

Parameters

Name Type Required Description
id string required L’id du profil. Via le broadcast, il est accepté sous la forme id ou profile_id.

Request

content call — recommandé

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.setActive --extra token:s:<your_access_token> --extra id:s:<profile_id>

broadcast — pour l’automatisation

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_SET_ACTIVE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id>

Response ok=true

Bundle[{data={"id":"a1b2...","isActive":true}, ok=true}]
ACTION profile.deactivate Désactiver le profil actif — arrêter l’usurpation content call / broadcast

Parameters

No parameters.

Request

content call — recommandé

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.deactivate --extra token:s:<your_access_token>

broadcast — pour l’automatisation

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_DEACTIVATE -p com.wowsoftware.hidemyandroid -e token <your_access_token>

Response ok=true

Bundle[{data={}, ok=true}]

Aucun id nécessaire — désactive le profil actif, quel qu’il soit.

content call est la forme à privilégier : il est synchrone et affiche le Bundle renvoyé. Les broadcasts HEADLESS_SET_ACTIVE et HEADLESS_DEACTIVATE font le même travail depuis des outils d’automatisation comme Tasker. Ils répondent sous forme de broadcast ordonné, qui renvoie toujours des données : en cas de succès, am broadcast affiche result=0 avec le JSON du résultat dans data="…", et en cas d’échec result=1 avec data="{"error_code":…,"error_message":…}". Ils ne sont donc pas strictement « fire-and-forget » — analysez data= et vous obtenez la même réponse que content call aurait donnée. HEADLESS_SET_ACTIVE prend l’id du profil sous la forme -e id ou -e profile_id ; HEADLESS_DEACTIVATE n’a besoin d’aucun id. Comme toujours, incluez -p com.wowsoftware.hidemyandroid.

Applications cibles

Les applications cibles sont les applications qu’un profil usurpe.

READ profile.getApps Lister les applications cibles d’un profil content call

Parameters

Name Type Required Description
id string required L’id du profil.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.getApps --extra token:s:<your_access_token> --extra id:s:<profile_id>

Response ok=true

Bundle[{data=[{"packageName":"com.whatsapp"}], ok=true}]
CREATE profile.addApp Ajouter une application cible à un profil content call

Parameters

Name Type Required Description
id string required L’id du profil.
packageName string required Le nom de paquet de l’application.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp

Response ok=true · updated app list

Bundle[{data=[{"packageName":"com.whatsapp"}], ok=true}]

⚠️ Ajouter deux fois le même paquet renvoie BAD_REQUEST.

DELETE profile.removeApp Retirer une application cible d’un profil content call

Parameters

Name Type Required Description
id string required L’id du profil.
packageName string required L’application à retirer.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.removeApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp

Response ok=true · updated app list

Bundle[{data=[], ok=true}]

⚠️ Retirer un paquet absent du profil réussit quand même et ne change rien — ce n’est pas une erreur. C’est volontairement différent de addApp, où ajouter un doublon renvoie BAD_REQUEST.

Sauvegarde et restauration

Nouveau dans la 1.5.3, ce groupe copie les données d’applications d’un profil dans des archives sur l’appareil et les réinjecte plus tard — le même travail que Manage Backups dans l’application, sans l’interface. Les six méthodes sont uniquement en content call (pas de forme broadcast), et les deux appels *.start sont asynchrones : ils vous remettent immédiatement un jobId et poursuivent le travail en arrière-plan — interrogez backup.job pour suivre l’avancement. La sauvegarde d’une seule application peut prendre plusieurs minutes.

⚠️ Une tâche à la fois. Un second *.start pendant qu’une tâche tourne renvoie BUSY, avec le jobId en cours dans error_message. Les deux appels *.start exigent également que le profil cible soit actif — sinon REQUIRES_ACTIVE_PROFILE, et il n’existe aucun flag pour passer outre. Les quatre autres méthodes fonctionnent sur n’importe quel profil. Et comme partout dans la Headless API, rien ne demande de confirmation — chaque appel s’exécute directement.

ACTION backup.start Lancer une tâche de sauvegarde pour le profil actif content call

Parameters

Name Type Required Description
id string required L’id du profil — doit être le profil actuellement actif.
packages string optional Noms de paquets à sauvegarder, séparés par des virgules (sans espaces). Omettez-le pour sauvegarder toutes les applications cibles du profil. Chaque paquet doit appartenir au profil.

Request

content call — toutes les applications cibles

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.start --extra token:s:<your_access_token> --extra id:s:<profile_id>

content call — paquets sélectionnés uniquement

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.start --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packages:s:com.twitter.android,com.facebook.katana

Response ok=true · job accepted

Bundle[{data={"jobId":"f0e1d2c3-...","type":"backup","total":2,"packages":["com.twitter.android","com.facebook.katana"],"foregroundHeld":true}, ok=true}]

L’appel rend la main dès que la tâche est acceptée — il n’attend pas la fin de la copie. total indique combien d’applications la tâche va traiter ; interrogez backup.job pour la suivre. Pour ce que foregroundHeld promet (et ne promet pas), voir les remarques ci-dessous.

⚠️ Une sauvegarde ne force jamais l’arrêt de l’application et n’efface jamais ses données. Pour lire un instantané cohérent, elle met brièvement l’application en pause (SIGSTOP) pendant l’archivage de chaque composant, puis la relance (SIGCONT) — l’application continue de tourner et ne perd rien. Sauvegarder un paquet qui possède déjà une sauvegarde remplace l’ancienne archive : une sauvegarde par application et par profil, sans historique.

ACTION restore.start Restaurer les données d’applications sauvegardées dans le profil actif content call

Parameters

Name Type Required Description
id string required L’id du profil — doit être le profil actuellement actif. Une sauvegarde ne se restaure que dans le profil qui l’a créée.
packages string optional Noms de paquets à restaurer, séparés par des virgules (sans espaces). Omettez-le pour restaurer toutes les applications qui ont une sauvegarde dans ce profil — celles qui n’en ont pas sont ignorées sans message. Si vous nommez explicitement des paquets, l’appel échoue immédiatement : une seule sauvegarde manquante fait échouer tout l’appel avec NO_BACKUP et rien n’est restauré.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method restore.start --extra token:s:<your_access_token> --extra id:s:<profile_id>

Response ok=true · job accepted

Bundle[{data={"jobId":"09a8b7c6-...","type":"restore","total":1,"packages":["com.twitter.android"],"foregroundHeld":true}, ok=true}]

Même modèle de tâche que backup.start — la réponse est immédiate et le champ type indique "restore". Interrogez backup.job pour la suivre ; il n’existe pas de restore.job distinct.

⚠️ La restauration force l’arrêt de l’application cible (am force-stop) sans la redémarrer, puis extrait l’archive par-dessus /data/data/<pkg> sans vider le répertoire au préalable — les fichiers créés par l’application après la sauvegarde sont conservés. Et les sauvegardes sont indexées par paquet + profil, c’est pourquoi la restauration entre profils n’existe pas — vous ne pouvez pas réinjecter la sauvegarde d’un profil dans un autre.

READ backup.job Suivre la progression et les résultats d’une tâche content call

Parameters

Name Type Required Description
jobId string optional La tâche à inspecter. Omettez-le pour lire la tâche la plus récente.

Request

content call — une tâche précise

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.job --extra token:s:<your_access_token> --extra jobId:s:<job_id>

content call — la dernière tâche (sans jobId)

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.job --extra token:s:<your_access_token>

Response ok=true

# while it runs
Bundle[{data={"jobId":"f0e1d2c3-...","type":"backup","profileId":"a1b2...","state":"RUNNING","total":2,"done":0,"ok":0,"failed":0,"currentPackage":"com.twitter.android","currentComponent":"Internal Data","progress":0.31,"results":[],"error":null,"foregroundHeld":true,"startedAt":1712345678901,"finishedAt":null}, ok=true}]

# when it finishes — note: DONE even though one app failed
Bundle[{data={"jobId":"f0e1d2c3-...","type":"backup","profileId":"a1b2...","state":"DONE","total":2,"done":2,"ok":1,"failed":1,"currentPackage":null,"currentComponent":null,"progress":1.0,"results":[{"packageName":"com.twitter.android","ok":true,"error":null},{"packageName":"com.facebook.katana","ok":false,"error":"tar exited 2"}],"error":null,"foregroundHeld":true,"startedAt":1712345678901,"finishedAt":1712345699999}, ok=true}]

Une seule méthode sert les deux types de tâche — type indique "backup" ou "restore". state vaut RUNNING, DONE, FAILED ou CANCELLED ; progress va de 0 à 1 sur l’ensemble de la tâche ; startedAt / finishedAt sont en millisecondes epoch et finishedAt reste null tant que la tâche tourne. DONE signifie que la tâche est allée jusqu’au bout — pas que chaque application a réussi — lisez donc toujours failed et results[] (un {packageName, ok, error} par application). currentComponent est un nom d’étape lisible ("Internal Data", "Device Encrypted Data", "External Data", "Media", "OBB", "Permissions", "SSAID") — volontairement différent des chaînes de components[] dans backup.list. Fonctionne sur n’importe quel profil. Seules les cinq tâches les plus récentes sont conservées — un jobId inconnu ou plus ancien renvoie NOT_FOUND, tout comme une interrogation avant qu’aucune tâche n’ait jamais été lancée.

ACTION backup.cancel Annuler une tâche en cours content call

Parameters

Name Type Required Description
jobId string optional La tâche à annuler. Omettez-le pour annuler la tâche la plus récente.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.cancel --extra token:s:<your_access_token> --extra jobId:s:<job_id>

Response ok=true · job snapshot

Renvoie l’instantané de la tâche après annulation — la même forme que celle renvoyée par backup.job.

⚠️ Annuler au milieu d’une application laisse son archive à moitié écrite : l’application n’est pas ajoutée à la liste des sauvegardes et les fichiers restants sont dans un état indéfini. Ne restaurez pas à partir de celle-ci — faites un backup.delete du paquet et sauvegardez-le à nouveau. Par ailleurs, l’instantané passe immédiatement à CANCELLED (avec finishedAt renseigné), mais le tar root sous-jacent ne peut pas être interrompu en cours de fichier et continue de tourner — la tâche peut donc encore occuper le créneau alors que CANCELLED est déjà affiché (voir les remarques ci-dessous).

READ backup.list Lister les sauvegardes stockées d’un profil content call

Parameters

Name Type Required Description
id string required L’id du profil — n’importe quel profil, pas seulement le profil actif.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.list --extra token:s:<your_access_token> --extra id:s:<profile_id>

Response ok=true

Bundle[{data=[{"packageName":"com.twitter.android","appName":"X","timestamp":1712345678901,"totalSize":12345678,"components":["INTERNAL_DATA","EXTERNAL_DATA","OBB"]}], ok=true}]

Une entrée par application sauvegardée. appName est le nom d’affichage relevé au moment de la sauvegarde (lu dans le metadata.json de l’archive, et non déduit du paquet). timestamp est en millisecondes epoch, totalSize en octets, et components[] utilise des noms d’énumération : INTERNAL_DATA, DEVICE_ENCRYPTED, EXTERNAL_DATA, MEDIA, OBB, PERMISSIONS, SSAID.

DELETE backup.delete Supprimer la sauvegarde d’une application dans un profil content call

Parameters

Name Type Required Description
id string required L’id du profil.
packageName string required L’application dont la sauvegarde doit être supprimée.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.delete --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.twitter.android

Response ok=true

Bundle[{data={}, ok=true}]

Synchrone — aucune tâche n’est créée ; le dossier de sauvegarde est supprimé sur-le-champ. Supprimer une sauvegarde inexistante n’est pas une erreur : l’appel est idempotent et renvoie quand même ok=true avec data={}. NOT_FOUND signifie uniquement que l’id du profil n’existe pas ; un packageName mal formé renvoie BAD_REQUEST.

Comportement des tâches

  • DONE ne signifie pas que chaque application a réussi. Cela signifie seulement que la tâche est allée jusqu’au bout. Une application peut échouer alors que la tâche se termine quand même en DONE — lisez toujours failed et results[].
  • L’activation attend désormais les tâches. Tant qu’une tâche occupe le créneau, profile.setActive, profile.deactivate et profile.delete répondent BUSY — même pour une tâche que vous avez déjà annulée, car le tar root sous-jacent ne peut pas être arrêté en cours de fichier, et aucun champ de l’instantané n’indique l’état du créneau. Une tâche qui se termine normalement en DONE ou FAILED libère le créneau presque aussitôt ; après une annulation, ne considérez pas CANCELLED comme « créneau libre » — réessayez simplement l’appel jusqu’à ce que BUSY cesse.
  • foregroundHeld est une observation, pas une promesse. Il indique si un service de premier plan protège la tâche contre l’arrêt par le système. Il a été mesuré à true sur l’API 36, mais même true signifie seulement que le démarrage du service a été accepté — l’étape de promotion ultérieure peut encore échouer silencieusement sur certains appareils. Pour les tâches longues, gardez l’appareil éveillé plutôt que de vous y fier.
  • Emplacement des sauvegardes. /sdcard/HideMyAndroid_Backups/<packageName>-<profileId>/ — un dossier par application et par profil, contenant des archives .tar.gz (data.tar.gz, data_ext.tar.gz, media.tar.gz, …) ainsi que metadata.json, écrites avec le tar root. C’est la clé {package}-{profileId} qui limite la restauration au même profil. Les sauvegardes réalisées en mode headless apparaissent aussi dans l’écran Manage Backups de l’application.

SIM & appareil depuis la base de données intégrée

Nouveau dans la 1.5.9. La section Configuration ci-dessous montre comment écrire à la main un bloc sim ou deviceMock, champ par champ. Ce groupe vous permet de vous en passer : deux clés supplémentaires de profile.update — simCountries et deviceTemplate — font générer le bloc entier par l’application à partir de la même base d’opérateurs et d’appareils que celle utilisée par sa propre interface, et deux méthodes de lecture listent ce qu’elle peut générer. Le résultat est enregistré dans le profil avec enabled:true déjà défini, il n’y a donc rien d’autre à envoyer — relisez-le avec profile.get.

⚠️ Une seule méthode par réglage, par appel. sim et simCountries dans la même requête donnent BAD_REQUEST, tout comme deviceMock avec deviceTemplate. Mélanger entre réglages ne pose aucun problème — simCountries à côté d’un deviceMock écrit à la main, ou les deux générateurs à la fois, comme dans le premier exemple ci-dessous. L’appel est atomique : tout est validé avant que quoi que ce soit ne soit enregistré, donc un id de modèle incorrect fait échouer toute la requête et le simCountries envoyé avec lui n’est pas appliqué non plus.

READ sim.countries Lister les pays connus du générateur SIM content call

Parameters

No parameters.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method sim.countries --extra token:s:<your_access_token>

Response ok=true

Bundle[{data=[{"code":"AF","country":"Afghanistan"},{"code":"AL","country":"Albania"},...,{"code":"GB","country":"United Kingdom"},...,{"code":"US","country":"United States"},...], ok=true}]

Seuls les pays ayant au moins un opérateur dans la base sont listés, triés par nom. code est la valeur ISO 3166-1 alpha-2 en majuscules attendue par simCountries ; country est le nom anglais tel qu’il est stocké ("United Kingdom", "United States").

READ device.templates Lister les modèles d’appareil — intégrés et importés content call

Parameters

No parameters.

Request

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method device.templates --extra token:s:<your_access_token>

Response ok=true

Bundle[{data=[{"id":"asus|ASUS_AI2401|AI2401_A","manufacturer":"asus","label":"ROG Phone 8","isCustom":false},...,{"id":"custom:samsung|e3qxeea|SM-S928B","manufacturer":"samsung","label":"Galaxy S24 Ultra","isCustom":true}], ok=true}]

Une entrée par modèle. id est ce que prend deviceTemplate — brand|product|model, précédé de custom: pour les modèles que vous avez importés dans l’application (isCustom true) ; label est le nom commercial (ROG Phone 8) ; manufacturer est conservé exactement tel que le fabricant l’écrit (asus, samsung, OnePlus), sans normalisation. Voir la remarque sur le transport ci-dessous pour les ids custom:.

UPDATE profile.update Générer des cartes SIM et/ou un appareil depuis la base content call / broadcast

Parameters

Name Type Required Description
id string required L’id du profil.
simCountries string[] optional Tableau JSON de 1 à 2 codes ISO alpha-2, par ex. ["US","GB"] — un par emplacement SIM, dans l’ordre. content call ou broadcast.
deviceTemplate string optional random (ou une chaîne vide) pour un modèle aléatoire, intégré ou importé ; ou un id issu de device.templates. Ids intégrés : content call ou broadcast. Ids custom: : broadcast uniquement.

Request

broadcast — les deux générateurs en un seul appel (tel que testé)

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e simCountries '["US","GB"]' -e deviceTemplate random

content call — simCountries uniquement, emplacement 0 uniquement (les guillemets simples sont obligatoires)

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'simCountries:s:["US"]'

content call — un modèle aléatoire

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra deviceTemplate:s:random

content call — un modèle intégré précis (les guillemets simples sont obligatoires : | est un pipe du shell)

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'deviceTemplate:s:asus|ASUS_AI2401|AI2401_A'

broadcast — un modèle importé (custom:)

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceTemplate 'custom:samsung|e3qxeea|SM-S928B'

Response ok=true · full updated profile

Renvoie le profil complet mis à jour, comme tout profile.update — les sim.simCards et deviceMock générés figurent directement dans la réponse.

⚠️ Chaque appel tire de nouvelles valeurs : répéter le même simCountries donne de nouveaux numéros, et deviceTemplate random peut tomber sur un appareil différent à chaque fois. N’envoyez que la clé que vous voulez régénérer.

simCountries

  • Format. Un tableau JSON de codes ISO 3166-1 alpha-2 — ["US","GB"], insensible à la casse. La position correspond à l’emplacement : le premier code remplit l’emplacement 0, le second l’emplacement 1. Tout ce qui n’est pas un tableau JSON, un tableau vide, une entrée vide, plus de deux entrées, ou un code que sim.countries ne liste pas renvoie BAD_REQUEST — un troisième code est refusé, jamais ignoré en silence comme l’est une troisième carte sim.
  • Ce que vous obtenez. Pour chaque emplacement, l’application choisit un opérateur de ce pays dans sa base et remplit chaque champ du bloc sim écrit à la main : carrierName, countryIso, mcc, mnc, operatorCode, un phoneNumber mobile E.164 valide avec l’indicatif du pays (+1… pour les US), un iccid et un imsi préfixés par le MCC+MNC de cet opérateur, et un networkType tiré au hasard parmi LTE, NR 5G, WCDMA et GSM. Elle définit ensuite sim.enabled à true et enregistre.
  • Il remplace tout le bloc SIM. Comme avec sim, le résultat est normalisé à deux cartes : ["US"] remplit l’emplacement 0 et laisse l’emplacement 1 vide, quel que soit son contenu précédent.

deviceTemplate

  • random (ou une chaîne vide) — l’application tire un modèle parmi tous ceux qu’elle connaît, intégrés comme importés. Notez la différence entre vide et absent : -e deviceTemplate "" signifie aléatoire, tandis qu’omettre complètement la clé laisse l’appareil inchangé.
  • Un id de modèle issu de device.templates — cet appareil, à chaque fois. Les ids intégrés sont de la forme brand|product|model, par ex. asus|ASUS_AI2401|AI2401_A ; les modèles importés dans l’application ont la même forme précédée de custom:, par ex. custom:samsung|e3qxeea|SM-S928B. Un id absent de la liste renvoie BAD_REQUEST.
  • Ce que vous obtenez. Chaque champ de deviceMock rempli à partir du modèle, deviceMock.enabled défini à true, et le profil enregistré.

Quel transport

La règle habituelle du deux-points s’applique. sim.countries, device.templates, simCountries et les ids de modèles intégrés ne contiennent pas de :, donc content call les transporte. Entourez la valeur de guillemets simples dès qu’elle contient |, [, ] ou " — c’est le cas de chaque tableau simCountries et de chaque id de modèle. Sans les guillemets, le shell de l’appareil interprète | comme un pipe et échoue avant même que content ne s’exécute (sh: e3qxeea: not found, code de sortie 127). Un id personnalisé commence par custom:, et ce deux-points supplémentaire casse la forme key:type:value de --extra : l’outil content lui-même le rejette avec [ERROR] Binding not well formed et la requête n’atteint jamais l’application — il n’y a aucun BAD_REQUEST à intercepter. Envoyez les ids personnalisés via le broadcast HEADLESS_UPDATE ; rien d’autre ne change dans l’appel.

Configuration

Voici les valeurs que vous envoyez avec profile.update. Valeurs par défaut à la création d’un profil :

Réglage Par défaut Pour l’utiliser…
hookFlags (all 27) ✅ ON — sauf hook_spoof_uptime ❌ OFF Déjà activés. Envoyez false uniquement pour ceux à désactiver — et true pour hook_spoof_uptime, le seul flag désactivé au départ.
proxy ❌ OFF Incluez "enabled":true
geo PROXY Envoyez "source":"CUSTOM" avec des coordonnées, countryCode et timezone pour définir une localisation sans proxy
deviceMock ❌ OFF Incluez "enabled":true — ou envoyez plutôt deviceTemplate et laissez l’application le remplir (1.5.9+)
sim ❌ OFF Incluez "enabled":true — ou envoyez plutôt simCountries et laissez l’application le remplir (1.5.9+)
gmails empty Envoyez les adresses (comptes virtuels activés par défaut)

⚠️ Une configuration avec enabled:false est enregistrée mais inactive — les valeurs sont conservées pour que vous puissiez l’activer plus tard, mais rien n’est usurpé tant que enabled:true n’est pas défini. geo fait exception : il n’a pas d’interrupteur enabled. Les flags hook_geo_* s’appliquent dès que geo aboutit à une localisation exploitable — soit via source: CUSTOM, soit via un proxy en enabled:true qui a réussi son test en direct.

hookFlags

Par défaut : ON pour chaque flag sauf hook_spoof_uptime, qui est OFF. Une table de "flag": true|false. Une mise à jour remplace toute la table, mais uniquement la table que vous envoyez effectivement : une mise à jour qui omet complètement l’extra hookFlags laisse chaque flag exactement tel qu’il était. Dans une table que vous envoyez, chaque flag omis revient à sa propre valeur par défaut : les 26 autres repassent donc à ON tandis que hook_spoof_uptime repasse à OFF, même si vous l’aviez activé. Pour en modifier quelques-uns et conserver les autres, exécutez d’abord profile.get, modifiez la table complète, puis renvoyez-la en entier.

Flag Effet
hook_hide_dev_opts Masquer les options pour les développeurs
hook_hide_vpn Masquer le VPN
hook_hide_airplane_mode Masquer le mode avion
hook_hide_proxy Masquer le réglage de proxy système
hook_hide_root Masquer le root
hook_hide_lsposed Masquer LSPosed
hook_spoof_installer Usurper la source d’installation
hook_package_info Usurper les informations de paquet / signatures
hook_lan_scan_block Bloquer l’analyse du réseau local
hook_identifiers_partly Usurper les identifiants de base de l’appareil
hook_identifiers_fully Usurper l’ensemble complet des identifiants de l’appareil — inclut tout ce que couvre hook_identifiers_partly
hook_wifi Usurper les détails du réseau Wi-Fi connecté
hook_nearby_wifi Usurper les résultats d’analyse des réseaux Wi-Fi à proximité
hook_nearby_bluetooth Usurper les appareils Bluetooth à proximité
hook_realistic_sensor Utiliser des données de capteurs réalistes
hook_sensor_accelerometer Usurper l’accéléromètre (requiert hook_realistic_sensor)
hook_sensor_gyroscope Usurper le gyroscope (requiert hook_realistic_sensor). Requiert l’application 1.6.3+.
hook_sensor_light Usurper le capteur de luminosité ambiante (requiert hook_realistic_sensor). Requiert l’application 1.6.4+. Le préréglage d’environnement lumineux (Indoor, On the move, Outdoors, Night / dark) ne peut être choisi que dans l’application ; un profil créé via la Headless API démarre sur Indoor, et une mise à jour headless laisse un choix existant inchangé. À partir de l’application 1.6.9, la mesure suit aussi l’heure locale (nuit, crépuscule, jour ; selon le fuseau horaire du profil lorsque l’usurpation du fuseau horaire est activée) et peut chuter fortement lorsque le capteur de proximité signale un objet proche, par ex. téléphone tenu contre l’oreille.
hook_sensor_magnetometer Usurper le magnétomètre (boussole), y compris le capteur non calibré (requiert hook_realistic_sensor). Le champ magnétique est calculé pour les coordonnées usurpées du profil et pivote selon la même orientation de l’appareil que l’accéléromètre et le gyroscope. Sans localisation de profil, un champ plausible propre au profil est utilisé. Appliqué uniquement lorsque hook_sensor_accelerometer est également activé. Requiert l’application 1.6.9+.
hook_sensor_fused Usurper les capteurs de fusion : gravité, accélération linéaire, vecteur de rotation, vecteur de rotation de jeu, vecteur de rotation géomagnétique et orientation, tous dérivés du même mouvement simulé (requiert hook_realistic_sensor). La gravité, l’accélération linéaire et le vecteur de rotation de jeu requièrent hook_sensor_accelerometer et hook_sensor_gyroscope activés ; le vecteur de rotation, le vecteur de rotation géomagnétique et l’orientation requièrent en plus hook_sensor_magnetometer. Requiert l’application 1.6.9+.
hook_sensor_pressure Usurper le baromètre (requiert hook_realistic_sensor). La pression atmosphérique suit l’altitude de la localisation usurpée du profil (la même altitude que renvoie Location.getAltitude()), plus une lente dérive météorologique. Ne prend effet que si le profil dispose d’une géolocalisation (géolocalisation du proxy ou localisation personnalisée) et que hook_geo_gps est activé. Requiert l’application 1.6.9+.
hook_sensor_roster Faire correspondre la liste des capteurs et les métadonnées de chaque capteur (nom, fabricant, plage, résolution, consommation, minDelay) à l’appareil simulé (requiert hook_realistic_sensor). Ne prend effet que lorsque la simulation d’appareil (deviceMock.enabled) est activée. Masque les capteurs que l’appareil simulé n’aurait pas ; n’ajoute jamais de capteurs absents de l’appareil réel. Requiert l’application 1.6.9+.
hook_spoof_uptime Usurper la durée de fonctionnement de l’appareil — donne l’impression que l’appareil tourne depuis plus longtemps. Premium, expérimental. Désactivé par défaut — le seul flag dans ce cas. Requiert l’application 1.3.4+.
hook_virtual_accounts Activer les comptes Google virtuels (gmails nécessite ce flag sur ON)
hook_geo_gps Usurper la position GPS (requiert geo — proxy ou personnalisée)
hook_geo_locale Usurper la langue/région (requiert geo — proxy ou personnalisée)
hook_geo_timezone Usurper le fuseau horaire (requiert geo — proxy ou personnalisée)

proxy

Par défaut : OFF. Avec enabled:true, l’application s’y connecte réellement, lit sa localisation et remplit countryCode/lat/lon/timezone. Le test en direct prend jusqu’à ~8 s ; un proxy qui échoue renvoie PROXY_INVALID et n’est pas enregistré. Ces quatre champs sont des sorties — l’application les écrit, donc tout ce que vous y envoyez est écrasé. Pour définir une localisation à la main, utilisez plutôt geo avec source: CUSTOM ; cela ne nécessite aucun proxy. profile.get renvoie le proxy avec ces quatre champs, mais ne renvoie jamais username ni password.

Champ Type Par défaut Signification / contraintes
host string "" IP / nom d’hôte du proxy
port int 0 Port — 1–65535, vérifié uniquement lorsque vous activez le proxy
protocol string HTTP HTTP, SOCKS4 ou SOCKS5
username string "" Authentification (facultative) — jamais renvoyée par profile.get
password string "" Authentification (facultative) — jamais renvoyée par profile.get
countryCode string "" Sortie — pays sur 2 lettres, rempli par le test en direct
lat double 0 Sortie — rempli par le test en direct
lon double 0 Sortie — rempli par le test en direct
timezone string "" Sortie — nom IANA, rempli par le test en direct
bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}'

geo

Par défaut : {"source":"PROXY"}. Requiert l’application 1.4.5+. C’est d’ici que provient la localisation d’un profil, et il existe deux sources — choisissez-en une avec source. PROXY utilise la localisation lue lors du test en direct du proxy. CUSTOM vous permet de définir vous-même les coordonnées, le fuseau horaire et la région, sans proxy — vous pouvez ainsi placer un profil à Tokyo tout en faisant transiter le trafic n’importe où, ou nulle part. Les trois flags hook_geo_* activent ensuite chaque partie indépendamment : GPS, région + langue, et fuseau horaire.

⚠️ Attention aux noms de champs : geo les écrit latitude/longitude, tandis que proxy ci-dessus utilise les formes courtes lat/lon. Ce sont deux objets distincts, pas des alias — les noms courts dans une charge utile geo sont tout simplement ignorés.

Champ Type Par défaut Signification / contraintes
source string PROXY Obligatoire. Exactement PROXY ou CUSTOM — une valeur absente ou mal orthographiée renvoie BAD_REQUEST, elle n’est jamais interprétée silencieusement comme PROXY
latitude double 0 Obligatoire pour CUSTOM — doit être comprise entre -90 et 90 ; 0/0 compte comme non défini
longitude double 0 Obligatoire pour CUSTOM — doit être comprise entre -180 et 180 ; 0/0 compte comme non défini
countryCode string "" Obligatoire pour CUSTOM — 2 lettres, par ex. JP. Insensible à la casse en entrée, toujours renvoyé en majuscules
timezone string "" Obligatoire pour CUSTOM — nom IANA, par ex. Asia/Tokyo. Seule sa non-vacuité est vérifiée — voir l’avertissement ci-dessous
language string "" Facultatif — code ISO 639-1 à 2 lettres comme ja, et non une balise complète comme ja-JP. Déduit de countryCode s’il est laissé vide, et toujours stocké en minuscules. Seul CUSTOM peut le définir explicitement ; avec PROXY, il est toujours déduit

⚠️ source: CUSTOM doit arriver complet : une paire de coordonnées différente de 0/0 et dans les limites, un countryCode à 2 lettres et un timezone. S’il en manque un seul, l’appel renvoie BAD_REQUEST — il ne se rabat pas sur le proxy. L’application ne fait jamais de géocodage et ne se connecte jamais en ligne pour compléter ces valeurs à votre place. Si aucune source n’est finalement exploitable, aucun hook de géolocalisation n’est chargé et la localisation réelle transparaît.

🛑 timezone est le seul champ qui n’est pas vraiment vérifié. On vérifie seulement qu’il n’est pas vide — jamais par rapport à la base IANA. Une faute de frappe comme Asia/Tokyoo est acceptée, renvoie ok=true, est renvoyée telle quelle par profile.get, puis se résout silencieusement en GMT sur l’appareil. Aucune erreur n’est signalée nulle part, copiez donc le nom exactement. Les coordonnées sont l’inverse — elles sont contrôlées et une valeur hors limites échoue explicitement avec BAD_REQUEST.

CUSTOM — définir une localisation à la main, sans proxy

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}'

PROXY — prendre la localisation du proxy (par défaut)

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"PROXY"}'

deviceMock

Par défaut : OFF. Fait passer l’appareil pour un autre modèle. Définissez "enabled":true ainsi que n’importe lequel de ces champs — tous des chaînes facultatives (vides par défaut), chacune correspondant à une propriété Android Build. À partir de la 1.5.9+, vous pouvez vous passer entièrement de ce bloc et envoyer plutôt deviceTemplate — random tire un appareil de la base de l’application, un id issu de device.templates en choisit un précis — et l’application remplit chaque champ et l’active pour vous.

Champ Correspond à Exemple
manufacturer Build.MANUFACTURER Samsung
brand Build.BRAND samsung
model Build.MODEL SM-S918B
device Build.DEVICE (nom de code) dm3q
product Build.PRODUCT dm3qxxx
board Build.BOARD kalama
hardware Build.HARDWARE qcom
buildId Build.ID UP1A.231005.007
buildIncremental Build.VERSION.INCREMENTAL S918BXXU3CWK9
buildType Build.TYPE user
buildTags Build.TAGS release-keys
buildFingerprint Build.FINGERPRINT samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys
deviceName Nom d’appareil affiché Galaxy S23 Ultra
bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}'

Ou, à partir de la 1.5.9+, laissez l’application tirer un appareil aléatoire de sa base — sans aucun JSON (random puise indifféremment dans les modèles intégrés et importés ; mettez à sa place un id issu de device.templates pour choisir un appareil précis) :

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra deviceTemplate:s:random

sim

Par défaut : OFF. Usurpe la SIM/l’opérateur. Définissez "enabled":true et fournissez jusqu’à deux cartes dans simCards. La liste est toujours normalisée à exactement deux : une troisième carte est ignorée silencieusement — l’appel renvoie quand même ok=true — et une carte unique est complétée par une seconde carte vide, c’est pourquoi profile.get en renvoie toujours deux. À partir de la 1.5.9+, vous pouvez vous passer entièrement de ce bloc et envoyer plutôt simCountries — l’application génère de vraies données d’opérateur pour chaque emplacement et les active pour vous. Chaque carte :

Champ Type Par défaut Signification / contraintes
slotIndex int 0 Emplacement SIM — attribué selon la position de la carte dans le tableau (0, puis 1) ; la valeur envoyée est ignorée
carrierName string "" Nom de l’opérateur (par ex. AT&T)
countryIso string "" Code pays ISO (par ex. us) — stocké en minuscules. Notez que c’est l’inverse de geo.countryCode, stocké en majuscules
mcc string "" Mobile Country Code (par ex. 310)
mnc string "" Mobile Network Code (par ex. 410)
operatorCode string "" Code opérateur = mcc + mnc (par ex. 310410)
phoneNumber string "" Numéro de téléphone
iccid string "" Numéro de série de la SIM (ICCID)
imsi string "" IMSI
networkType string "" Type de réseau — voir les valeurs acceptées ci-dessous ; une valeur non reconnue est ignorée en silence

networkType est débarrassé des espaces superflus et comparé sans tenir compte de la casse, et chaque génération accepte plusieurs graphies :

Valeur Également accepté Génération de réseau
NR 5G NR, 5G 5G
LTE 4G 4G
WCDMA UMTS, 3G 3G
GSM 2G 2G

⚠️ Toute valeur hors de ce tableau désactive silencieusement l’usurpation du type de réseau pour cette carte — aucune erreur, aucun BAD_REQUEST, la valeur est simplement stockée et jamais utilisée. Notez que NR 5G contient une espace : NR5G n’est pas reconnu et tombe précisément dans ce piège silencieux.

bash
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G"}]}'

Ou, à partir de la 1.5.9+, laissez l’application générer les deux cartes à partir de codes pays — sans aucun JSON (l’emplacement 0 reçoit le premier code, l’emplacement 1 le second ; un seul code ne remplit que l’emplacement 0) :

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'simCountries:s:["US","GB"]'

gmails

Par défaut : vide. Une liste de comptes Google virtuels — seules les adresses @gmail.com sont acceptées. La liste remplace la précédente ; [] la vide. Aucun : à l’intérieur, donc content call fonctionne :

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'gmails:s:["[email protected]","[email protected]"]'

Exemple complet

Un profil de zéro jusqu’à l’activation, étape par étape. Les étapes 5, 6 et 7 proposent chacune plusieurs façons d’arriver au même résultat — choisissez-en une par étape ; les onglets permettent de passer de l’une à l’autre. Chaque commande est présentée sous sa forme adb shell. À la fin, les deux recettes condensent toute la séquence en un seul bloc à copier et exécuter, et la section Dépannage propose la même chose sous forme de script à exécuter sur l’appareil.

En un coup d’œil

  1. 01 Vérifier que l’API est prête
  2. 02 Créer le profil
  3. 03 Ajouter les applications cibles
  4. 04 Ajouter des comptes Gmail virtuels
  5. 05 Choisir l’identité de l’appareil
  6. 06 Choisir les cartes SIM
  7. 07 Réseau et localisation
  8. 08 Ajuster les hook flags
  9. 09 Sauvegarder le profil sortant
  10. 10 Activer
  11. 11 Vérifier
  12. 12 Ensuite : cloner, arrêter, supprimer

Espaces réservés utilisés ci-dessous

  • <your_access_token> — la clé issue de Paramètres → Développeur → Headless API
  • <profile_id> — l’id renvoyé par l’étape 2
  • <active_profile_id> / <job_id> — étape 9 uniquement, issus de status et backup.start

Une lecture avant toute chose. Elle vous indique si le Premium, l’interrupteur de la fonctionnalité et la fraîcheur de la licence sont en ordre — les trois conditions dont dépendent tous les autres appels.

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method status --extra token:s:<your_access_token>
# expect  "premium":true, "featureEnabled":true, "freshnessOk":true
# anything else: fix that first — see Status and Error codes above

Tout le reste dépend de l’id renvoyé ici. Un nouveau profil démarre avec chaque hook flag sur ON (sauf hook_spoof_uptime), aucune application cible, et proxy, deviceMock et sim tous sur OFF.

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.create --extra token:s:<your_access_token> --extra name:s:Demo
# → Bundle[{data={"id":"a1b2c3d4-..."}, ok=true}]
# copy that id — it is <profile_id> in every command below

Seules les applications de cette liste sont usurpées. Ajoutez-les une par une par nom de paquet ; toute application non listée continue de voir l’appareil réel.

bash
# one call per app — the package name, not the display name
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.instagram.android

# check the list (adding the same package twice returns BAD_REQUEST)
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.getApps --extra token:s:<your_access_token> --extra id:s:<profile_id>

Les adresses que les applications cibles verront comme des comptes Google connectés. Requiert hook_virtual_accounts, activé par défaut. Sautez cette étape et les applications ne verront aucun compte Google.

bash
# @gmail.com only; the list replaces the previous one, [] clears it
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'gmails:s:["[email protected]","[email protected]"]'

Trois façons d’obtenir le même résultat — un bloc deviceMock avec enabled:true. Laissez l’application tirer un appareil, désignez un modèle, ou écrivez chaque champ vous-même.

bash
# 1.5.9+ — one call, no JSON: the app rolls a device from its database
# (built-in and imported templates alike) and switches deviceMock on for you
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra deviceTemplate:s:random
bash
# 1.5.9+ — first see what is available; "id" is what you send back
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method device.templates --extra token:s:<your_access_token>
# → [{"id":"asus|ASUS_AI2401|AI2401_A","manufacturer":"asus","label":"ROG Phone 8","isCustom":false}, ...]

# built-in id → content call works — single quotes are REQUIRED, | is a shell pipe
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'deviceTemplate:s:asus|ASUS_AI2401|AI2401_A'

# imported (custom:) id → broadcast ONLY; the extra colon breaks content call
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceTemplate 'custom:samsung|e3qxeea|SM-S928B'
bash
# any version — write every Build field yourself; "enabled":true is the switch
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}'

A et B requièrent l’application 1.5.9+ et ne vont jamais dans le même appel que C. Les exécuter l’un après l’autre ne pose pas de problème — le dernier appel l’emporte, et A / B tirent de nouvelles valeurs à chaque exécution.

Même principe pour sim : générez les cartes à partir de codes pays, ou écrivez vous-même les deux cartes. Dans tous les cas, le profil se retrouve avec exactement deux emplacements.

bash
# 1.5.9+ — see which countries the generator knows ("code" is what you send)
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method sim.countries --extra token:s:<your_access_token>
# → [{"code":"AF","country":"Afghanistan"}, ..., {"code":"GB","country":"United Kingdom"}, ..., {"code":"US","country":"United States"}, ...]

# two cards: slot 0 = US, slot 1 = GB — carrier, number, ICCID, IMSI all generated
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'simCountries:s:["US","GB"]'

# or a single card — slot 1 is left empty
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'simCountries:s:["US"]'
bash
# any version — two cards, every field yourself; a third card is dropped silently
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE","phoneNumber":"+12025550123","iccid":"8901410123456789012","imsi":"310410123456789"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G","phoneNumber":"+12025550456","iccid":"8901260987654321098","imsi":"310260987654321"}]}'
bash
# 1.5.9+ — device (step 5) and SIM (step 6) in ONE broadcast: validated together, saved together
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e simCountries '["US","GB"]' -e deviceTemplate random

A et C requièrent l’application 1.5.9+. sim et simCountries dans un même appel donnent BAD_REQUEST. C est atomique — un id de modèle incorrect fait échouer tout l’appel et la SIM n’est pas appliquée non plus.

La destination du trafic et l’endroit où l’appareil prétend se trouver sont deux réglages distincts. proxy achemine le trafic et fournit aussi, par défaut, la localisation ; geo avec source: CUSTOM définit la localisation à la main et ne nécessite aucun proxy. Sautez cette étape et le profil conserve l’IP réelle et la localisation réelle.

bash
# the proxy is tested live (device needs internet, up to ~8s);
# one that fails returns PROXY_INVALID and is not saved
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}'
# with auth: add "username":"…","password":"…" — never echoed back by profile.get

# location follows the proxy by default; this line only matters if geo was CUSTOM before
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"PROXY"}'
bash
# no proxy at all — the location is yours; coordinates, countryCode and timezone are all required
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}'
# timezone is NOT validated: a typo silently becomes GMT — copy the IANA name exactly
bash
# traffic through the proxy, GPS / timezone / locale from your own values —
# a deliberate mismatch (IP in one country, GPS in another); geo.source decides what the hooks use
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}'
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}'

Un profil avec proxy nécessite une fois le consentement VPN système, accordé depuis l’écran Headless API de l’application — sans lui, l’activation réussit quand même, mais le proxy ne se connectera pas et l’appel renvoie INTERNAL.

Tous les flags sauf hook_spoof_uptime sont déjà sur ON, la plupart des profils sautent donc cette étape. Ne la faites que pour désactiver certains hooks, ou pour activer l’usurpation de la durée de fonctionnement. Comme une mise à jour remplace toute la table, lisez-la d’abord et renvoyez-la complète.

bash
# every flag is already ON (except hook_spoof_uptime), so most profiles skip this step.
# an update REPLACES the whole map — read it first, then send it back complete:
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id>

# example: Wi-Fi + Bluetooth spoofing off, uptime spoofing on, everything else at its default
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e hookFlags '{"hook_hide_dev_opts":true,"hook_hide_vpn":true,"hook_hide_airplane_mode":true,"hook_hide_proxy":true,"hook_hide_root":true,"hook_hide_lsposed":true,"hook_spoof_installer":true,"hook_package_info":true,"hook_lan_scan_block":true,"hook_identifiers_partly":true,"hook_identifiers_fully":true,"hook_wifi":false,"hook_nearby_wifi":true,"hook_nearby_bluetooth":false,"hook_realistic_sensor":true,"hook_sensor_accelerometer":true,"hook_sensor_gyroscope":true,"hook_sensor_light":true,"hook_sensor_magnetometer":true,"hook_sensor_fused":true,"hook_sensor_pressure":true,"hook_sensor_roster":true,"hook_spoof_uptime":true,"hook_virtual_accounts":true,"hook_geo_gps":true,"hook_geo_locale":true,"hook_geo_timezone":true}'

Sauvegarder le profil sortant

facultatif application 1.5.3+

Le seul filet de sécurité qui existe : activer le nouveau profil efface les données des applications cibles. Si le profil actif en ce moment contient des sessions ou des données à conserver, sauvegardez-le avant de basculer. Les deux appels *.start ne fonctionnent que sur le profil actif.

bash
# activating wipes the target apps' data — if the CURRENTLY active profile has anything worth keeping, save it first
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method status --extra token:s:<your_access_token>
# → "activeProfileId" is the profile to back up

adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.start --extra token:s:<your_access_token> --extra id:s:<active_profile_id>
# → {"jobId":"f0e1d2c3-...", "type":"backup", ...} — poll until "state" is DONE (or FAILED):
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.job --extra token:s:<your_access_token> --extra jobId:s:<job_id>

# later, once that profile is active again, pour it back:
# adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method restore.start --extra token:s:<your_access_token> --extra id:s:<active_profile_id>

Le moment où l’identité devient effective. Le profil précédemment actif est désactivé pour vous — inutile d’appeler profile.deactivate au préalable.

bash
# force-stops every target app, CLEARS ITS DATA, and brings it back with the new identity.
# no confirmation dialog — this comment is the only warning you get
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.setActive --extra token:s:<your_access_token> --extra id:s:<profile_id>
# → Bundle[{data={"id":"a1b2...","isActive":true}, ok=true}]
# BUSY? a backup / restore job still holds the slot — retry until it stops

Relisez le profil et confirmez ce que les hooks vont utiliser : les blocs générés ou écrits à la main avec enabled:true, le proxy avec le résultat de son test en direct, et geo pointant vers la source choisie.

bash
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id>
# → "isActive":true, "deviceMock":{"enabled":true,...}, "sim":{"enabled":true,"simCards":[...]}, "proxy":{...}, "geo":{...}

adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method status --extra token:s:<your_access_token>
# → "activeProfileId":"<profile_id>"

Le profil est prêt. Voici les appels dont vous aurez besoin ensuite.

bash
# a second identity with the same settings — device re-rolled, SIM numbers regenerated, name generated
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.duplicate --extra token:s:<your_access_token> --extra id:s:<profile_id>

# stop spoofing (no id needed — it deactivates whichever profile is active)
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.deactivate --extra token:s:<your_access_token>

# delete the profile — its backups under /sdcard/HideMyAndroid_Backups/ go with it
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.delete --extra token:s:<your_access_token> --extra id:s:<profile_id>

Deux recettes complètes

Les étapes ci-dessus, chacune condensée en un bloc à copier et exécuter. A est le chemin le plus court sur 1.5.9+ ; B se passe complètement du générateur et du proxy et fonctionne sur 1.4.5+. Dans les deux cas, remplacez <profile_id> après la première commande.

A

Recette A — tout généré

Appareil aléatoire, cartes SIM pour US + GB, trafic et localisation via un proxy. Sept commandes.

bash
# Recipe A — everything generated (app 1.5.9+). The shortest path to a working profile.

# 1. create — copy the returned id into <profile_id> below
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.create --extra token:s:<your_access_token> --extra name:s:Demo

# 2. target app
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp

# 3. virtual Gmail account
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'gmails:s:["[email protected]"]'

# 4. device + SIM in one call — a random device, slot 0 US, slot 1 GB (both enabled and saved)
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e simCountries '["US","GB"]' -e deviceTemplate random

# 5. proxy — tested live (~8s); the location follows it
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}'

# 6. activate — clears the target app's data
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.setActive --extra token:s:<your_access_token> --extra id:s:<profile_id>

# 7. verify
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id>
B

Recette B — tout à la main

Chaque champ Build, chaque champ SIM et la localisation écrits par vous ; ni proxy, ni générateur.

bash
# Recipe B — everything by hand (app 1.4.5+). No generator, no proxy: you control every value.

# 1. create — copy the returned id into <profile_id> below
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.create --extra token:s:<your_access_token> --extra name:s:Demo

# 2. target app
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp

# 3. virtual Gmail accounts
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'gmails:s:["[email protected]","[email protected]"]'

# 4. device — every Build field yourself
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}'

# 5. SIM — two cards, every field yourself
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE","phoneNumber":"+12025550123","iccid":"8901410123456789012","imsi":"310410123456789"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G","phoneNumber":"+12025550456","iccid":"8901260987654321098","imsi":"310260987654321"}]}'

# 6. location — custom, no proxy (all four fields required; timezone is not validated)
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}'

# 7. activate — clears the target app's data
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.setActive --extra token:s:<your_access_token> --extra id:s:<profile_id>

# 8. verify
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id>

Codes d’erreur

En cas d’échec, vous obtenez ok=false avec l’une de ces valeurs d’error_code (les broadcasts renvoient result=1) :

Code Signification Solution
UNAUTHORIZED Token manquant ou incorrect Utilisez votre clé actuelle ; régénérez-la en cas de doute
FEATURE_DISABLED La Headless API est désactivée Activez-la dans Paramètres → Développeur → Headless API
BAD_REQUEST Paramètre ou JSON incorrect Vérifiez les champs obligatoires, la validité du JSON, les adresses gmail uniquement, l’absence d’application en double, des paquets qui appartiennent au profil, un code pays / id de modèle listé par les appels de découverte — et jamais sim avec simCountries ni deviceMock avec deviceTemplate dans un même appel
NOT_FOUND Ce profil, cette tâche ou cette sauvegarde n’existe pas Vérifiez l’id avec profile.list, backup.job ou backup.list
BUSY Une tâche de sauvegarde / restauration occupe encore le créneau error_message indique le jobId en cours — attendez la fin de la tâche, puis réessayez ; après une annulation, le créneau peut rester occupé au-delà de l’état CANCELLED, réessayez donc jusqu’à ce que BUSY cesse. Également renvoyé par profile.setActive / deactivate / delete tant qu’une tâche occupe le créneau
REQUIRES_ACTIVE_PROFILE backup.start / restore.start sur un profil qui n’est pas actif Activez-le d’abord avec profile.setActive — il n’existe aucun flag pour passer outre
NO_BACKUP restore.start n’a trouvé aucune sauvegarde pour une application demandée (ou le profil n’en a aucune) Consultez backup.list ; exécutez d’abord backup.start
PROXY_INVALID Le proxy a échoué au test en direct Vérifiez host/port/protocole/authentification et la connexion internet de l’appareil ; il n’a pas été enregistré
LICENSE_EXPIRED Premium expiré Renouvelez le Premium
LICENSE_STALE Licence non vérifiée en ligne récemment Ouvrez l’application une fois pour la revalider (au moins toutes les 24 h pour une utilisation continue)
INTERNAL Erreur interne (E/S ou root) Réessayez ; vérifiez que root/LSPosed fonctionnent

Conseils & dépannage

  • Un broadcast ne fait rien ? Vérifiez que vous avez inclus -p com.wowsoftware.hidemyandroid — Android bloque les broadcasts sans ce paramètre.
  • Une valeur a été tronquée après un : ? Cette valeur contient un deux-points, donc content call l’a tronquée. Envoyez-la plutôt via le broadcast HEADLESS_UPDATE.
  • Un broadcast JSON ne s’applique pas (souvent sous Windows) ? Entre un shell de bureau et le shell de l’appareil, les guillemets du JSON de am broadcast (hookFlags, proxy, deviceMock, sim) sont facilement supprimés, si bien que am interprète mal la valeur (vous pouvez la voir arriver comme une URI de données dat=…) et rien ne change. La solution fiable consiste à garder le JSON hors de la ligne de commande — placez tout le workflow dans un fichier .sh (les guillemets simples préservent chaque JSON), puis poussez-le et exécutez-le sur l’appareil. Le script s’exécute sur l’appareil, il peut donc même récupérer l’id du nouveau profil et le réutiliser :
    bash
    # setup.sh — Recipe A from the full example as one runnable script (runs on the device)
    URI=content://com.wowsoftware.hidemyandroid.headless
    PKG=com.wowsoftware.hidemyandroid
    K=<your_access_token>
    
    # 1. create a profile and capture its id
    ID=$(content call --uri $URI --method profile.create --extra token:s:$K --extra name:s:Demo | grep -o '"id":"[^"]*"' | head -n1 | sed 's/.*"id":"//;s/"//')
    echo "profile id: $ID"
    
    # 2. add a target app
    content call --uri $URI --method profile.addApp --extra token:s:$K --extra id:s:$ID --extra packageName:s:com.facebook.katana
    
    # 3. add the virtual Gmail accounts
    content call --uri $URI --method profile.update --extra token:s:$K --extra id:s:$ID --extra 'gmails:s:["[email protected]","[email protected]"]'
    
    # 4. device + SIM generated from the database (1.5.9+): random device, slot 0 US, slot 1 GB
    am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e simCountries '["US","GB"]' -e deviceTemplate random
    #    Recipe B alternative (any version) — write both blocks yourself instead:
    # am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}'
    # am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE","phoneNumber":"+12025550123","iccid":"8901410123456789012","imsi":"310410123456789"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G","phoneNumber":"+12025550456","iccid":"8901260987654321098","imsi":"310260987654321"}]}'
    
    # 5. enable + set the proxy (tested live, ~8s) — the location follows it
    am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}'
    #    Or skip the proxy and set the location yourself (use INSTEAD of the proxy line, not after it):
    # am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}'
    
    # 6. activate (restarts the target app and clears its data)
    content call --uri $URI --method profile.setActive --extra token:s:$K --extra id:s:$ID
    
    # 7. verify
    content call --uri $URI --method profile.get --extra token:s:$K --extra id:s:$ID
    puis poussez-le sur l’appareil et exécutez-le :
    bash
    adb push setup.sh /data/local/tmp/setup.sh
    adb shell sh /data/local/tmp/setup.sh
    Les commandes content call simples (sans JSON) peuvent être saisies directement sans script. Dans Git Bash, préfixez les lignes adb par MSYS_NO_PATHCONV=1 pour que le chemin sur l’appareil ne soit pas réécrit.
  • Les modifications n’apparaissent pas ? L’application cible doit redémarrer — activer un profil s’en charge pour vous, et efface les données de cette application dans la même étape, afin qu’elle redémarre avec la nouvelle identité et sans rien conserver de l’état précédent.
  • PROXY_INVALID pour un proxy fiable ? L’appareil a besoin d’internet pour le test, limité à ~8 s ; un proxy lent peut donc dépasser le délai.
  • BUSY pour une tâche déjà annulée ? backup.cancel fait passer la tâche à CANCELLED (et renseigne finishedAt) immédiatement, mais le tar qu’elle a lancé ne peut pas être interrompu et continue de tourner, donc le créneau reste occupé. backup.job affiche CANCELLED alors que le créneau est encore occupé, et aucun champ n’indique l’état du créneau — ne considérez pas CANCELLED comme « créneau libre » ; réessayez simplement profile.setActive / deactivate / delete jusqu’à ce qu’ils cessent de renvoyer BUSY. (Une tâche qui se termine normalement en DONE ou FAILED libère le créneau presque aussitôt.)
  • Binding not well formed pour un id de modèle copié directement depuis device.templates ? Les modèles importés ont des ids qui commencent par custom:, et ce deux-points casse la forme key:type:value de --extra — l’outil content affiche [ERROR] Binding not well formed suivi de son texte d’aide, et la requête n’atteint jamais l’application. Envoyez-le plutôt avec le broadcast HEADLESS_UPDATE (-e deviceTemplate 'custom:…'). Les ids intégrés (brand|product|model) ne contiennent pas de deux-points et fonctionnent avec l’un ou l’autre transport — mais entourez-les de guillemets simples, sinon le shell interprète | comme un pipe (sh: e3qxeea: not found) et rien n’est envoyé.
Télécharger