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

# Custom role

A custom role is an access control resource defined at the organization level. Custom roles allow individual organizations to create roles tailored to their specific needs, in addition to the environment roles that apply across all organizations.

Like environment roles, custom roles can be assigned to [organization memberships](https://workos.com/docs/reference/authkit/organization-membership), [directory users](https://workos.com/docs/directory-sync/identity-provider-role-assignment), and [SSO profiles](https://workos.com/docs/sso/identity-provider-role-assignment). Each custom role has a unique slug identifier within the organization and can have permissions assigned to it.

> **Note:** When listing roles for an organization, both environment roles and custom
> roles are returned in priority order. Environment roles are included because
> they apply to all organizations in your environment.

## Add a permission to a custom role

Add a single permission to a custom role. If the permission is already assigned to the role, this operation has no effect.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles/org-admin/permissions" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "slug": "reports:export"
    }
BODY
```

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

const workos = new WorkOS('sk_example_123456789');

const role = await workos.authorization.addOrganizationRolePermission(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  'org-billing-admin',
  { permissionSlug: 'reports:export' },
);
```

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

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

WorkOS.client.authorization.add_organization_role_permission(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  slug: "org-admin",
  body_slug: "reports:export"
)
```

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

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

client.authorization.add_organization_role_permission(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT",
    slug="org-admin",
    body_slug="reports:export",
)
```

```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.Authorization().AddOrganizationRolePermission(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin", &workos.AuthorizationAddOrganizationRolePermissionParams{
		Slug: "reports:export",
	})
	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
    ->authorization()
    ->addOrganizationRolePermission(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        slug: "org-admin",
        bodySlug: "reports:export",
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.authorization.AuthorizationApi.AddOrganizationRolePermissionOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

AddOrganizationRolePermissionOptions options =
    AddOrganizationRolePermissionOptions.builder().slug("reports:export").build();

workos.authorization.addOrganizationRolePermission(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin", 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.Authorization.AddOrganizationRolePermissionAsync("org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin",
                                                              new AuthorizationAddOrganizationRolePermissionOptions {
                                                                  Slug = "reports:export",
                                                              });
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::authorization::AddOrganizationRolePermissionParams;

#[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
        .authorization()
        .add_organization_role_permission(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            "org-admin",
            AddOrganizationRolePermissionParams {
                slug: "reports:export".into(),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "slug": "org-admin",
  "object": "role",
  "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
  "name": "Organization Admin",
  "description": "Can manage all resources",
  "type": "OrganizationRole",
  "resource_type_slug": "organization",
  "permissions": [
    "reports:export"
  ],
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Create a custom role

Create a new custom role. The role will be specific to the organization and can be assigned to organization memberships.

The `slug` must be unique within the organization, begin with `org-`, and contain only lowercase letters, numbers, hyphens, and underscores.

> **Note:** New roles are placed at the bottom of the organization's priority order.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "slug": "org-billing-admin",
        "name": "Billing Administrator",
        "description": "Can manage billing and invoices"
    }
BODY
```

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

const workos = new WorkOS('sk_example_123456789');

const role = await workos.authorization.createOrganizationRole(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  {
    slug: 'org-billing-admin',
    name: 'Billing Administrator',
    description: 'Can manage billing and invoices',
  },
);
```

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

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

WorkOS.client.authorization.create_organization_role(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  name: "Billing Administrator"
)
```

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

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

