Skip to main content

Perform Bulk Operations

Use the Permit API bulk endpoints to sync many users, tenants, resource instances, role assignments, relationship tuples, or roles in one request. This reference is for developers who sync application data into Permit, for example during an initial user import or a policy graph update. It lists each bulk endpoint, its item limit, and a sample request.

Bulk operations in the Permit SDKs

The samples on this page are plain HTTP requests. The Permit SDKs wrap many of the bulk endpoints. See SDK feature parity for the operations each SDK supports. To request a missing SDK operation, ask in the Permit Slack community.

Before you call a bulk endpoint

Every sample on this page uses these placeholders. Replace them before you run a request:

PlaceholderReplace with
{proj_id}Your project ID or key. See Get the project ID and environment ID.
{env_id}Your environment ID or key.
{your_permit_token}A Permit API key with access to the environment. See Get your API key.
...More items of the same shape. Remove ... from the JSON body before you send the request.

Bulk limits

Each bulk call accepts a limited number of items. The following limits apply per call:

Bulk callMaximum items per call
Users3,000
Tenants2,000
Resource instances3,000
Role assignments2,000
Roles2,000
Relationship tuples1,000

If a request contains more items than the limit, the Permit API rejects the whole request with HTTP 403 and the message Number of requested operations (<count>) exceeds maximum allowed (<limit>). A request with no items returns HTTP 400. Split large data sets into several requests.

Bulk calls also count toward the Permit API rate limits. Bulk endpoints are not designed for full or large-volume data migrations. Before a large-scale migration, contact Permit support at support@permit.io.

Bulk operations glossary

Each bulk endpoint replaces many calls to a single-item endpoint:

Single-item operationBulk operationBulk endpoint
Create UserBulk Create UsersPOST /v2/facts/{proj_id}/{env_id}/bulk/users
Replace UserBulk Replace UsersPUT /v2/facts/{proj_id}/{env_id}/bulk/users
Delete UserBulk Delete UsersDELETE /v2/facts/{proj_id}/{env_id}/bulk/users
Create TenantBulk Create TenantsPOST /v2/facts/{proj_id}/{env_id}/bulk/tenants
Delete TenantBulk Delete TenantsDELETE /v2/facts/{proj_id}/{env_id}/bulk/tenants
Create Resource InstanceBulk Replace Resource InstancesPUT /v2/facts/{proj_id}/{env_id}/bulk/resource_instances
Delete Resource InstanceBulk Delete Resource InstancesDELETE /v2/facts/{proj_id}/{env_id}/bulk/resource_instances
Assign RoleBulk Assign RolesPOST /v2/facts/{proj_id}/{env_id}/role_assignments/bulk
Unassign RoleBulk Unassign RolesDELETE /v2/facts/{proj_id}/{env_id}/role_assignments/bulk
Create Relationship TupleBulk Create Relationship TuplesPOST /v2/facts/{proj_id}/{env_id}/relationship_tuples/bulk
Delete Relationship TupleBulk Delete Relationship TuplesDELETE /v2/facts/{proj_id}/{env_id}/relationship_tuples/bulk
Create RoleBulk Create or Replace RolesPUT /v2/schema/{proj_id}/{env_id}/bulk/roles

Bulk user operations

Permit handles authorization, not identity management, so your user data usually lives in an identity provider or your application database and is synced into Permit. Use the bulk user endpoints for the initial user sync or to update many users at once. For a walkthrough of syncing one user, see Sync your first user.

OperationMethod and pathBody
Create usersPOST /v2/facts/{proj_id}/{env_id}/bulk/usersoperations: a list of users. Each user requires key, and accepts email, first_name, last_name, attributes, and role_assignments.
Replace usersPUT /v2/facts/{proj_id}/{env_id}/bulk/usersoperations: a list of users with the same fields as create.
Delete usersDELETE /v2/facts/{proj_id}/{env_id}/bulk/usersidents: a list of user keys.

The following sample creates, replaces, and deletes users:

# Create new users
curl -X POST https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/users \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"operations": [{
"key": "jane_doe",
"email": "jane@coolcompany.com",
"first_name": "Jane",
"last_name": "Doe",
"attributes": {}
}, ...]
}'


# Update existing users
curl -X PUT https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/users \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"operations": [{
"key": "jane_doe",
"email": "test@permit.io",
"first_name": "Jane",
"last_name": "Doe",
"attributes": {}
}, ...]
}'

# Delete existing users
curl -X DELETE https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/users \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"idents": ["jane_doe", ...]
}'

A successful request returns HTTP 200. To confirm the result, open the Directory screen in the Permit dashboard and check that the users appear, or list users with the List Users API.

Bulk tenant operations

Tenants group users in the same way your application groups users under customer accounts (account -> user). When you sync users in bulk, you usually sync their tenants in bulk too.

OperationMethod and pathBody
Create tenantsPOST /v2/facts/{proj_id}/{env_id}/bulk/tenantsoperations: a list of tenants. Each tenant requires key and name, and accepts description and attributes.
Delete tenantsDELETE /v2/facts/{proj_id}/{env_id}/bulk/tenantsidents: a list of tenant keys.

