Skip to content

Accounts and keys

Every app that uses the DEA SDK is registered with DEA, once per platform. Registration gives you two values, which you pass to the SDK together:

Value What it is Secret?
appId Identifies your app. A proof the SDK signs for DEA names it No
appKey Identifies your app to the DEA service. The SDK sends it in the X-App-Key header of every attestation and proof request No

Neither value is a secret. Both ship inside your app or page, where anyone can read them, so they identify your app but do not authorize anything on their own. What makes a request trusted is the proof the device signs with a key DEA registered (see Attest).

Get an appId and appKey

DEA registers apps; there is no self-service sign-up. Ask your DEA contact to register each app and tell them:

Platform What identifies your app
Android The application ID (package name) of the build you ship
iOS The bundle identifier of the build you ship
Web The origins your pages are served from, for example https://www.example.com
Flutter, React Native Both of the above: your Android app and your iOS app are registered as two apps, each with its own pair

You receive an appId and appKey pair for each registered app. For an Android app you also receive a Google Cloud project number, which you pass as playIntegrityProject (see the Android Attest guide).

Use the pair issued for the app the build is: the DEA service files a device key under the app behind X-App-Key, and refuses a proof whose appId belongs to another app.

Pass them to the SDK

Platform appId appKey A production app without appKey
Web init({ appId }) init({ appKey }) Attest fails and Ads proofs are refused on the device, without a request
Flutter DeaOptions(appId:) DeaSdk.init(…, appKey:), the pair of the platform the app runs on Attest answers unsupported, without a request. Proofs are still sent, under DEA's development key
Android DeaConfig(appId = …) DeaConfig(appKey = …) Attest answers UNSUPPORTED and proofs are refused, without a request
iOS DeaSdkOptions(appId:) DeaSdkOptions(appKey:) Attest answers .unsupported, and proofs are signed but not sent, without a request
React Native init({ appId }) init({ appKey }), the pair of the platform the app runs on Attest answers unsupported, without a request

Capture and the classification work the same with or without appKey. When attest() answers as in the last column, check the appKey first: the device is not the cause.

On Flutter, Android and iOS, the appId inside a signed proof comes from a separate option, registryAppId. Set it to the same appId; left unset, proofs carry a development id that DEA refuses. Attest and the classification do not read it; the proof calls on those platforms' Ads pages do.

How the SDK reads an appId

The SDK never sends appId in a header. It reads how the id starts to decide what kind of app it is running in:

appId The SDK runs as What that means
Starts with test_ or sandbox_ A DEA test account It reads DEA's test models, and attestation falls back to a development key when no appKey is given. These accounts are for DEA's own testing: never ship a build with one
Anything else, including an id that starts with stg_ A production app It reads the production models, attestation and proofs need your appKey, and captured input never leaves the device

The appId DEA issues for your app is a production one. On the Web and Android, appId has a default, 'unknown-app', which runs as a production app DEA has not registered: always pass your own.

Attestation and proofs

appId and appKey matter as soon as the SDK talks to DEA:

  • Attest registers the device's signing key with DEA. The registration is filed under the app that X-App-Key names.
  • Proofs, such as the ones the Ads pages attach to impressions and clicks, carry appId inside the signed payload and appKey in the header. The service accepts one only when both name the same app as the device key that signed it.

Reading the classification needs neither: scoring runs on the device and makes no request.