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

# Auto-login (single sign-on)

> Generate a single-use link via the API that logs a known partner straight into their portal dashboard — no password or one-time code required

When you already know who the user is (for example, they're logged into your own app), you can send them **straight into their partner portal dashboard** without them entering an email, password, or one-time code. Your backend asks Partnero for a **single-use sign-in link**, then redirects the partner to it — Partnero consumes the link, signs them in, and lands them on their dashboard.

This is the fully login-free experience referenced in [Prefill the login email](/guides/partner-portal/prefill-login-email): instead of pre-filling the login form, it skips the login step entirely.

<Note>
  Works for both **affiliate** and **refer-a-friend** portals. The link is minted through the API, so it requires your **secret API key** and must be generated **server-side**.
</Note>

## How it works

<Steps>
  <Step title="Your backend requests a sign-in link">
    When a signed-in user on your site clicks "Open partner portal", your server calls the [create sign-in URL](/api-reference/partners/sign-in-url) endpoint, identifying the partner by `id`, `key`, or `email`.
  </Step>

  <Step title="Partnero returns a single-use URL">
    The response contains a `url` on your portal's domain (for example `https://partners.yourdomain.com/sso/<token>`) and an `expires_at` timestamp.
  </Step>

  <Step title="Redirect the partner to the URL">
    Redirect the browser to the returned `url` (or open it). Partnero validates the token, logs the partner in, and redirects them to their dashboard.
  </Step>

  <Step title="The link is consumed">
    The token is **single-use** and **short-lived**. Once used (or once it expires) it can't be used again, and visiting it lands the user on the normal login screen instead.
  </Step>
</Steps>

## Generating a link

Call the endpoint from your backend, identifying the partner and (optionally) how long the link stays valid:

```bash cURL theme={null}
curl --location 'https://api.partnero.com/v1/partners:sign-in-url' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "email": "john.doe@partnero.com",
    "expires_in": 120
  }'
```

```json Response theme={null}
{
  "data": {
    "url": "https://partners.yourdomain.com/sso/8f3c...redacted",
    "expires_at": "2026-07-16T13:22:00.000000Z"
  },
  "status": 1
}
```

You can also target the partner by ID in the path — `POST /v1/partners/{id}/sign-in-url` — instead of passing an identifier in the body. See the [API reference](/api-reference/partners/sign-in-url) for all parameters.

<Tip>
  Generate the link **on demand, right before you redirect** — not ahead of time. Because it's single-use and short-lived, a link minted in advance will usually be expired or already consumed by the time it's needed.
</Tip>

## Link lifetime

The token's validity is controlled by `expires_in` (in seconds):

|         | Value                    |
| ------- | ------------------------ |
| Default | 120 seconds (2 minutes)  |
| Minimum | 30 seconds               |
| Maximum | 900 seconds (15 minutes) |

Values outside the range are clamped to the nearest allowed value. Keep it short: the link only needs to survive the redirect from your app to the portal.

## Security

<CardGroup cols={2}>
  <Card title="Server-side only" icon="lock">
    Minting a link requires your secret API key. Never expose it in client-side code — call the endpoint from your backend.
  </Card>

  <Card title="Single-use" icon="rotate-right">
    Each link works exactly once. Concurrent attempts to use the same link are safely rejected — only the first wins.
  </Card>

  <Card title="Short-lived" icon="clock">
    Links expire quickly (2 minutes by default, 15 minutes max), limiting the window if one leaks.
  </Card>

  <Card title="Respects portal access" icon="user-shield">
    Partners who are archived or otherwise blocked from portal login can't be signed in, even with a valid link.
  </Card>
</CardGroup>

<Warning>
  Treat the returned `url` as a credential. Anyone who obtains it before it's used can sign in as that partner. Only deliver it to the intended user (e.g. via a server-side redirect) and don't log it.
</Warning>

<Info>
  The create-link endpoint is rate limited to **60 requests per minute** per API key (falling back to IP). This is generous for on-demand, per-user generation.
</Info>

## When to use which

<CardGroup cols={2}>
  <Card title="Auto-login (this guide)" icon="right-to-bracket">
    You know the user (they're authenticated in your app) and want a zero-click hand-off into the portal.
  </Card>

  <Card title="Prefill the login email" icon="envelope" href="/guides/partner-portal/prefill-login-email">
    You want to reduce login friction but still have the partner verify with a one-time code or password.
  </Card>
</CardGroup>