The following sample creates and deletes tenants:

# Create new tenants
curl -X POST https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/tenants \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"operations": [{
"key": "cool_company",
"name": "Cool Company",
"attributes": {}
}, ...]
}'

# Delete existing tenants
curl -X DELETE https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/tenants \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"idents": ["stripeince", ...]
}'

Bulk role assignment

After you sync users, you assign them roles. Bulk role assignment also fits two other cases:

  • You add a role to your policy and assign the role to many existing users.
  • You update the resource roles of many users to keep relationship-based access control (ReBAC) relationships in sync.
OperationMethod and pathBody
Assign rolesPOST /v2/facts/{proj_id}/{env_id}/role_assignments/bulkA JSON list of role assignments. Each assignment requires user and role, and accepts tenant and resource_instance.
Unassign rolesDELETE /v2/facts/{proj_id}/{env_id}/role_assignments/bulkA JSON list of role assignments to remove. Each assignment requires user, role, and tenant, and accepts resource_instance.

The response to a bulk assign request contains assignments_created, the number of role assignments created. The response to a bulk unassign request contains assignments_removed.

The following sample assigns and unassigns roles:

curl -X POST https://api.permit.io/v2/facts/{proj_id}/{env_id}/role_assignments/bulk \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '[{
"user": "892179821739812389327",
"role": "admin",
"tenant": "default"
}, ...]'

curl -X DELETE https://api.permit.io/v2/facts/{proj_id}/{env_id}/role_assignments/bulk \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '[{
"user": "892179821739812389327",
"role": "owner:892179821739812389327",
"tenant": "stripeince"
}, ...]'

Bulk resource operations

A ReBAC policy evaluates resource instances, so the resource instances in Permit must match the resources in your application. Use the single-item resource instance endpoints for event-driven updates. Use the bulk resource instance endpoints when you sync many resource instances at once.

OperationMethod and pathBody
Create or replace resource instancesPUT /v2/facts/{proj_id}/{env_id}/bulk/resource_instancesoperations: a list of resource instances. Each instance requires key, resource, and tenant, and accepts attributes. An instance with the same key and resource as an existing instance replaces the existing instance.
Delete resource instancesDELETE /v2/facts/{proj_id}/{env_id}/bulk/resource_instancesidents: a list of resource instance identifiers in resource:key format, for example repository:react.

The following sample replaces and deletes resource instances:

# Update existing resource instances
curl -X PUT https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/resource_instances \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"operations": [{
"key": "react",
"resource": "repository",
"tenant": "default",
"attributes": {}
}, ...]
}'

# Delete existing resource instances
curl -X DELETE https://api.permit.io/v2/facts/{proj_id}/{env_id}/bulk/resource_instances \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"idents": ["repository:react", ...]
}'

Bulk relationship operations

Relationship tuples connect resource instances in a ReBAC policy graph, for example organization:permitio is the owner of repo:opal. Create or delete one relationship tuple at a time for event-driven updates. Use the bulk relationship tuple endpoints when you change many relationships at once.

OperationMethod and pathBody
Create relationship tuplesPOST /v2/facts/{proj_id}/{env_id}/relationship_tuples/bulkoperations: a list of tuples. Each tuple requires subject, relation, and object, and accepts tenant.
Delete relationship tuplesDELETE /v2/facts/{proj_id}/{env_id}/relationship_tuples/bulkidents: a list of tuples, each with subject, relation, and object.

The following sample creates and deletes relationship tuples:

# Create new relationships
curl -X POST https://api.permit.io/v2/facts/{proj_id}/{env_id}/relationship_tuples/bulk \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"operations": [{
"subject": "organization:permitio",
"relation": "owner",
"object": "repo:opal",
"tenant": "public"
}, ...]
}'

# Delete an existing relationships
curl -X DELETE https://api.permit.io/v2/facts/{proj_id}/{env_id}/relationship_tuples/bulk \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"idents": [{
"subject": "organization:permitio",
"relation": "owner",
"object": "repo:removed_repo"
}, ...]
}'

Bulk role operations

Create or replace roles in bulk

PUT /v2/schema/{proj_id}/{env_id}/bulk/roles creates or replaces many roles in one request. One request can contain both top-level role-based access control (RBAC) roles and ReBAC resource roles for several resources:

  • Each role requires key and name, and accepts permissions, attributes, and extends.
  • Add the optional resource field to create a resource role for that resource. A role without resource is a top-level RBAC role.
  • If a role with the same key exists, the request replaces the existing role.

The response lists the roles the request created in created and the roles it replaced in updated.

curl -X PUT https://api.permit.io/v2/schema/{proj_id}/{env_id}/bulk/roles \
-H "Authorization: Bearer {your_permit_token}" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{
"key": "admin",
"name": "Administrator",
"permissions": ["document:create", "document:delete"]
},
{
"key": "editor",
"name": "Editor",
"resource": "document",
"permissions": ["read", "write"]
}]
}'

Next steps