Developers

Authentication

Markdown

App launch from the merchant dashboard

What your launch URL receives on install and on open, and how to confirm that LARM issued the URL just now.

When the launch URL is opened

LARM opens the launch_url registered in your app version in two cases:

larm_intentWhenWhat to do
installThe merchant clicked "Install"Start authorization for this store
openThe merchant opened the installed app from the dashboardStart the merchant's session in your app

There is no separate app.installed webhook; you learn about the install from this URL and then from the code exchange.

Parameters

LARM removes any parameters starting with larm_ from your URL, then appends:

ParameterValue
larm_store_idStore UUID
larm_installation_idInstallation UUID, with open only
larm_intentinstall or open
larm_issued_atIssue time in Unix seconds
larm_nonce24 random base64url characters
larm_signature43 base64url characters

Example:

HTTP
https://app.example.com/larm/launch?larm_store_id=5b1d7a62-0c4e-4f38-9a51-2e7b3c9d8f10&larm_installation_id=c7e4a1f2-6b3d-4e8a-9c05-1d2f3a4b5c6d&larm_intent=open&larm_issued_at=1792060800&larm_nonce=Vx3mQ0aT9kLz2pR8sN4wYb1c&larm_signature=8m2Kq…

Verify the URL

The signature uses a key that only LARM holds, so you cannot verify it locally. Send the parameters exactly as received to [POST /oauth/launch/verify](/api/oauth-launch-verify) from your server:

Node.js
const params = Object.fromEntries(
  [...new URL(req.url, 'https://app.example.com').searchParams].filter(([key]) => key.startsWith('larm_')),
)
const response = await fetch('https://larm.sa/oauth/launch/verify', {
  method: 'POST',
  headers: {
    Authorization: 'Basic ' + Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64'),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(params),
})
if (!response.ok) return res.status(401).send('Invalid launch URL')
const launch = await response.json()
// { valid: true, store_id, installation_id, intent, issued_at }
  • The body carries larm_* keys only, all as strings. Any other key returns 400 INVALID_LAUNCH.
  • The URL is valid for 5 minutes from larm_issued_at. After that: 401 LAUNCH_EXPIRED.
  • With open, the installation must be active; otherwise 401 INSTALLATION_INACTIVE.
  • A wrong signature returns 401 LAUNCH_SIGNATURE_INVALID.

Start the merchant's session

The launch URL carries no access token and grants no access. After verification:

  1. Look up the installation_id in your database. If it is not there, or intent=install, start authorization.
  2. Create a session in your app bound to store_id, with an HttpOnly, Secure, SameSite=Lax cookie.
  3. Redirect the browser to your app page without the larm_* parameters, so they do not stay in history or in the Referer header.

Your app opens in its own window, not in a frame inside the merchant dashboard.

    ↑↓ moveEnter openEsc close