How It Works
Your server asks for a link
When a signed-in user of your app opens the partner area, your backend calls the Affiliate SSO Link API with your API key. The key is what vouches for the user, so no password is involved.
You get a one-time link
The link points to your portal address, works once, expires after 120 seconds and only works for your account.
Your app opens it
Load the link in a webview or iframe. The affiliate is signed in and lands on the portal dashboard, or on the page you asked for.
Captcha is skipped for these links, because your own app has already signed the user in. Affiliates who set up two-factor authentication are still asked for their code; see Passwords and Two-Factor.
Before You Start
- Your plan must include API access.
- This feature is available on request. If you do not see the setting below, contact support to have it enabled for your account.
- Turn on Sign-in from your app (SSO) under Settings → Customize → Security → Portal Embedding. It is off by default, and until you turn it on the API refuses every sign-in link.
- Create an API key under Settings → Security → API Keys. You need your Account ID, the key and its secret. More about API keys.
- Call the API from your server only. Never put the API secret in a mobile app or in web page code.
Create a Sign-in Link
Send a POST request with your credentials in the headers. Identify the affiliate by one of external_id, affiliate_id or email.
curl -X POST https://api.affclix.com/v1/a/affiliate-sso-link \
-H "X-Domain-Id: YOUR_ACCOUNT_ID" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"external_id": "usr_8f2c1a",
"chrome": "minimal",
"redirect_to": "/p/affiliate/campaigns"
}' | Field | Description |
|---|---|
external_id | Your own user ID. The first time you send it together with an affiliate ID or e-mail, the two are linked, and from then on the external ID alone is enough. |
affiliate_id | The affiliate ID shown in your dashboard. |
email | The affiliate login e-mail. |
redirect_to | Optional. A portal path starting with /, for example /p/affiliate/reports. Full URLs to other sites are refused. |
chrome | Optional. full, minimal or none. See Portal Layout below. |
create | Optional. Set to true to create the affiliate if they do not exist yet. |
password_login | Optional. Set to false to make the affiliate app-only: the login form, Forgot password and the Affiliate Login API then refuse them. Set to true to allow password sign-in again. Leave it out to keep the current setting. |
host | Optional. The portal address the link opens on. See Your Own Domain. |
A successful response:
{
"status": 200,
"response": "affiliate_sso_link_created",
"login_url": "https://yourbrand.affclix.com/affiliate/sso/…",
"affiliate_id": "745744",
"external_id": "usr_8f2c1a",
"created": false,
"password_login": true,
"expires_at": "2026-10-28T08:41:01+00:00",
"expires_ts": 1793176861
} Open the Link
Load login_url in the webview or iframe straight away. Ask for a new link every time you open the portal; do not store links or send them by e-mail.
Opening a link a second time, or after 120 seconds, shows the sign-in page with the message “This sign-in link is invalid or has expired. Please try again from the app.”
Opening a link replaces whoever was signed in to the portal in that browser or webview before.
Portal Layout
Inside your app you usually do not want the portal menus around the page. The chrome field controls this:
| Value | What the affiliate sees |
|---|---|
full | The normal portal with the top bar, sidebar and footer. This is the default. |
minimal | A slim bar with the page title and a menu button that opens the portal navigation. Good for mobile apps. |
none | The page content only. Use it when your app draws its own navigation. |
While the affiliate is signed in through a link, you can switch layout by adding ?chrome=none (or minimal, or full) to any portal address. Affiliates who sign in with a password always get the full portal.
Creating Affiliates on First Sign-in
If your users should become affiliates the first time they open the partner area, send "create": true with an e-mail and a first name:
{
"external_id": "usr_8f2c1a",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"company": "Doe Media",
"create": true
} - If an affiliate with that external ID or e-mail already exists, they are signed in instead and the response says
"created": false. - New affiliates are created as Active unless you send
"status": "PENDING". A Pending affiliate cannot sign in until you approve them. - No welcome e-mail is sent, and the affiliate gets a random password. They are app-only by default: they cannot sign in with a password or use Forgot password. Send
"password_login": trueif they should also be able to sign in directly. - Affiliates created this way count towards the affiliate limit of your plan.
Passwords and Two-Factor
App-only affiliates
An app-only affiliate can open the portal only through your app. The login form, Forgot password and the Affiliate Login API all refuse them.
- Affiliates created on first sign-in are app-only unless you send
"password_login": true. - For any affiliate, send
"password_login": falseto make them app-only, ortrueto allow password sign-in again. Leave it out to keep the current setting. - Every response tells you the current setting in
password_login.
Two-factor authentication
An affiliate who has set up two-factor authentication is asked for their 6-digit code, or a recovery code, after opening the link. They then land on the page you asked for, in the layout you chose.
If your app already checks a second factor when the user signs in, you can skip this step: turn off Ask for the 2FA code on app sign-ins under Settings → Customize → Security → Portal Embedding. It is on by default. Password sign-ins on the login page still ask for the code.
Your Own Domain
A sign-in only holds on the address it happened on. Links open on your Affclix subdomain unless you say otherwise.
If your affiliates use the portal on your own white-label domain, send it as host, for example "host": "partners.yourbrand.com". It must be a portal domain on your account that is active and verified under Custom Domains. Any other value is refused with validation_failed, and the error lists the hosts you can use.
Signing Out
When a user signs out of your app, end their portal session too. There are two ways, and you can use both:
- From your server — call
POST /v1/a/affiliate-sso-logoutwith the same headers and the affiliateexternal_id,affiliate_idoremail. Every portal session the affiliate opened through a link ends on its next page load, and links not yet opened stop working. - In the webview — load
https://<your-portal-address>/affiliate/sso/logout. This clears the session in that webview at once.
curl -X POST https://api.affclix.com/v1/a/affiliate-sso-logout \
-H "X-Domain-Id: YOUR_ACCOUNT_ID" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{ "external_id": "usr_8f2c1a" }'
{ "status": 200, "response": "affiliate_sso_sessions_revoked", "affiliate_id": "745744" } A sign-in still waiting on the affiliate’s two-factor code is refused as well. Neither way signs out an affiliate who logged in with their password.
Managing It in Your Dashboard
Open an affiliate under Affiliates → All Affiliates. On the Basic Info tab, the Portal SSO card shows the external ID your app uses for them, whether they can also sign in with a password, and their last sign-in from your app. With permission to edit affiliates you can:
- Change the external ID — the API links an external ID once and never changes it, so fix a wrong one here. The affiliate is signed out of your app and links not yet opened stop working.
- Unlink the external ID — your app can then link a new one by sending affiliate_id or email together with the new external_id.
- Allow password sign-in — the same setting as password_login in the API.
- Sign out of app sessions — the same as calling the logout API.
Turning Sign-in from your app off signs every affiliate out of your app at once, and links already sent stop working. Turning it back on does not bring those sessions back. While it is off, app-only affiliates can sign in with a password, using Forgot password first if they never set one.
Embedding in an iframe
Mobile app webviews need no setup. To show the portal inside an iframe on your website, list that website under Settings → Customize → Security → Portal Embedding.
- Enter one site per line, for example
https://www.example.comorhttps://*.example.com. Up to 10 sites. - Sites must use https. Plain http is accepted only for localhost while you test.
- Only the affiliate portal and its sign-in, sign-up and password pages can be embedded. Your own dashboard never can.
- Leave the list empty to block all embedding.
Safari blocks cookies inside iframes from another site, so the portal may not stay signed in there. If many of your users are on Safari or iOS, open the portal in a new tab or a webview instead.
Errors
| Status | response | Meaning |
|---|---|---|
| 400 | — | One of the three headers is missing. |
| 401 | — | Wrong API key, secret or Account ID. |
| 403 | — | Your plan does not include API access, or the request came from an IP the key does not allow. |
| 403 | sso_not_enabled | Sign-in from your app is turned off, or not yet enabled for your account. Turn it on under Settings → Customize → Security → Portal Embedding, or contact support if the setting is not there. |
| 403 | account_not_active | The affiliate exists but is pending, suspended or deleted. |
| 403 | password_login_disabled | Returned by the Affiliate Login API for an app-only affiliate. |
| 403 | plan_limit_reached | Creating the affiliate would go over the affiliate limit of your plan. |
| 404 | affiliate_not_found | No affiliate matches, and create was not set. |
| 409 | identity_conflict | The external ID is already linked to a different affiliate, or the affiliate is linked to a different external ID. |
| 409 | provisioning_in_progress | Another request is creating the same affiliate. Retry after a moment. |
| 422 | validation_failed | A field is missing or invalid, for example a redirect_to that is not a portal path, or a host that is not one of your portal domains. |