client.authorization.create_organization_role(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT", name="Billing Administrator"
)
```

```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.Authorization().CreateOrganizationRole(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", &workos.AuthorizationCreateOrganizationRoleParams{
		Name: "Billing Administrator",
	})
	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
    ->authorization()
    ->createOrganizationRole(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        name: "Billing Administrator",
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.authorization.AuthorizationApi.CreateOrganizationRoleOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

CreateOrganizationRoleOptions options =
    CreateOrganizationRoleOptions.builder().name("Billing Administrator").build();

workos.authorization.createOrganizationRole("org_01EHZNVPK3SFK441A1RGBFSHRT", 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.Authorization.CreateOrganizationRoleAsync("org_01EHZNVPK3SFK441A1RGBFSHRT",
                                                       new AuthorizationCreateOrganizationRoleOptions {
                                                           Name = "Billing Administrator",
                                                       });
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::authorization::CreateOrganizationRoleParams;

#[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
        .authorization()
        .create_organization_role(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            CreateOrganizationRoleParams {
                name: "Billing Administrator".into(),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "slug": "org-billing-admin",
  "object": "role",
  "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
  "name": "Billing Administrator",
  "description": "Can manage billing and invoices",
  "type": "OrganizationRole",
  "resource_type_slug": "organization",
  "permissions": [
    "posts:read",
    "posts:write"
  ],
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Delete a custom role

Delete an existing custom role. The role must not have any active assignments or [IdP group role mappings](https://workos.com/docs/rbac/idp-role-assignment).

If the role has active assignments, you will receive a `409 Conflict` error with code `role_has_assignments`. If the role has group role mappings, you will receive a `409 Conflict` error with code `role_has_group_role_mappings`.

:::code-group{title="Request"}

```bash language="curl"
curl --request DELETE \
  --url https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles/org-billing-admin \
  --header "Authorization: Bearer sk_example_123456789"
```

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

const workos = new WorkOS('sk_example_123456789');

await workos.authorization.deleteOrganizationRole(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  'org-billing-admin',
);
```

```rb language="ruby"
require "workos"

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

WorkOS.client.authorization.delete_organization_role(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  slug: "org-admin"
)
```

```py language="python"
from workos import WorkOSClient

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

client.authorization.delete_organization_role(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT", slug="org-admin"
)
```

```go language="go"
package main

import (
	"context"

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

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

	_, err := client.Authorization().DeleteOrganizationRole(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin")
	if err != nil {
		panic(err)
	}
}
```

```php language="php"
<?php

use WorkOS\WorkOS;

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

$workos
    ->authorization()
    ->deleteOrganizationRole(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        slug: "org-admin",
    );
```

```java language="java"
import com.workos.WorkOS;

WorkOS workos = new WorkOS("sk_example_123456789");

workos.authorization.deleteOrganizationRole(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin");
```

```cs language="dotnet"
using WorkOS;

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

await client.Authorization.DeleteOrganizationRoleAsync("org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin");
```

```rust language="rust"
use workos::Client;

#[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
        .authorization()
        .delete_organization_role(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            "org-admin"
        )
        .await?;

    Ok(())
}
```

:::

## Get a custom role

Retrieve a role that applies to an organization by its slug. This can return either an environment role or a custom role.

:::code-group

```bash language="curl" title="Request" tab="1"
curl "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles/org-billing-admin" \
  --header "Authorization: Bearer sk_example_123456789"
```

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

const workos = new WorkOS('sk_example_123456789');

const role = await workos.authorization.getOrganizationRole(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  'org-billing-admin',
);
```

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

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

WorkOS.client.authorization.get_organization_role(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  slug: "org-billing-admin"
)
```

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

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

client.authorization.get_organization_role(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT", slug="org-billing-admin"
)
```

```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.Authorization().GetOrganizationRole(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-billing-admin")
	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
    ->authorization()
    ->getOrganizationRole(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        slug: "org-billing-admin",
    );
```

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

WorkOS workos = new WorkOS("sk_example_123456789");

workos.authorization.getOrganizationRole(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-billing-admin");
```

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

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

await client.Authorization.GetOrganizationRoleAsync("org_01EHZNVPK3SFK441A1RGBFSHRT", "org-billing-admin");
```

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

#[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
        .authorization()
        .get_organization_role(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            "org-billing-admin"
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "slug": "org-billing-admin",
  "object": "role",
  "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
  "name": "Billing Manager",
  "description": "Can view and export billing reports",
  "type": "OrganizationRole",
  "resource_type_slug": "organization",
  "permissions": [
    "posts:read",
    "posts:write"
  ],
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## List custom roles

Get a list of all roles that apply to an organization. This includes both environment roles and custom roles, returned in priority order.

:::code-group

```bash language="curl" title="Request" tab="1"
curl "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles" \
  --header "Authorization: Bearer sk_example_123456789"
```

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

const workos = new WorkOS('sk_example_123456789');

const roles = await workos.authorization.listOrganizationRoles(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
);
```

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

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

WorkOS.client.authorization.list_organization_roles(organization_id: "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.authorization.list_organization_roles(
    organization_id="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.Authorization().ListOrganizationRoles(context.Background(), "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
    ->authorization()
    ->listOrganizationRoles(organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT");
```

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

WorkOS workos = new WorkOS("sk_example_123456789");

workos.authorization.listOrganizationRoles("org_01EHZNVPK3SFK441A1RGBFSHRT");
```

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

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

await client.Authorization.ListOrganizationRolesAsync("org_01EHZNVPK3SFK441A1RGBFSHRT");
```

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

#[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
        .authorization()
        .list_organization_roles("org_01EHZNVPK3SFK441A1RGBFSHRT")
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "object": "list",
  "data": [
    {
      "slug": "admin",
      "object": "role",
      "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
      "name": "Admin",
      "description": "Can manage all resources",
      "type": "EnvironmentRole",
      "resource_type_slug": "organization",
      "permissions": [
        "posts:read",
        "posts:write"
      ],
      "created_at": "2026-01-15T12:00:00.000Z",
      "updated_at": "2026-01-15T12:00:00.000Z"
    }
  ]
}
```

:::

## Remove a permission from a custom role

Remove a single permission from a custom role by its slug.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request DELETE \
  --url "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles/org-admin/permissions/documents:read" \
  --header "Authorization: Bearer sk_example_123456789"
```

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

const workos = new WorkOS('sk_example_123456789');

const role = await workos.authorization.removeOrganizationRolePermission(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  'org-billing-admin',
  'reports:export',
);
```

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

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

WorkOS.client.authorization.remove_organization_role_permission(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  slug: "org-admin",
  permission_slug: "documents:read"
)
```

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

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

client.authorization.remove_organization_role_permission(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT",
    slug="org-admin",
    permission_slug="documents:read",
)
```

```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.Authorization().RemoveOrganizationRolePermission(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin", "documents:read")
	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
    ->authorization()
    ->removeOrganizationRolePermission(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        slug: "org-admin",
        permissionSlug: "documents:read",
    );
```

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

WorkOS workos = new WorkOS("sk_example_123456789");

workos.authorization.removeOrganizationRolePermission(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin", "documents:read");
```

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

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

await client.Authorization.RemoveOrganizationRolePermissionAsync("org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin",
                                                                 "documents:read");
```

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

#[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
        .authorization()
        .remove_organization_role_permission(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            "org-admin",
            "documents:read"
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "slug": "admin",
  "object": "role",
  "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
  "name": "Admin",
  "description": "Can manage all resources",
  "type": "EnvironmentRole",
  "resource_type_slug": "organization",
  "permissions": [
    "posts:read",
    "posts:write"
  ],
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Set permissions for a custom role

Replace all permissions assigned to a custom role. This operation removes any existing permissions and assigns the provided permissions.

To remove all permissions from a role, pass an empty array.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request PUT \
  --url "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles/org-admin/permissions" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "permissions": [
            "billing:read",
            "billing:write",
            "invoices:manage",
            "reports:view"
        ]
    }
BODY
```

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

const workos = new WorkOS('sk_example_123456789');

const role = await workos.authorization.setOrganizationRolePermissions(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  'org-billing-admin',
  {
    permissions: [
      'billing:read',
      'billing:write',
      'invoices:manage',
      'reports:view',
    ],
  },
);
```

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

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

WorkOS.client.authorization.set_organization_role_permissions(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  slug: "org-admin",
  permissions: ["billing:read", "billing:write", "invoices:manage", "reports:view"]
)
```

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

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

client.authorization.set_organization_role_permissions(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT",
    slug="org-admin",
    permissions=["billing:read", "billing:write", "invoices:manage", "reports:view"],
)
```

```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.Authorization().SetOrganizationRolePermissions(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin", &workos.AuthorizationSetOrganizationRolePermissionsParams{
		Permissions: []any{"billing:read", "billing:write", "invoices:manage", "reports:view"},
	})
	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
    ->authorization()
    ->setOrganizationRolePermissions(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        slug: "org-admin",
        permissions: [
            "billing:read",
            "billing:write",
            "invoices:manage",
            "reports:view",
        ],
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.authorization.AuthorizationApi.SetOrganizationRolePermissionsOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

SetOrganizationRolePermissionsOptions options =
    SetOrganizationRolePermissionsOptions.builder()
        .permissions(
            List.of("billing:read", "billing:write", "invoices:manage", "reports:view"))
        .build();

workos.authorization.setOrganizationRolePermissions(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin", 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.Authorization.SetOrganizationRolePermissionsAsync(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-admin",
    new AuthorizationSetOrganizationRolePermissionsOptions {
        Permissions = new[] { "billing:read", "billing:write", "invoices:manage", "reports:view" },
    });
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::authorization::SetOrganizationRolePermissionsParams;

#[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
        .authorization()
        .set_organization_role_permissions(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            "org-admin",
            SetOrganizationRolePermissionsParams {
                permissions: vec![
                    "billing:read".into(),
                    "billing:write".into(),
                    "invoices:manage".into(),
                    "reports:view".into(),
                ],
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "slug": "org-admin",
  "object": "role",
  "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
  "name": "Organization Admin",
  "description": "Can manage all resources",
  "type": "OrganizationRole",
  "resource_type_slug": "organization",
  "permissions": [
    "billing:read",
    "billing:write",
    "invoices:manage",
    "reports:view"
  ],
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Update a custom role

Update an existing custom role. Only the fields provided in the request body will be updated.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request PATCH \
  --url "https://api.workos.com/authorization/organizations/org_01EHZNVPK3SFK441A1RGBFSHRT/roles/org-billing-admin" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "name": "Finance Administrator",
        "description": "Can manage all financial operations"
    }
BODY
```

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

const workos = new WorkOS('sk_example_123456789');

const role = await workos.authorization.updateOrganizationRole(
  'org_01EHZNVPK3SFK441A1RGBFSHRT',
  'org-billing-admin',
  {
    name: 'Finance Administrator',
    description: 'Can manage all financial operations',
  },
);
```

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

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

WorkOS.client.authorization.update_organization_role(
  organization_id: "org_01EHZNVPK3SFK441A1RGBFSHRT",
  slug: "org-billing-admin"
)
```

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

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

client.authorization.update_organization_role(
    organization_id="org_01EHZNVPK3SFK441A1RGBFSHRT", slug="org-billing-admin"
)
```

```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.Authorization().UpdateOrganizationRole(context.Background(), "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-billing-admin")
	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
    ->authorization()
    ->updateOrganizationRole(
        organizationId: "org_01EHZNVPK3SFK441A1RGBFSHRT",
        slug: "org-billing-admin",
    );
```

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

WorkOS workos = new WorkOS("sk_example_123456789");

workos.authorization.updateOrganizationRole(
    "org_01EHZNVPK3SFK441A1RGBFSHRT", "org-billing-admin");
```

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

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

await client.Authorization.UpdateOrganizationRoleAsync("org_01EHZNVPK3SFK441A1RGBFSHRT", "org-billing-admin");
```

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

#[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
        .authorization()
        .update_organization_role(
            "org_01EHZNVPK3SFK441A1RGBFSHRT",
            "org-billing-admin"
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "slug": "org-billing-admin",
  "object": "role",
  "id": "role_01EHQMYV6MBK39QC5PZXHY59C3",
  "name": "Finance Administrator",
  "description": "Can manage all financial operations",
  "type": "OrganizationRole",
  "resource_type_slug": "organization",
  "permissions": [
    "posts:read",
    "posts:write"
  ],
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

### Organization Role

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | "role" | Yes | Distinguishes the Role object. |
| `id` | string | Yes | Unique identifier of the Role. |
| `name` | string | Yes | A descriptive name for the Role. This field does not need to be unique. |
| `slug` | string | Yes | A unique key to reference the role within the organization. Must be lowercase and contain only letters, numbers, hyphens, and underscores. |
| `description` | string \| null | Yes | A description for the Role. |
| `permissions` | string[] | Yes | A list of permission slugs assigned to the role. |
| `type` | "OrganizationRole" | Yes | The type of Role. For custom roles, this is always `OrganizationRole`. |
| `resource_type_slug` | string | Yes | The slug of the resource type the role is scoped to. |
| `created_at` | string | Yes | The timestamp when the Role was created. |
| `updated_at` | string | Yes | The timestamp when the Role was last updated. |

### POST /authorization/organizations/{organizationId}/roles/{slug}/permissions

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |
| `slug` | string | Yes | The slug of the permission to add to the role. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `role` | object | Distinguishes the role object. |

### POST /authorization/organizations/{organizationId}/roles

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `slug` | string | No | A unique key to reference the role within the organization. Must begin with `org-` and contain only lowercase letters, numbers, hyphens, and underscores. |
| `name` | string | Yes | A descriptive name for the role. |
| `description` | string | No | An optional description for the role. |
| `resource_type_slug` | string | No | The slug of the resource type the role is scoped to. |

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `role` | object | Distinguishes the role object. |

### DELETE /authorization/organizations/{organizationId}/roles/{slug}

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |
| `slug` | string | Yes | The slug of the role. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `empty` | empty | Returns an empty response on success. |

### GET /authorization/organizations/{organizationId}/roles/{slug}

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |
| `slug` | string | Yes | The unique slug of the role to retrieve. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `role` | object | Distinguishes the role object. |

### GET /authorization/organizations/{organizationId}/roles

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `list` | object |  |

### DELETE /authorization/organizations/{organizationId}/roles/{slug}/permissions/{permissionSlug}

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |
| `slug` | string | Yes | The slug of the role. |
| `permissionSlug` | string | Yes | The slug of the permission to remove. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `role` | object | Distinguishes the role object. |

### PUT /authorization/organizations/{organizationId}/roles/{slug}/permissions

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `permissions` | string[] | Yes | An array of permission slugs to assign to the role. This replaces all existing permissions. |

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |
| `slug` | string | Yes | The slug of the role. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `role` | object | Distinguishes the role object. |

### PATCH /authorization/organizations/{organizationId}/roles/{slug}

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | The new name for the role. |
| `description` | string | No | The new description for the role. Set to `null` to remove the description. |

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | string | Yes | The ID of the organization. |
| `slug` | string | Yes | The slug of the role. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `role` | object | Distinguishes the role object. |