IDer integration guide for AI agents

Who this page is for. You are an AI coding agent (or a developer) asked to add “Login with IDer” to a website, web app, e-commerce or mobile app, or to set up IDer QR code campaigns. This page contains everything you need: how IDer works, what the human must do in the partner portal, the exact OpenID Connect parameters, the data you receive and the known pitfalls. Read it all before writing code. Last updated: November 2026.

Rules that are easy to get wrong (details below):
  1. Supported for partners: only the Authorization Code flow with the client secret (client_secret_basic or client_secret_post) plus the userinfo endpoint. No PKCE (it is not needed: turn it off in your library, many enable it by default), no refresh tokens, no implicit or password flows, even if the discovery document lists them.
  2. The scope must be exactly openid <Scope Name>: two values, openid first. No email, profile, offline_access, no second GUID.
  3. The redirect_uri must be identical, character by character, to the callback URL saved in the partner portal.
  4. Always send state and nonce.
  5. Read the customer data from the userinfo endpoint.
  6. address arrives as a string containing JSON; gender is lowercase m/f; normalise phone_number.
  7. Never put the Client Secret in a browser or mobile app bundle: the code exchange must run on a server.

1. What IDer is2. What the human must do3. Official plugins4. Connection values5. The flow, step by step6. Customer data7. Accounts and sessions8. Mobile apps and SPAs9. Partner portal reference10. Campaigns and QR codes11. Troubleshooting12. Checklist

1. What IDer is

IDer is a passwordless authentication app (iOS and Android) and a standard OpenID Connect provider. The end customer keeps their digital identity in the IDer app. To sign in to a partner site they click “Login with IDer” (or scan an IDer QR code), confirm in the app which data to share, and are sent back to the partner site already authenticated. On the first access the app also shows the partner’s terms and privacy policy, which the customer must accept.

  • Partner: the company that integrates IDer (your user). It manages everything at partner.ider.com.
  • Login Button: the partner’s OpenID Connect client (Client Id, Client Secret, Scope Name, callback URL).
  • Campaign: a QR code or link to acquire new customers, with its own data request and its own Scope Name (see section 10).
  • Scope Name: a GUID that identifies the Login Button or the campaign. It decides which data the customer is asked to share.

Customers without the app are guided to download it and then continue.

2. What the human must do (you cannot do it for them)

