Setting up an ICR app

We'll go through, step by step, the process of setting up an ICR app. From creating the app on to the first user installing the app on their organization.

Everything in this tutorial will be made on the sandbox.

Creating the app

To create an app you have to start by creating an organization and setting the type of the organization as "Market participant". If you have not made an organization start by creating one. If you already have an organization then go to organization -> settings and change the type to Market participant .

Now your organization dashboard should look something like this:

Notice that the buttons now say "Create app" and the table displays "Apps" instead of "Projects".

Click the "Create app" and go through the flow to create your first app.

Setting up the minimum test app's website

This example uses the Best marketplace demo app. Clone it:

git clone

For it to be able to run you'll have to define some environment variables in the .env file

ICR_WEBHOOK_SECRET="" # optional
DATABASE_URL="file:./db.sqlite" # path to local db

To generate the ICR_PRIVATE_KEY navigate to the "Credentials" tab on your app's dashboard, there you can generate your keypair. Press the "Generate a private key" button. It automatically creates a keypair and downloads the "icr_private_key.pem" file to your machine. ICR does NOT store your private key. ICR only stores the public key and a fingerprint / hash for your convenience (see Verifying private keys for more info).

Please make sure you store your private key in a secure location where your website / app can use it for signing requests. Ideally it is stored in such away it can only be used for signing. Definitely make sure it is not committed to a repository, even if that repository is private. See Private keys for more details on why.

Open the downloaded ICR_PRIVATE_KEY pem file and copy paste the key into your .env file as the variable ICR_PRIVATE_KEY.

You can find the NEXT_PUBLIC_ICR_APP_ID and NEXT_PUBLIC_ICR_NAME_ID on your app's dashboard.

Now run

pnpm i
pnpx prisma db push
pnpm dev

The app should be running successfully on whatever port is open on your machine. The output should look like this:

Setting up remaining configs

The main configs to setup so your app's installation will work are:

  1. a callbackUrl (see Callback URLs for more info on callback urls)

  2. creating an RSA keypair (see App private keys for more info on private keys)

We've already created the RSA keypair so we only need to define the callbackURL. Go to the "General" tab on the app's dashboard and input your callback url. The callback url should point to the path where your app is running. For our example it will likely be running on localhost:3000, but you can see where your instance of the example app is running in the output from the pnpm devcommand (see image above). So copy the path to your running instance and paste it with the /api/icrCallback path to the Callback URLs section of the General tab on your app's dashboard.


And save the updated info.

Integrating the first user

For this example we are only going to look at the integrations part of the App.

This is the user facing code. The only thing it does is show a "Connect to ICR" button to the user of our app. This button then takes the user to the url${env.NEXT_PUBLIC_ICR_NAME_ID}/installations/new?state=${stateVariable}&redirectUri=http://localhost:3001/api/icrCallback

Some explanation on the query params is needed.

  • state - you can use this variable to link the user to the callback and also this makes it harder for attackers to fake an installation by calling your callback endpoint with an installationId that they have no real connection to

  • redirectUri - here you can put where the user will be redirected after installing the app on their organization. This must match one of the callbackURLs you defined on the app's dashboard. If left empty the first callbackUrl you defined on the app's dashboard is used.

After installing the app the user is redirected to our /api/icrCallback endpoint where our app verifies the state variable, here you could match it to an internal user if it contains its uid, and calls the /app/installations/:installationId to both verify that this installtionId is legit and get data to save with the user so we know which apps are integrated with this user.

Now if you go through installing the app on an organization you are an admin of, by going through the "Best marketplace" ui, the Best marketplace will show your organization.

That's about it for integrating the first user with our app. This integration only has limited permission though, i.e. only the organization_info permission so the only thing we can do is read basic info about the connected organization. Next up we'll add permissions to our app and request moving credits from an organization's inventory. To see available permission see "App permissions".

Last updated