SReverseby Simpa Labs

Private APIs

How to get an API from an app that has none

The app has no public API and no documentation, and it still exchanges data with a server. The API specification for that traffic is compiled into the package, so the work is recovering it and proving it works outside the app.

The API specification exists even when the documentation does not

An app that displays data from a server calls that server, and the code that builds each call ships inside the APK. An unpublished API means nobody wrote the API specification down. The host, the paths, the parameters and the values the app computes before sending all exist in the package and can be read from it.

Three places hold most of the answer. The networking library shows the shape of the request code. The classes above it name endpoints and parameters. The configuration and string tables name the server. Read them in that order, because each one narrows what to look for in the next. APK API extraction produces the same result as a finished client when you would rather not run the process yourself.

Identify the networking library first

The library decides what the request-building code looks like and where derived values are assembled.

  • Retrofit declares endpoints in annotations. The service interface carries the path and the verb above each method, so the endpoint list is readable before any dynamic analysis begins, and the converter factory names the serialisation format.
  • OkHttp shows what happens between a call and the socket. Interceptors add headers, sign requests, retry and log, and they are the usual home of authentication logic.
  • Ktor and Volley spread the same work differently. Ktor assembles requests in coroutine code with a configuration block, and Volley places them in request classes with overridden methods.
  • A native library may own the transport. When socket work happens in a shared object, the Java or Kotlin layer only crosses the JNI boundary and the paths may live in the binary.
  • Flutter, React Native and Xamarin keep their logic outside the dex. The network code sits in libapp.so, a JavaScript bundle or managed assemblies, and each needs its own tooling.

Search the decompiled sources for the library package name to establish which case applies. That one result decides the next hour of work.

Find the host and the paths

With the library known, search the package and string tables for a scheme, a host and the first path segment. Base URLs are often assembled from parts, so the full domain may never appear as one string. Look for a build configuration class, a resources entry or a constant that holds a fragment, then follow how the fragments are combined.

Endpoint paths follow the same pattern. Retrofit methods expose them directly. Manual builders pass a path as an argument to a request constructor, which means the string reaches the call site rather than sitting in one place. Trace backwards from the constructor to the caller that supplies the value.

Some apps fetch configuration at startup and use the response to set the base URL for later calls. Treat that first request as part of the API specification and record its response, because the rest of the traffic depends on it.

Establish what the server checks

An endpoint list describes the traffic and does not grant access to it. Replay one request before writing any client code, and read the answer.

  • A signature binds a request to its exact contents. Editing one byte and watching the server refuse tells you that a signature covers the field you changed.
  • Timestamps and nonces enforce freshness. A captured request that succeeds once and fails immediately afterwards carries a value the server accepts only once.
  • Device identifiers tie a token to one installation. A request that works on the phone and fails in a terminal is usually carrying evidence that only that device can produce.
  • Encrypted bodies hide the parameters. When the payload is opaque, the cipher runs in the client and has to be located before a request can be rebuilt.

Each check becomes a separate problem with a bounded answer. Turning an APK into a callable API describes the deliverable that results once they are all satisfied.

Reproduce one call before building a client

Write the smallest script that reproduces a single read-only endpoint, using the same headers, the same body and the same computed values as the app. Success at one endpoint proves the transport, the authentication and the serialisation in one step, and failure at one endpoint is easier to read than failure scattered across a client.

Once one call works, generalise it. Move the base URL and the credentials into configuration, keep signing and encryption in one module, and map the remaining endpoints onto the same pattern. A client built in that order stays readable when the vendor changes something, and it makes the next endpoint a small piece of work.

Reviewed 28 September 2026 · SReverse research desk

Start your full APK reconstruction

Send the full APK

Projects start at $120. Choose WhatsApp or email, then attach the APK in the app that opens. We reply within one hour with the next step and send the fixed quote after review.

Want us to contact you?