The partner portal is accessed only by scanning a QR code with the IDer app, so ask your user to do these steps and to give you the resulting values:

  1. Install the IDer app, create an identity, then open partner.ider.com and scan the QR code. The company area is created on the first access.
  2. Open Login Button → Edit and complete the wizard:
    1. Choose site type: Website for any custom site, app or generic OpenID Connect module (choose WordPress/Woocommerce only with the official WordPress plugin).
    2. The requested information: tick the data you need and mark each item required or optional (list in section 6). Ask only what you need: fewer fields, more completed sign-ups.
    3. Terms and conditions and Privacy Policy of the partner (required; shown in the app).
    4. URL: the authentication request URL (the page of the partner site that starts the login, e.g. https://shop.example.com/auth/ider/login) and the callback URL (your redirect_uri, e.g. https://shop.example.com/auth/ider/callback). Tell your user the exact values your code uses.
    5. Button layout: icon only or “Login with IDer”.
    6. Summary → Save.
  3. Copy from the summary: Client Id, Client Secret, Scope Name. Store the secret in an environment variable or secret manager, never in the repository.
In the Login Button summary the labels “Callback URL” and “Button URL” may appear swapped. What matters is the value saved in the callback field of the URL step: it must equal your redirect_uri.

Each Login Button and each campaign has one redirect URI. To serve several sites or environments (production, staging), use a separate client or campaign for each, or a single public callback URL.

3. Official plugins (use them when the platform matches)

PlatformPackageAddresses to enter in the portal
WordPress / WooCommerceIDer Login (wordpress.org)Site type WordPress or Woocommerce; the plugin uses /iderbutton (start) and /idercallback (callback)
PrestaShop 8 and 9iderlogin (GitHub release zip)Website; start …/module/iderlogin/login, callback …/module/iderlogin/callback; the Scope Name goes in “Extra scopes”
Joomla 5 and 6plg_system_iderlogin (GitHub release zip)Website; start …/index.php/iderlogin/login, callback …/index.php/iderlogin/callback

For Drupal, Magento, PrestaShop 1.7, Joomla 4 and other CMSs use a generic OpenID Connect client module with the values of section 4: see the OpenID Connect integration guide. For custom code use a certified library (openid-client for Node.js, Authlib for Python, Microsoft.AspNetCore.Authentication.OpenIdConnect for .NET, jumbojett/openid-connect-php for PHP, Spring Security OAuth2 Client for Java) configured as in section 5, or the plain HTTP calls shown there.

4. Connection values

ItemValue
Issuerhttps://oid.ider.com/core
Discoveryhttps://oid.ider.com/core/.well-known/openid-configuration
Authorization endpointhttps://oid.ider.com/core/connect/authorize
Token endpointhttps://oid.ider.com/core/connect/token
Userinfo endpointhttps://oid.ider.com/core/connect/userinfo
JWKShttps://oid.ider.com/core/.well-known/jwks
Client authenticationclient_secret_basic (recommended) or client_secret_post
id_token signatureRS256
Response type / modecode / query (the default; form_post is not tested)
Scopeopenid <Scope Name>, for example openid 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d (example value)
Access token lifetime3600 seconds. No refresh token.

The discovery document lists more grant types, response types and options (refresh tokens, implicit, password, PKCE) than partner clients can use: do not rely on it to choose the flow. claims_supported and scopes_supported are empty there: configure the scope by hand.

5. The flow, step by step

5.1 Start the login (your “authentication request URL”)

Generate a random state and nonce, store them in the user session (valid a few minutes, single use) and redirect the browser to:

GET https://oid.ider.com/core/connect/authorize
  ?response_type=code
  &client_id=<Client Id>
  &redirect_uri=<callback URL, URL-encoded, identical to the portal>
  &scope=openid%20<Scope Name>
  &state=<random>
  &nonce=<random>

These six parameters are all you need. PKCE is not needed: do not send code_challenge / code_verifier (if your library adds them by default, disable that option). prompt, max_age, login_hint and ui_locales are ignored, and prompt=none always returns login_required. IDer shows a page with a QR code (desktop) or opens the app (mobile); the customer confirms in the app. The QR code must be scanned within about 20 minutes. The IDer pages are in English.

5.2 Handle the callback

IDer redirects to <redirect_uri>?code=…&state=…. Check that state matches the stored value, then delete it. If the query contains error (for example login_required or invalid_scope), show a friendly message and a link to retry.

Configuration errors (wrong scope, unknown client, redirect_uri not registered) are not sent back to your callback: IDer shows its own error page (“Invalid Partner configuration”) on oid.ider.com. If the user is stuck there, check section 11.

5.3 Exchange the code (server side)

POST https://oid.ider.com/core/connect/token
Authorization: Basic base64(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=<code>&redirect_uri=<same redirect_uri>

Do not URL-encode the client id and secret inside the Basic header: IDer decodes only the base64. If your library URL-encodes them (many do, following the standard) and the secret contains characters other than letters and digits, use client_secret_post instead. With client_secret_post send client_id and client_secret in the body instead of the header. The response contains access_token (valid 3600 seconds), id_token, token_type and expires_in. There is no refresh token.

5.4 Validate the id_token

  • Signature RS256 with the key from the JWKS that matches the token’s kid (build the public key from its n and e values).
  • iss = https://oid.ider.com/core, aud = your Client Id, exp in the future (allow a little clock skew and keep the server clock in sync with NTP), nonce = the stored value.
  • Take the user identifier from sub. Do not expect customer data in the id_token: read it from userinfo.

5.5 Read the customer data

GET https://oid.ider.com/core/connect/userinfo
Authorization: Bearer <access_token>

Check that the sub in the response equals the sub of the id_token. The response contains all the data of the scope the customer has a value for (not only what changed since the last login). Parse it as described in section 6.

5.6 Example (Node.js, openid-client 5.x)

const { Issuer, generators } = require('openid-client');
const ider = await Issuer.discover('https://oid.ider.com/core');
const client = new ider.Client({
  client_id: process.env.IDER_CLIENT_ID,
  client_secret: process.env.IDER_CLIENT_SECRET,
  redirect_uris: ['https://shop.example.com/auth/ider/callback'],
  response_types: ['code'],
  token_endpoint_auth_method: 'client_secret_basic',
});
// login route (no PKCE: do not pass code_challenge)
const state = generators.state(), nonce = generators.nonce();
req.session.ider = { state, nonce };
res.redirect(client.authorizationUrl({ scope: 'openid ' + process.env.IDER_SCOPE_NAME, state, nonce }));
// callback route
const params = client.callbackParams(req);
const tokens = await client.callback('https://shop.example.com/auth/ider/callback', params,
  { state: req.session.ider.state, nonce: req.session.ider.nonce });
const profile = await client.userinfo(tokens.access_token);

The same structure applies to any language: one route that builds the authorization URL, one callback route that checks state, exchanges the code, validates the id_token and calls userinfo.

6. Customer data (claims)

You receive the data ticked in the portal for that Login Button or campaign, and only the items the customer has filled in. Treat every claim as optional.

ClaimContent and format
subStable identifier of the customer’s IDer identity, the same for every partner. Use it as the external id. A customer’s personal and company identities have different sub values.
emailEmail. If a campaign requires it and the customer has none, the app asks for it before continuing.
given_name, family_name, preferred_username, nameFirst name, last name, username, full name.
phone_numberUsually international format with a space after the country code, e.g. +39 3331234567, but other spellings exist: normalise it (for example to E.164) before storing.
birthdateYYYY-MM-DD.
genderLowercase m or f.
nationalityISO 3166-1 alpha-2 code, uppercase (e.g. IT).
address, address_residence, address_shipping, address_billingA string containing JSON, to decode: {"address_name":"…","street_address":"…","locality":"…","region":"…","postal_code":"…","country":"IT"}. address_name can be missing; region is usually a 2-letter province code but can be empty or a full name; country is ISO alpha-2.
Company identitiescompany_name, company_vat.
Other categoriesDocuments (fiscal_code, identity_card_id, passport_card_id, …), family (marital_status, family_num_person), job (job_title, Employment_Sector), vehicles (license_plate, driving_license_type, …), sizes (shirt_size, pants_size, shoe_size), web (nickname, website, …).
Custom fieldsFields created for a partner by the IDer team arrive with their exact claim name, hyphens included (e.g. postalcode-yourcompany).

Robust parsing: values are normally single strings; if a claim arrives as an array (several different values of the same type), take the first non-empty one. Accept both a JSON string and an object for the address claims. Ignore claims you do not know. email_verified and phone_number_verified are normally not sent; if present they are the strings "true"/"false".

7. Accounts and sessions

  • Linking: look for a local user with the IDer sub (store it in a dedicated table or field); if none, optionally link by email; otherwise create the user. Linking by email is convenient but lets whoever controls that email in IDer take over the local account: for administrator accounts, do not allow it.
  • Updating: at every login refresh the profile with the received data, without deleting local values the customer did not share.
  • Session: after the callback create your own session. The IDer session lasts only a few minutes and is not reusable, so every login goes through the app again. Logout is local: you do not need the IDer end session endpoint.
  • Consent: the app shows the partner terms only once per customer. They are shown again only when a new version of the terms is published.
  • Privacy: store only what you need, never log tokens, codes or personal data, and offer the customer a way to delete the local account (GDPR).

8. Mobile apps and single-page apps

Always use a server (backend-for-frontend) that owns the Client Secret and performs steps 5.3 to 5.5. The callback URL registered in the portal must be an absolute https:// address of that server (http://localhost works only if registered exactly; custom URL schemes such as myapp:// are not supported). For native apps open the authorization URL in the system browser (ASWebAuthenticationSession on iOS, Custom Tabs on Android); after the callback the server returns to the app with your own session token through a universal/app link. Do not call the token or userinfo endpoints from a browser or embed the Client Secret in an app.

9. Partner portal reference (partner.ider.com)

MenuWhat it does
HomepageStatistics: acquired users, by Login Button and by campaigns, gender split.
CampaignsList and creation of campaigns (section 10).
Login ButtonThe OpenID Connect client: requested data, terms, URLs, layout, Client Id / Secret / Scope Name.
Direct MarketingMessages to the partner’s users as Push notifications in the IDer app (Email and SMS are available on specific request to the IDer team): name, date, text; source campaigns; filters by age, gender and nationality; a summary with the recipient count before sending. There is no selection of single users: narrow the filters until the count is right.
Manage TeamOther IDer users who can manage the partner (roles Owner, Writer and Reader).
Company ProfileCompany data and logo.
My UsersCustomers who shared data with the partner, with export.

One IDer user can manage several partners: switch with the menu at the top right. Data fields that are not in the list are created on request by the IDer team (contact form).

10. Campaigns and QR codes

  • Wizard: requested data → terms and privacy → general setup (name up to 40 characters, how many users to acquire, start and end dates, end message) → campaign setup → payment. There is no fixed limit of users per campaign: larger numbers can be configured on request to the IDer team.
  • Every campaign always asks for email, nationality, birthdate and gender (for company identities also company_name and company_vat), plus the data you choose.
  • Types: Digital QR code / button for social media, newsletters and websites, or Printable QR code for flyers, posters, TV and shop windows.
  • After access: To my website (your start and callback URLs, same OpenID Connect flow as the Login Button but with the campaign’s own Scope Name and redirect URI) or To my IDer area (a page hosted by IDer).
  • Campaign QR codes point to https://l.ider.com/<code>. With the IDer app installed the link opens the app and starts the access; on an Android phone without the app it leads to Google Play; on a desktop it opens a page that explains IDer. Installing the app does not subscribe the customer to the campaign automatically: they scan or open the code again from the app.
  • Any costs and the budget are shown in the portal during the campaign wizard: ask your user, do not assume prices.
  • One OpenID Connect client can serve several campaigns: the data you receive depends on the Scope Name used in the request.

11. Troubleshooting

SymptomCause and fix
IDer shows “Invalid Partner configuration” or another error page on oid.ider.comWrong scope (it must be exactly openid <Scope Name>), unknown Client Id, or redirect_uri not identical to the portal (scheme, www, trailing slash, path, encoding).
error=invalid_scope or error=login_required on the callbackScope with extra values, or prompt=none sent: remove it.
invalid_client at the token endpointWrong secret or authentication method. Use client_secret_basic or client_secret_post. With Basic, the id and secret must not be URL-encoded: if your library encodes them and the secret has characters such as + / = %, switch to client_secret_post.
invalid_grant at the token endpointThe code was already used or expired, the redirect_uri differs from the one of step 5.1, or the library sent PKCE parameters by default (code_verifier): PKCE is not needed, disable it so that the request contains only the fields shown in 5.3.
id_token rejected because of the signatureSelect the JWKS key by kid and build it from n/e; refresh the cached JWKS.
Token “expired” or “not yet valid”Server clock out of sync: enable NTP.
Login works but data is missingThe data is not ticked in the portal for that Scope Name, the customer did not fill it in, or you read the id_token instead of userinfo.
Address, gender or phone stored wronglyDecode the address string as JSON; gender is lowercase; normalise phone_number.
The customer is not asked to accept the terms againNormal: terms are shown once. Publish a new version of them to show them again.
A duplicate local user is createdStore and look up the IDer sub; link by email only as a fallback.
The QR code page expiredThe QR code must be scanned within about 20 minutes: start the login again.
HTTP 429Too many requests: retry later.

12. Checklist before going live

  1. The human has created the Login Button (or campaign) and given you Client Id, Client Secret (in a secret store) and Scope Name.
  2. Start URL and callback URL in the portal are exactly the ones your code uses, over https://.
  3. Scope = openid <Scope Name>; authorization request with only the six parameters of 5.1, PKCE turned off.
  4. state and nonce are random, stored server side, checked and used once.
  5. Code exchange on the server with client authentication; id_token validated (RS256 key by kid, iss, aud, exp, nonce).
  6. Data read from userinfo, sub checked, address JSON decoded, gender and phone normalised, every claim optional.
  7. Users linked by sub; admin accounts cannot be taken over through IDer.
  8. No secrets, tokens or personal data in logs, source code or client bundles.
  9. A “Login with IDer” button is visible on the login, registration and checkout pages.
  10. Tested end to end with a real IDer account on desktop (QR code) and on mobile (app switch).

Need help or a custom field? Contact the IDer team.