> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `claude plugin marketplace add scalekit-inc/claude-code-authstack && claude plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Organization-specific redirect URLs

Register one redirect URL pattern that Scalekit resolves to an organization-specific URL at runtime.
Multi-tenant applications often need a different callback URL for each customer. Instead of registering a separate redirect URL for every organization, you can register a single template that Scalekit expands per organization at runtime.

For example, `https://{{slug}}/oauth/callback` expands to `https://auth.megasoft.com/oauth/callback` for Megasoft and `https://auth.betacorp.com/oauth/callback` for Beta Corp, with no additional configuration needed.

## Available template variables

| Variable | Source | Example value |
|---|---|---|
| `{{slug}}` | Organization's slug field. Can be a single DNS label (`megasoft`) or a full hostname (`auth.megasoft.com`). | `auth.megasoft.com` |
| `{{external_id}}` | Organization's external ID from your system. | `megasoft-123` |
| `{{custom_domain}}` | Any key stored in the organization's metadata. | `metadata.custom_domain = "auth.megasoft.com"` |

## Register an organization-specific URL

Add organization-specific URLs in **Dashboard > Authentication > Redirects** and type the URL pattern directly into the input field. These URLs are valid in all three redirect fields:

- **Allowed callback URLs**: where Scalekit sends users after authentication
- **Post logout URL**: where Scalekit sends users after logout
- **Initiate login URL**: where Scalekit sends IdP-initiated login requests

> Image: Screenshot

Supported patterns for redirect URLs:

| Pattern | Example | Notes |
|---|---|---|
| Subdomain | `https://{{slug}}.yourapp.com/callback` | `{{slug}}` is a single DNS label such as `acme` |
| Full host | `https://{{slug}}/callback` | `{{slug}}` is a full hostname such as `auth.megasoft.com` |
| Custom domain | `https://{{custom_domain}}/callback` | Value comes from org metadata |
| Path variable | `https://yourapp.com/{{slug}}/callback` | Variable in the path component |

> caution: DNS label constraint
>
> Template variables cannot span part of a DNS label. `https://app-{{slug}}.yourapp.com` is not valid; the placeholder must occupy the entire DNS label or the entire host.

At runtime, Scalekit substitutes each `{{variable}}` with its resolved value, validates the expanded URL against registered templates, and redirects the user. For logout, the organization is resolved from the active session; if the session has expired, template expansion is skipped and the redirect is rejected.

## Set slug or metadata for an organization

Set `slug` on an organization to expand `{{slug}}` templates. Store any key in organization `metadata` to use it as a custom variable like `{{custom_domain}}`. Setting just one is enough — use whichever fits your registered URL pattern.

### Via dashboard

Navigate to **Organizations > Select an organization > Overview > Edit**. Add the organization slug in the **Slug** field.
> Image: Create Organization dialog showing the Slug field

### Via SDK

### Node.js

```bash showLineNumbers=false frame="none"
npm install @scalekit-sdk/node
```

   ### Python

```sh showLineNumbers=false frame="none"
pip install scalekit-sdk-python
```

  ### Go

```sh showLineNumbers=false frame="none"
go get -u github.com/scalekit-inc/scalekit-sdk-go
```

   ### Java

```groovy showLineNumbers=false frame="none"
/* Gradle users - add the following to your dependencies in build file */
implementation "com.scalekit:scalekit-sdk-java:2.1.3"
```

```xml showLineNumbers=false frame="none"
<!-- Maven users - add the following to your `pom.xml` -->
<dependency>
    <groupId>com.scalekit</groupId>
    <artifactId>scalekit-sdk-java</artifactId>
    <version>2.1.3</version>
</dependency>
```

### Node.js

```javascript title="Create organization with slug and metadata"
// Set slug, metadata, or both — each enables a different template variable.
const organization = await scalekit.organization.createOrganization(
  'Megasoft',
  {
    slug: 'auth.megasoft.com',
    metadata: { custom_domain: 'auth.megasoft.com' },
  }
);
```

### Python

