> ## Documentation Index
> Fetch the complete documentation index at: https://docs.air3.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Launch checklist

> Move an AIR Kit integration from sandbox to production on Moca Chain mainnet: Dashboard setup, SDK settings, backends, credentials, and go-live checks.

Sandbox and production are separate environments. Production runs on Moca Chain mainnet and has its own <a href="https://developers.air3.com/dashboard" target="_blank" rel="noreferrer">Developer Dashboard</a>. Nothing you set up in sandbox carries over: you register your app, keys, issuer, schemas, and programs again, and you switch your code to the production settings.

## What changes in production

| Setting | Sandbox | Production |
| - | - | - |
| Developer Dashboard | [developers.sandbox.air3.com](https://developers.sandbox.air3.com/dashboard) | [developers.air3.com](https://developers.air3.com/dashboard) |
| Web SDK `buildEnv` | `BUILD_ENV.SANDBOX` | `BUILD_ENV.PRODUCTION`, with `credentialNetwork: "mainnet"` |
| Flutter `env` | `Environment.sandbox` | `Environment.production` |
| AIR account domain (passkeys, mobile) | `account.sandbox.air3.com` | `account.air3.com` |
| AIR API base URL (direct issuance) | `https://api.sandbox.mocachain.org/v1` | `https://mocachain-mainnet.api.air3.com/v1` |
| Issuer service `NODE_ENV` | `sandbox` | `production` |
| Moca Chain | Testnet (222888) | Mainnet (2288) |
| Allowed domains | `localhost` ports 3000, 5173, and 8200 are allowed | HTTPS domains only |

Credentials are network-specific. Credentials issued in sandbox do not exist in production. See [Environments](/get-started/environments/about).

## Step 1: Set up your production partner account

1. Sign in to the <a href="https://developers.air3.com/dashboard" target="_blank" rel="noreferrer">production Developer Dashboard</a>.
2. In **Account → General Settings**, copy your production **Partner ID**. Do not assume it matches your sandbox Partner ID.
3. Fill in your app's **Name**, **Logo URL**, and **Website URL**. Users see them during login, transactions, issuance, and verification.
4. Register your production **JWKS URL**. It must be public HTTPS and reachable from AIR servers. See [JWKS endpoint setup](/get-started/authentication/jwks-endpoint).
5. Under **Account → Domains**, add the HTTPS domains that load AIR Kit. You can add up to 3, and wildcards such as `*.myapp.example.com` are supported. `localhost` is not available in production.

For what each setting does, see [Developer Dashboard](/get-started/dashboard/features).

## Step 2: Switch the SDK to production

<Tabs>
  <Tab title="Web">
    ```ts theme={null}
    import { AirService, BUILD_ENV } from "@mocanetwork/airkit";

    const airService = new AirService({
      partnerId: process.env.NEXT_PUBLIC_PARTNER_ID, // production Partner ID
    });

    await airService.init({
      buildEnv: BUILD_ENV.PRODUCTION,
      credentialNetwork: "mainnet",
      enableLogging: false,
    });
    ```

    `credentialNetwork` is only accepted when `buildEnv` is `BUILD_ENV.PRODUCTION`.
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    await airService.initialize(
      partnerId: 'YOUR_PRODUCTION_PARTNER_ID',
      navigatorKey: navigatorKey,
      env: Environment.production,
      enableLogging: false,
    );
    ```

    Keep `account.air3.com` in your Android asset statements and iOS associated domains so passkeys work in production. See [Android setup](/get-started/sdks/flutter/android-setup) and [iOS setup](/get-started/sdks/flutter/ios-setup).
  </Tab>
</Tabs>

Keep sandbox and production values in separate environment configurations, so a production build never ships with a sandbox Partner ID or program ID.

## Step 3: Point your backend at production

Your Partner JWT endpoint signs tokens for the production Partner ID:

* Sign with the private key whose public key is in your production JWKS, and set the `kid` to match.
* Keep tokens short-lived and generate them on the server only. See [SDK authentication](/get-started/authentication/sdk-auth).
* If you call the AIR API directly, for example `initialize-user` and `dstorage/vcs` for direct issuance, use the production base URL.

## Step 4: Set up credentials in production

Skip this step if you use AIR Kit only for login or wallets.

**If you issue credentials:**

1. Deploy your issuer service for production on a domain you control, with a durable database and `NODE_ENV=production`. The reference issuer service uses PostgreSQL. See [Issuer backend hosting](/products/identity/backend-hosting).
2. Register the issuer in **Issuer → Settings** on the production Dashboard: the `did:web` Issuer DID, the issuer API key, the JWKS URL, and the endpoint URLs.
3. Recreate your schemas and issuance programs in the production Dashboard, and update the program IDs in your app.
4. Decide your revocation setup, including whether to enable the [token status list](/products/identity/revocation#token-status-list), before you issue the first production credential.
5. If you issue [Iden3 credentials](/products/identity/iden3-credentials), contact the AIR team to enable them in production.

The issuer host becomes your issuer identity once you issue on mainnet, so do not change it afterwards.

**If you verify credentials:**

1. Recreate your verification programs in the production Dashboard and update the program IDs in your app.
2. Constrain each program to the production Issuer DIDs you trust.
3. Verify every presentation on your backend, with a fresh nonce per verification. See [Verify SD-JWT on your backend](/products/identity/verify-sd-jwt).

## Step 5: Set up accounts and gas

Skip this step if you do not use smart accounts.

* Contact the AIR team to set up gas sponsorship policies and the chains in your partner configuration. See [Paymaster](/products/money/paymaster).
* If your app or users pay gas on Moca Chain, see [How to get \$MOCA](/technicals/mocachain/how-to-get-moca).
* If you use [session keys](/products/money/session-keys), scope them to the smallest set of actions and give them short expiry times.

## Step 6: Test on production before launch

Run your main flows end to end with a real test account on production:

* Log in and log out, including on each mobile platform you ship.
* Issue a credential, verify it, revoke it, and confirm that verification then fails.
* Send a transaction from the smart account, if you use one.
* Check that a request from a domain that is not on your allowed list is refused.

## Go-live checklist

**Dashboard and keys**

* [ ] Signed in to the production Developer Dashboard, and copied the production Partner ID
* [ ] App name, logo URL, and website URL set
* [ ] Production JWKS URL is public HTTPS and registered
* [ ] Partner JWTs are signed server-side with a key whose `kid` is in that JWKS, and expire within 5 minutes
* [ ] Allowed domains list only your HTTPS production domains
* [ ] Private keys and API keys are stored in a secrets manager, not in source control or client code

**SDK and apps**

* [ ] Web apps initialize with `BUILD_ENV.PRODUCTION` and `credentialNetwork: "mainnet"`
* [ ] Flutter apps initialize with `Environment.production`
* [ ] Mobile apps include `account.air3.com` in their associated domains and asset statements
* [ ] No sandbox Partner ID, program ID, or URL remains in the production build
* [ ] Logging is off or reduced for production

**Issuing credentials** (if you issue)

* [ ] Issuer service deployed on a domain you control, with `NODE_ENV=production`
* [ ] The issuer database is durable and its migrations are applied
* [ ] `did:web` Issuer DID, issuer API key, JWKS URL, and endpoint URLs registered in the production Dashboard
* [ ] Schemas and issuance programs recreated in production, and their IDs updated in your app
* [ ] Revocation tested; token status list partition size final and a publish job scheduled, if you use it
* [ ] Iden3 credentials enabled by the AIR team, if you use them

**Verifying credentials** (if you verify)

* [ ] Verification programs recreated in production, and their IDs updated in your app
* [ ] Programs limited to the production Issuer DIDs you trust
* [ ] Backend verifies every presentation, including the key-binding JWT, and uses each nonce only once

**Accounts and gas** (if you use smart accounts)

* [ ] Gas sponsorship policies and chains confirmed with the AIR team
* [ ] Sponsorship spend is monitored
* [ ] Session keys are narrowly scoped with short expiry

**Operations**

* [ ] All main flows tested end to end on production
* [ ] Alerts set up for failed authentication (spikes in 401 and 403 responses) and unusual issuance volume
* [ ] A key rotation plan: add the new key to your JWKS before removing the old one

For the full list of security practices, see the [Security checklist](/technicals/architecture/security-checklist).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.