What blocks the automation
Play Integrity answers a question for the backend: is this request coming from the genuine app, running on a device that passes Google's checks, with an unmodified binary. The app asks Google Play for an integrity verdict, receives a signed token, and sends that token to its own server. The server verifies the token against Google and reads the verdict before deciding whether to serve the request.
Automation that replays a captured request fails at that step for three structural reasons, and none of them is a header you can copy once.
- The token is short-lived. It is issued for immediate use, so a captured value is stale within minutes. A client that stores one token and reuses it starts failing without any change on its side.
- The token is bound to a nonce and to the request. The app asks for an integrity token with a nonce, and the server checks that the same nonce appears in the token it receives. The binding is what stops an old token from being reused, and it means the client has to be able to request a token as part of the call rather than in advance.
- The verdict is bound to the app identity and the signing certificate. A different package, a debug certificate or a modified APK produces a verdict the server treats as untrusted, so a repackaged build answers that question the wrong way even when the code inside it is correct.
How to tell it apart from a neighbouring failure
Integrity enforcement looks like other 403 responses, and separating it is worth the effort because the alternatives need much less work.
A request that is refused with an integrity-shaped error usually arrives intact: the body parses, the signature check passes, and the server still declines. That combination points at attestation rather than at the payload.
Enforcement is often rolled out gradually, so behaviour can differ by endpoint, by app version and by account. The practical test is to send the same call with the attestation field removed and compare. If the response changes, the field is evaluated. If the response is identical, the backend is either logging the verdict without acting on it or not reading it at all, and the automation can proceed without solving attestation.
Root and emulator checks applied by the app itself are a separate matter. Those run on the device before any request is sent, and they fail on the launch path rather than at the server. A build that refuses to run in an emulator is not the same problem as a server that refuses a request with a bad verdict.
The verdict depends on the device profile
The checks behind a verdict cover several signals at once, and that breadth is why a server stack is hard to imitate. The devices that might host an automation stack, such as rooted handsets, emulators or a server environment, are exactly the profiles these checks are designed to flag.
A verdict also says something about the app itself. It reflects whether the binary matches what Play distributed, whether the account that installed it is licensed for it, and whether the app is the one the token was requested for. A rebuilt or re-signed APK changes the answer even if nothing about the request changed.
For a reconstruction this means the device side cannot be treated as a detail to sort out later. If the backend enforces the verdict, a client that runs in a data centre has to obtain a value it cannot generate there, and the design decision about where the client runs belongs in the scope review rather than in the last day of the project.
What the reconstruction has to account for
Three things have to line up before the call is accepted.
The first is the request binding. The server expects an attestation value tied to this specific call, so the client has to produce it per request rather than reuse one. Where the binding is a nonce issued by the app's server, the client has to fetch and use that nonce in the same order the app does.
The second is the project and package identity. Verification happens against a specific package name, signing certificate and integrity configuration, so those values have to be recovered from the APK and reproduced exactly. A client that presents a valid verdict for a different package fails in a way that looks like an invalid token.
The third is session continuity. A verdict may be checked once when a session starts and then trusted for that session, which changes the shape of the client: it becomes a small number of attested session establishments followed by ordinary signed calls, rather than an attestation on every request. Reading the app's flow tells you which of those patterns the backend uses.
Confirming the problem before scoping the work
Send the request with and without the attestation field and record both responses. Request a fresh value and resend within seconds to rule out staleness. Compare a verdict produced by the real app with the one your client produces, if your client can produce one at all, and read the backend error closely because it often names the field it rejected.
Once enforcement is confirmed, the project is Play Integrity reverse engineering on the attestation path plus the request reconstruction that surrounds it, and it is handled as part of APK to callable API when the whole flow has to be rebuilt. Projects start at $120 and most are delivered in 24 to 72 hours.
Related work
Reviewed 28 September 2026 · SReverse research desk