```python title="Create organization with slug and metadata"
# Set slug, metadata, or both — each enables a different template variable.
from scalekit.v1.organizations.organizations_pb2 import CreateOrganization

organization = scalekit_client.organization.create_organization(
    CreateOrganization(
        display_name='Megasoft',
        slug='auth.megasoft.com',
        metadata={'custom_domain': 'auth.megasoft.com'},
    )
)
```

### Go

```go title="Create organization with slug and metadata"
// Set slug, metadata, or both — each enables a different template variable.
slug := "auth.megasoft.com"

_, err := scalekitClient.Organization().CreateOrganization(
    ctx,
    "Megasoft",
    scalekit.CreateOrganizationOptions{
        Slug: &slug,
        Metadata: map[string]interface{}{
            "custom_domain": "auth.megasoft.com",
        },
    },
)
if err != nil {
    log.Fatal(err)
}
```

### Java

```java title="Create organization with slug and metadata"
// Set slug, metadata, or both — each enables a different template variable.
// Requires scalekit-sdk-java v2.1.3+
CreateOrganization create = CreateOrganization.newBuilder()
    .setDisplayName("Megasoft")
    .setSlug("auth.megasoft.com")
    .putMetadata("custom_domain", "auth.megasoft.com")
    .build();

scalekitClient.organizations().create(create);
```

## Pass organization_id and redirect URL in the authorization request

Pass the organization-specific `redirect_uri` and `organization_id` in the authorization request. Scalekit validates the redirect URL against the registered pattern using the organization's slug or metadata. See [set up login flow](/authenticate/fsa/implement-login/#set-up-login-flow) for the full auth call reference.

### Node.js

```javascript title="Authorization URL with organization_id" ins={1,5}
const redirectUri = 'https://auth.megasoft.com/oauth/callback';
const options = {
  scopes: ['openid', 'profile', 'email'],
  state: sessionStorage.oauthState,
  organizationId: 'org_12345',
};

const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);
res.redirect(authorizationUrl);
```

### Python

```python title="Authorization URL with organization_id" ins={1,5}
redirect_uri = 'https://auth.megasoft.com/oauth/callback'
options = AuthorizationUrlOptions(
    scopes=['openid', 'profile', 'email'],
    state=session['oauth_state'],
    organization_id='org_12345',
)

authorization_url = scalekit_client.get_authorization_url(redirect_uri, options)
return redirect(authorization_url)
```

### Go

```go title="Authorization URL with organization_id" ins={1,5}
redirectUri := "https://auth.megasoft.com/oauth/callback"
options := scalekit.AuthorizationUrlOptions{
    Scopes:         []string{"openid", "profile", "email"},
    State:          state,
    OrganizationId: "org_12345",
}

authorizationUrl := scalekitClient.GetAuthorizationUrl(redirectUri, options)
http.Redirect(w, r, authorizationUrl, http.StatusFound)
```

### Java

```java title="Authorization URL with organization_id" ins={1,5}
String redirectUri = "https://auth.megasoft.com/oauth/callback";
AuthorizationUrlOptions options = new AuthorizationUrlOptions();
options.setScopes(List.of("openid", "profile", "email"));
options.setState(state);
options.setOrganizationId("org_12345");

String authorizationUrl = scalekitClient.getAuthorizationUrl(redirectUri, options);
response.sendRedirect(authorizationUrl);
```

If no organization is in scope, the template is not expanded and the request is rejected.

## A worked example

1. **Register the URL pattern**

   In **Dashboard > Authentication > Redirects > Allowed callback URLs**, add the URL as `https://{{slug}}/oauth/callback`.

2. **Set the organization's slug**

   For Megasoft, set `slug` to `auth.megasoft.com` (see [Set slug and metadata for an organization](#set-slug-and-metadata-for-an-organization) above).

3. **Pass the org-specific redirect URL and `organization_id` in the authorization request**

   When a Megasoft user signs in, Scalekit validates the `redirect_uri` against the registered pattern using the organization's slug:

   ```
   https:///oauth/authorize?client_id=...&redirect_uri=https://auth.megasoft.com/oauth/callback&organization_id=org_megasoft_123&...
   ```

4. **Scalekit validates and redirects**

   Scalekit matches `https://auth.megasoft.com/oauth/callback` against the registered pattern `https://{{slug}}/oauth/callback` using Megasoft's slug and redirects the user.


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
