A small toolkit + Claude Code skill for finding the live HTTP/GraphQL API behind an Android app. Three steps:
- Fetch the APK by Play Store package name.
- Decompile with jadx and unzip the asset bundle.
- Scan the output for hostnames, REST/GraphQL paths, required headers, and embedded query strings.
Works for both native Android apps (Retrofit / OkHttp / native Java) and hybrid apps (Capacitor / Cordova / React Native), since the scanner looks at both decompiled Java and the raw asset JS bundles.
A vendor's mobile API and their consumer website often share a backend, but the public docs cover neither and the endpoints drift. When you need to integrate with a service that doesn't publish a stable API, the production Android app is a source of truth — it has to know how to talk to the real backend, in plain text, after decompilation.
This repo turns that into a repeatable workflow under 5 minutes per app.
You need a Java runtime and jadx. On Kali / Debian / Ubuntu:
sudo apt install default-jre-headless jadx ripgrepOn macOS:
brew install jadx ripgrepOn Windows: install jadx and add to PATH, plus Python 3.11+.
No pip dependencies — the scripts are pure stdlib.
# 1. Fetch the APK by Play Store package name (uses APKPure as the mirror)
python scripts/apk_fetch.py com.icemobile.jumboclient
# --> ./jumbo.apk
# 2. Decompile sources + extract raw assets
python scripts/apk_decompile.py jumbo.apk -o jumbo_decompiled
# --> jumbo_decompiled/sources/ (Java)
# --> jumbo_decompiled/assets/ (raw — includes JS bundles for hybrid apps)
# 3. Scan for candidate endpoints
python scripts/apk_scan.py jumbo_decompiled
# --> reports: hostnames, REST paths, GraphQL operations, headers, manifest hintsIf you have access to a phone with the Kali NetHunter chroot, run everything there — apt install jadx is one command.
The repo includes a Claude Code skill at SKILL.md. Symlink (or copy) it to ~/.claude/skills/apk-rev/SKILL.md and Claude will pick it up. After that you can just say:
"find the API behind com.icemobile.jumboclient"
and Claude orchestrates fetch → decompile → scan, then iterates on the candidate endpoints with curl to confirm which ones are live.
| Signal | Where | Why it matters |
|---|---|---|
https://*.<vendor>.* literals |
decompiled Java + JS bundles | Base hostnames the app knows |
/api/*, /v[0-9]+/* paths |
both | REST routes |
query Foo, mutation Foo |
JS bundles | GraphQL operation names + bodies |
@GET, @POST annotations |
decompiled Java | Retrofit interfaces |
Header constants (x-api-key, apollographql-client-name, etc.) |
both | Required headers — vendors often soft-block requests without them |
AndroidManifest.xml network-security-config |
resources | TLS pinning, cleartext allow-lists |
The output is a candidate list — not a working client. The follow-up step is curl against each candidate to confirm liveness and pull the response shape (often the GraphQL server returns a helpful "unknown field X — expected: ..." error that hands you the schema).
This is meant for cases where:
- You want to interact with a service you legitimately use (price comparison, personal data export, accessibility) and the vendor doesn't publish a stable API.
- You're debugging or auditing your own app.
- You're doing CTF / security research / coursework on apps you have permission to analyse.
Reverse-engineering is legal in many jurisdictions for interoperability (EU Software Directive Art. 6, US DMCA §1201(f)) but commercial Terms of Service often forbid it. Don't redistribute decompiled source. Don't use this for harassment, mass scraping, or to bypass paywalls.
See examples/jumbo-supermarkten.md for the full walkthrough that took Jumbo Supermarkten's API from "officially retired, drops connections" to "live GraphQL, schema fully mapped" in about 20 minutes.