<!-- llms.txt: https://workos.com/llms.txt -->
<!-- feedback.md: https://workos.com/docs/feedback.md -->

# Portal link

A portal link is a temporary endpoint to initiate an Admin Portal session. It expires five minutes after issuance.

```url title="Example Portal Link URL"
https://setup.workos.com?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

## Generate a Portal Link

Generate a Portal Link scoped to an Organization.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/portal/generate_link" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "organization": "org_01EHZNVPK3SFK441A1RGBFSHRT",
        "intent": "sso"
    }
BODY
```

```js language="js" title="Request" tab="1"
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS('sk_example_123456789');

const { link } = await workos.adminPortal.generateLink({
  organization: 'org_01EHZNVPK3SFK441A1RGBFSHRT',
  intent: 'sso',
});
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.admin_portal.generate_link(organization: "org_01EHZNVPK3SFK441A1RGBFSHRT")
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.admin_portal.generate_link(organization="org_01EHZNVPK3SFK441A1RGBFSHRT")
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.AdminPortal().GenerateLink(context.Background(), &workos.AdminPortalGenerateLinkParams{
		Organization: "org_01EHZNVPK3SFK441A1RGBFSHRT",
	})
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->adminPortal()
    ->generateLink(organization: "org_01EHZNVPK3SFK441A1RGBFSHRT");
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.adminportal.AdminPortalApi.GenerateLinkOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

GenerateLinkOptions options =
    GenerateLinkOptions.builder().organization("org_01EHZNVPK3SFK441A1RGBFSHRT").build();

workos.adminPortal.generateLink(options);
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.AdminPortal.GenerateLinkAsync(new AdminPortalGenerateLinkOptions {
    Organization = "org_01EHZNVPK3SFK441A1RGBFSHRT",
});
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::admin_portal::GenerateLinkParams;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .admin_portal()
        .generate_link(
            GenerateLinkParams {
                organization: "org_01EHZNVPK3SFK441A1RGBFSHRT".into(),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "link": "https://setup.workos.com/init?apiToken=01EHZNVPK3SFK441A1RGBFSHRT"
}
```

:::

## Revoke a Portal Link

Revokes every Portal Link generated for the given organization with the given `external_user_id`, and immediately ends any Admin Portal sessions that were started from those links. Use this when an admin is deprovisioned from your application: unopened links stop working, and their already-open portal sessions are ended. Only links that were generated with an `external_user_id` can be revoked, so pass one to `generate_link` for every admin you may later need to deprovision.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/portal/revoke_link" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "organization": "org_01EHZNVPK3SFK441A1RGBFSHRT",
        "external_user_id": "user_12345"
    }
BODY
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.admin_portal.revoke_link(
  organization: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  external_user_id: "user_12345"
)
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.admin_portal.revoke_link(
    organization="org_01EHZNVPK3SFK441A1RGBFSHRT", external_user_id="user_12345"
)
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.AdminPortal().RevokeLink(context.Background(), &workos.AdminPortalRevokeLinkParams{
		Organization:   "org_01EHZNVPK3SFK441A1RGBFSHRT",
		ExternalUserID: "user_12345",
	})
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->adminPortal()
    ->revokeLink(
        organization: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        externalUserId: "user_12345",
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.adminportal.AdminPortalApi.RevokeLinkOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

RevokeLinkOptions options = RevokeLinkOptions.builder()
                                .organization("org_01EHZNVPK3SFK441A1RGBFSHRT")
                                .externalUserId("user_12345")
                                .build();

workos.adminPortal.revokeLink(options);
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.AdminPortal.RevokeLinkAsync(new AdminPortalRevokeLinkOptions {
    Organization = "org_01EHZNVPK3SFK441A1RGBFSHRT",
    ExternalUserId = "user_12345",
});
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::admin_portal::RevokeLinkParams;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .admin_portal()
        .revoke_link(
            RevokeLinkParams {
                organization: "org_01EHZNVPK3SFK441A1RGBFSHRT".into(),
                external_user_id: "user_12345".into(),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

:::

### POST /portal/generate_link

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `return_url` | string | No | The URL to go to when an admin clicks on your logo in the Admin Portal. If not specified, the return URL configured on the [Admin Portal](https://dashboard.workos.com/admin-portal) page will be used. |
| `success_url` | string | No | The URL to redirect the admin to when they finish setup. If not specified, the success URL configured on the [Admin Portal](https://dashboard.workos.com/admin-portal) page will be used. |
| `organization` | string | Yes | An [Organization](/reference/organization) identifier. |
| `external_user_id` | string | No | The ID of the user in your application the link is generated for. The link and any Admin Portal sessions started from it can later be revoked by this ID, for example when that user is deprovisioned from your application. |
| `intent` | "sso" \| "dsync" \| "audit_logs" \| ... | No | The intent of the Admin Portal. `sso` - Launch Admin Portal for creating SSO connections `dsync` - Launch Admin Portal for creating Directory Sync connections `audit_logs` - Launch Admin Portal for viewing Audit Logs `log_streams` - Launch Admin Portal for creating Log Streams `domain_verification` - Launch Admin Portal for Domain Verification `certificate_renewal` - Launch Admin Portal for renewing SAML Certificates `bring_your_own_key` - Launch Admin Portal for configuring Bring Your Own Key |
| `it_contact_emails` | string[] | No | The email addresses of the IT contacts to grant access to the Admin Portal for the given organization. Accepts up to 20 emails. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `link` | string | An ephemeral link to initiate the Admin Portal. |

### POST /portal/revoke_link

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `organization` | string | Yes | An [Organization](/reference/organization) identifier. |
| `external_user_id` | string | Yes | The `external_user_id` the Portal Links were generated with for this organization. Every matching link is revoked, along with any Admin Portal sessions started from those links. |