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

# Log customers into the Self Service Center with a token

> Generate a Self Service Center login token by email address and send customers directly to their Firmhouse Self Service Center.

Use `createSelfServiceCenterLoginTokenV2` when you want to send a customer directly into the Firmhouse Self Service Center from your own app, email, or support tool without asking them to request a login email first.

The mutation looks up a completed subscription in your project by email address, creates a short-lived Self Service Center login token, and returns a URL that includes the token. Redirect the customer to that URL for immediate login.

## Requirements

* A Firmhouse API access token with write access. Create one in **Settings > Integrations > Access Tokens** in your Firmhouse project.
* The customer's email address must match a completed subscription in the same Firmhouse project.
* The mutation should be called from your backend. Do not expose a write API access token in browser code.

## Create the token

Send a GraphQL request to the Firmhouse API and pass the customer's email address to `createSelfServiceCenterLoginTokenV2`.

```graphql theme={null}
mutation CreateSelfServiceCenterLoginToken($email: String!) {
  createSelfServiceCenterLoginTokenV2(input: { email: $email }) {
    selfServiceCenterLoginToken {
      token
      expiresAt
      returnUrlWithToken
    }
    errors {
      attribute
      message
    }
  }
}
```

Use variables for the email address:

```json theme={null}
{
  "email": "customer@example.com"
}
```

Example request:

```bash theme={null}
curl https://portal.firmhouse.com/graphql \
  -H "Content-Type: application/json" \
  -H "X-Project-Access-Token: YOUR_PROJECT_ACCESS_TOKEN" \
  -d '{
    "query": "mutation CreateSelfServiceCenterLoginToken($email: String!) { createSelfServiceCenterLoginTokenV2(input: { email: $email }) { selfServiceCenterLoginToken { token expiresAt returnUrlWithToken } errors { attribute message } } }",
    "variables": {
      "email": "customer@example.com"
    }
  }'
```

## Redirect the customer

Use `returnUrlWithToken` from the response as the destination URL:

```json theme={null}
{
  "data": {
    "createSelfServiceCenterLoginTokenV2": {
      "selfServiceCenterLoginToken": {
        "token": "generated-token",
        "expiresAt": "2026-05-15T16:00:00Z",
        "returnUrlWithToken": "https://your-project.example.com/en/your-project/self-service/token_login?token=generated-token"
      },
      "errors": []
    }
  }
}
```

Redirect the customer to `returnUrlWithToken`. Firmhouse validates the token and starts the customer's Self Service Center session. When the email address has access to multiple subscriptions, Firmhouse uses the normal subscription chooser unless you add a target as described below.

### Target one of the customer's subscriptions

When the email address has access to multiple subscriptions, use the optional `subscription_id` query parameter to open a specific subscription directly.

To let the customer request their own magic link, include the target on the Customer Portal login-page URL:

```text theme={null}
https://<your-self-service-center-domain>/<locale>/<project-path>/self-service/login?subscription_id=<subscription-id>
```

Firmhouse preserves the target when the customer submits their email address and includes it in the emailed magic-link URL.

When you generate the token through the API instead, add the target to `returnUrlWithToken`:

```text theme={null}
https://<your-self-service-center-domain>/<locale>/<project-path>/self-service/token_login?token=<token>&subscription_id=<subscription-id>
```

Use the Firmhouse subscription ID returned by the API. Firmhouse only uses the target when it belongs to the email address authenticated by the login token, including subscriptions in a linked Self Service Center login project. Missing, invalid, or inaccessible subscription IDs use the normal post-login routing and do not reveal subscription data.

If the URL also includes a valid `redirect_to` path, Firmhouse opens that path for the targeted subscription. This can only be a path inside the targeted subscription's Self Service Center; external redirect URLs are ignored.

If you only need the raw token, you can build the login URL yourself by adding it as the `token` query parameter to your project's Self Service Center token login URL:

```text theme={null}
https://<your-self-service-center-domain>/<locale>/<project-path>/self-service/token_login?token=<token>
```

In most integrations, using `returnUrlWithToken` is safer because Firmhouse returns the correct project host, locale, project path, and token parameter for the matched subscription.

## Handle errors and expiry

Check both top-level GraphQL errors and the mutation payload's `errors` field.

When the API returns a mutation payload but cannot create a login token, `selfServiceCenterLoginToken` is `null` and the payload's `errors` field contains the validation details.

When the email address does not match a completed subscription in the project, the API can return a top-level GraphQL error before returning the mutation payload. Handle that response as a failed token creation and ask the customer to use the email address connected to their subscription.

Self Service Center login tokens expire after 4 hours. Generate the token shortly before redirecting the customer.

## Related

* [Generate API access tokens](/integrations/api-access-tokens)
* [Firmhouse Developer Docs](https://developer.firmhouse.com)
