---
updatedAt: 2026-09-07T10:20:40.000Z
agentTools:
  projectIndex: https://developer.connecteam.com/llms.txt
---

# Scheduling Rule Policies

List company scheduling rule policies, see which rules apply to an employee, assign users in bulk, and delete a policy.

Scheduling rule policies are named bundles of labor constraints that Job Schedule enforces for assigned employees: weekly hour caps, rest between shifts, and shift-count limits. Create and edit the policy contents in the Connecteam dashboard; this API is the read-and-assign surface. Integrators and the Connecteam agent use the same endpoints. The agent relies on them to help admins discover existing policies and attach the right one during setup.

## Endpoints

| Method | Endpoint                                                                           | Description                                                             |
| :----- | :--------------------------------------------------------------------------------- | :---------------------------------------------------------------------- |
| GET    | /company-policies/v1/scheduling-rule-policies                                      | List company policies and the rules in each one                         |
| GET    | /company-policies/v1/users/{userId}/scheduling-rule-policies                       | Get the policies governing one employee, including custom profile rules |
| GET    | /company-policies/v1/scheduling-rule-policies/{schedulingRulePolicyId}/assignments | List employees assigned to a policy                                     |
| PUT    | /company-policies/v1/scheduling-rule-policies/{schedulingRulePolicyId}/assignments | Assign one or more employees to a policy                                |
| DELETE | /company-policies/v1/scheduling-rule-policies/{schedulingRulePolicyId}             | Delete a policy and all of its assignments                              |

***

## Overview

* A **company policy** is a named, shareable set of rules. List these with the collection GET. Employee-specific custom rules are not included there.
* An employee can also have **custom scheduling rules** set on their profile. Those are returned only by the user GET, as a policy with `isCustomPolicy: true` and no `name`.
* An employee can be governed by a company policy, custom rules, or **both at once**. Where the same rule type appears in both, the **strictest value wins**: the lowest for `max*` types, the highest for `min*` types and `minHoursBetweenShifts`.
* Assignments take effect **immediately**. There is no `effectiveDate` (unlike [pay rule policies](company-policies-pay-rules)).
* An employee can be assigned to **one company scheduling rule policy** at a time. Assigning them to a different policy replaces the previous scheduling-rule assignment. Custom profile rules are not changed.
* Disabled policies (`isEnabled: false`) appear in the company list but are never enforced. You cannot assign employees to a disabled policy.
* Create and edit policy rules in the dashboard. Creating, updating, and setting custom profile rules are not part of this public surface.
* The **Connecteam agent** uses these endpoints to help admins attach the right policy during onboarding and setup.

> 👍 Good to know
>
> **Look up "which rules apply to this employee" with the user GET.** It returns only enabled policies, including custom profile rules. Use the company list to discover policy IDs you can assign.

> 📘 Did you know?
>
> **When several rules of the same type apply, the strictest wins.** If a company policy caps the week at 40 hours and the employee's custom rules cap it at 24, the employee is effectively capped at 24.

***

## Authentication

* **API Key** (`X-API-KEY` header), or
* **OAuth 2.0**

| Scope                     | Operations                                               |
| :------------------------ | :------------------------------------------------------- |
| `company_policies.read`   | GET company policies, GET user policies, GET assignments |
| `company_policies.write`  | PUT assignments                                          |
| `company_policies.delete` | DELETE policy                                            |

These endpoints require the Schedule API plan limitation (`schedulerApi`).

> 📘 Admin permissions
>
> For non-owner admins, assigning a policy also requires permission to add and edit users. Deleting a policy requires permission to manage user details.

***

## Rule Types

Each policy contains one or more rules. Each `type` appears at most once in a policy.

| Type                    | Value means | Typical use                 |
| :---------------------- | :---------- | :-------------------------- |
| `maxHoursPerWeek`       | Hours       | Weekly hour cap             |
| `maxShiftsPerWeek`      | Shift count | Weekly shift cap            |
| `maxHoursPerDay`        | Hours       | Daily hour cap              |
| `maxShiftsPerDay`       | Shift count | Daily shift cap             |
| `minHoursBetweenShifts` | Hours       | Minimum rest between shifts |
| `minHoursPerWeek`       | Hours       | Weekly hour floor           |
| `minShiftsPerWeek`      | Shift count | Weekly shift floor          |

### Rule fields

| Field                        | Type    | Description                                                                                                                                                                       |
| :--------------------------- | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`                       | enum    | One of the rule types above                                                                                                                                                       |
| `value`                      | number  | Threshold: hours for hour-based types, count for shift-based types. Hour values may include a decimal, for example `40.0`                                                         |
| `preventClaim`               | boolean | When `true`, an employee cannot claim an open shift that would break this rule. When `false`, the rule is still reported to admins but does not block a claim. Defaults to `true` |
| `applyToSpecificSchedulerId` | integer | Present when the rule is limited to a single schedule. Omitted when the rule applies across all schedules                                                                         |
| `applyToSpecificShifts`      | object  | Present when the rule is limited to matching shifts (for example one job or a custom field). Omitted when the rule applies to all shifts                                          |

`applyToSpecificShifts` is a filter tree: groups use `{ "op": "and" | "or", "filters": [...] }`, and leaves use `{ "id": "field", "filterType": "is", "filterCriteria": { "value": "string" } }`. Common leaf `id` values are `jobIds` and `customTextField_{fieldId}`.

When reading the tree:

* Evaluate each group's `filters` with its `and` or `or` operator.
* Use `id`, not `field`, for a leaf identifier.
* `filterCriteria.value` is a string, including custom-field option IDs.
* `jobIds` values are Job IDs; `customTextField_{fieldId}` values are custom-field option IDs.
* Other shift fields can use operators such as `contains`.
* If your integration does not support a leaf, flag the rule as unsupported. Do not silently treat an unknown condition as a match.

***

## Get scheduling rule policies

Retrieves all company scheduling rule policies, including disabled ones and the rules configured in each. Custom employee-profile rules are not included. Use the returned `id` when assigning employees.

### Example Request

```bash
curl --request GET \
  --url https://api.connecteam.com/company-policies/v1/scheduling-rule-policies \
  --header 'X-API-KEY: YOUR_API_KEY'
```

### Response

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789",
  "data": {
    "schedulingRulePolicies": [
      {
        "id": 4021,
        "name": "Standard Work Week",
        "isEnabled": true,
        "isDefaultForNewUsers": true,
        "isCustomPolicy": false,
        "rules": [
          {
            "type": "maxHoursPerWeek",
            "value": 40.0,
            "preventClaim": true
          },
          {
            "type": "minHoursBetweenShifts",
            "value": 11.0,
            "preventClaim": false
          }
        ]
      },
      {
        "id": 4022,
        "name": "Night Shift Limits",
        "isEnabled": true,
        "isDefaultForNewUsers": false,
        "isCustomPolicy": false,
        "rules": [
          {
            "type": "maxHoursPerWeek",
            "value": 35.0,
            "preventClaim": true,
            "applyToSpecificSchedulerId": 8817,
            "applyToSpecificShifts": {
              "op": "and",
              "filters": [
                {
                  "op": "or",
                  "filters": [
                    {
                      "id": "customTextField_104",
                      "filterType": "is",
                      "filterCriteria": { "value": "1762437964833" }
                    }
                  ]
                }
              ]
            }
          }
        ]
      }
    ]
  }
}
```

### Response Fields

| Field                                                | Type    | Description                                                                                                        |
| :--------------------------------------------------- | :------ | :----------------------------------------------------------------------------------------------------------------- |
| `data.schedulingRulePolicies`                        | array   | All company scheduling rule policies, enabled and disabled                                                         |
| `data.schedulingRulePolicies[].id`                   | integer | The unique identifier of the policy. Use this when assigning employees                                             |
| `data.schedulingRulePolicies[].name`                 | string  | The name of the company policy                                                                                     |
| `data.schedulingRulePolicies[].isEnabled`            | boolean | Whether the policy is active. When `false`, rules are stored but never enforced, and you cannot assign users to it |
| `data.schedulingRulePolicies[].isDefaultForNewUsers` | boolean | Whether newly created users are automatically assigned to this policy                                              |
| `data.schedulingRulePolicies[].isCustomPolicy`       | boolean | Always `false` on this endpoint                                                                                    |
| `data.schedulingRulePolicies[].rules`                | array   | The scheduling rules in this policy                                                                                |

[API Reference](https://developer.connecteam.com/reference/get_scheduling_rule_policies_company_policies_v1_scheduling_rule_policies_get)

***

## Get user scheduling rule policies

Retrieves the enabled policies currently governing one employee, including custom rules on their profile. This is the lookup for "which scheduling rules apply to this employee".

The response is an array because an employee can have a company policy, custom rules, or both. Custom rules have `isCustomPolicy: true` and no `name`. An employee with no scheduling rules returns an empty array (`200`), not `404`. `404` is returned only when the user does not exist.

### Path Parameters

| Parameter | Type    | Required | Description                       |
| :-------- | :------ | :------- | :-------------------------------- |
| `userId`  | integer | Yes      | The unique identifier of the user |

### Example Request

```bash
curl --request GET \
  --url https://api.connecteam.com/company-policies/v1/users/1045/scheduling-rule-policies \
  --header 'X-API-KEY: YOUR_API_KEY'
```

### Response — company policy and custom rules

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789",
  "data": {
    "schedulingRulePolicies": [
      {
        "id": 4021,
        "name": "Standard Work Week",
        "isEnabled": true,
        "isDefaultForNewUsers": true,
        "isCustomPolicy": false,
        "rules": [
          {
            "type": "maxHoursPerWeek",
            "value": 40.0,
            "preventClaim": true
          }
        ]
      },
      {
        "id": 4098,
        "isEnabled": true,
        "isDefaultForNewUsers": false,
        "isCustomPolicy": true,
        "rules": [
          {
            "type": "maxHoursPerWeek",
            "value": 24.0,
            "preventClaim": true
          }
        ]
      }
    ]
  }
}
```

In this example both sets apply, so the employee is effectively capped at **24** hours per week.

### Response — no scheduling rules

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789",
  "data": {
    "schedulingRulePolicies": []
  }
}
```

[API Reference](https://developer.connecteam.com/reference/get_user_scheduling_rule_policies_company_policies_v1_users__userid__scheduling_rule_policies_get)

***

## List scheduling rule policy assignments

Retrieves the employees currently assigned to a company policy. To go the other way (policies for one employee), use the user GET.

### Path Parameters

| Parameter                | Type    | Required | Description                                         |
| :----------------------- | :------ | :------- | :-------------------------------------------------- |
| `schedulingRulePolicyId` | integer | Yes      | The unique identifier of the scheduling rule policy |

### Query Parameters

| Parameter | Type    | Required | Description                                                                                       |
| :-------- | :------ | :------- | :------------------------------------------------------------------------------------------------ |
| `userId`  | integer | No       | When set, return only this user's assignment. Empty `assignments` when they are not on the policy |
| `limit`   | integer | No       | Page size. Default `100`, maximum `500`                                                           |
| `offset`  | integer | No       | Number of records to skip. Default `0`                                                            |

`paging.offset` is the position **after** the last returned record. Pass it as `offset` on the next request. `paging.total` is the full match count, ignoring pagination.

### Example Request

```bash
curl --request GET \
  --url 'https://api.connecteam.com/company-policies/v1/scheduling-rule-policies/4021/assignments?limit=100&offset=0' \
  --header 'X-API-KEY: YOUR_API_KEY'
```

### Response

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789",
  "paging": {
    "offset": 2,
    "total": 2
  },
  "data": {
    "assignments": [
      {
        "assignmentId": 90233,
        "userId": 1045
      },
      {
        "assignmentId": 90234,
        "userId": 1046
      }
    ]
  }
}
```

[API Reference](https://developer.connecteam.com/reference/list_assignments_company_policies_v1_scheduling_rule_policies__schedulingrulepolicyid__assignments_get)

***

## Assign users to a scheduling rule policy

Assigns one or more employees to the policy. Pass them in `userIds`. The call is **all or nothing**: if any ID does not exist, nothing is assigned.

If a user is already assigned to another scheduling rule policy, that assignment is replaced. Assigning a user who is already on this policy leaves the existing assignment in place. Custom profile rules are not affected.

> 🚧 All or nothing
>
> **If any user ID does not exist, nobody is assigned.** Archived and inactive users count as missing. There is no public unassign: move people to another policy instead.

### Path Parameters

| Parameter                | Type    | Required | Description                                                                |
| :----------------------- | :------ | :------- | :------------------------------------------------------------------------- |
| `schedulingRulePolicyId` | integer | Yes      | The unique identifier of the scheduling rule policy to assign employees to |

### Request Body

| Field     | Type              | Required | Description                                                                                      |
| :-------- | :---------------- | :------- | :----------------------------------------------------------------------------------------------- |
| `userIds` | array of integers | Yes      | 1–100 unique, positive IDs of active users. Archived/inactive users are rejected as not existing |

### Example Request

```bash
curl --request PUT \
  --url https://api.connecteam.com/company-policies/v1/scheduling-rule-policies/4021/assignments \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userIds": [1045, 1046, 1047]
  }'
```

### Response

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789",
  "data": {
    "assignments": [
      { "assignmentId": 90233, "userId": 1045 },
      { "assignmentId": 90234, "userId": 1046 },
      { "assignmentId": 90235, "userId": 1047 }
    ]
  }
}
```

| Field                             | Type    | Description                                                          |
| :-------------------------------- | :------ | :------------------------------------------------------------------- |
| `data.assignments`                | array   | One entry per assigned employee, in the order the user IDs were sent |
| `data.assignments[].assignmentId` | integer | The unique identifier of the assignment record                       |
| `data.assignments[].userId`       | integer | The unique identifier of the assigned user                           |

[API Reference](https://developer.connecteam.com/reference/assign_user_to_policy_company_policies_v1_scheduling_rule_policies__schedulingrulepolicyid__assignments_put)

***

## Delete a scheduling rule policy

Deletes the policy and **all** of its employee assignments. Assigned employees are left without that company policy, so none of its constraints apply to them any more. Custom profile rules are not deleted. This cannot be undone.

> ❗️ Cannot be undone
>
> **Every assignment is removed with the policy.** Custom profile rules stay. To take one person off, assign them to a different policy instead of deleting this one.

### Path Parameters

| Parameter                | Type    | Required | Description                                                   |
| :----------------------- | :------ | :------- | :------------------------------------------------------------ |
| `schedulingRulePolicyId` | integer | Yes      | The unique identifier of the scheduling rule policy to delete |

### Example Request

```bash
curl --request DELETE \
  --url https://api.connecteam.com/company-policies/v1/scheduling-rule-policies/4022 \
  --header 'X-API-KEY: YOUR_API_KEY'
```

### Response

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789"
}
```

[API Reference](https://developer.connecteam.com/reference/delete_scheduling_rule_policy_company_policies_v1_scheduling_rule_policies__schedulingrulepolicyid__delete)

***

## Error Codes

| HTTP Status | Description                                                                                                                                                                                   |
| :---------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`       | Validation failed: non-positive IDs, empty `userIds`, more than 100 IDs, duplicate IDs, or one or more users do not exist. Archived/inactive users are treated as not existing for assignment |
| `401`       | Missing or invalid authentication                                                                                                                                                             |
| `403`       | Missing `company_policies` scope, missing admin permission, or the plan does not include the Schedule API                                                                                     |
| `404`       | Policy not found, the ID is not a scheduling rule policy, or the policy is disabled (assign only)                                                                                             |
| `429`       | Rate limit exceeded                                                                                                                                                                           |

The user GET returns `200` with an empty array when the user has no scheduling rules.

### Example: missing or archived user in an assignment (`400`)

```json
{
  "requestId": "0b1c2d3e-4f56-7890-abcd-ef0123456789",
  "details": {
    "errorMessage": "Request is invalid",
    "errorCode": 1004
  },
  "error": "Users: [999999] not exists",
  "path": "/company-policies/v1/scheduling-rule-policies/4021/assignments"
}
```

The assignment is not changed when any ID in the batch fails validation.

### Example: policy not found or disabled for assignment (`404`)

```json
{
  "detail": "Scheduling rule policy with id 4021 not found"
}
```

Validation errors use top-level `error` (a string or field map). HTTP `404` errors use top-level `detail`.

***

## Integration Example — Assign new hires from an HRIS

```javascript
async function assignUsersToSchedulingPolicy(policyId, userIds) {
  const chunks = [];
  for (let i = 0; i < userIds.length; i += 100) {
    chunks.push(userIds.slice(i, i + 100));
  }

  const assigned = [];
  for (const userIdsChunk of chunks) {
    const res = await fetch(
      `https://api.connecteam.com/company-policies/v1/scheduling-rule-policies/${policyId}/assignments`,
      {
        method: 'PUT',
        headers: {
          'X-API-KEY': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ userIds: userIdsChunk })
      }
    );
    if (!res.ok) {
      const err = await res.json();
      throw new Error(`Assign failed: ${JSON.stringify(err)}`);
    }
    const body = await res.json();
    assigned.push(...body.data.assignments);
  }
  return assigned;
}

// Confirm which rules apply after assign
async function getUserSchedulingRules(userId) {
  const res = await fetch(
    `https://api.connecteam.com/company-policies/v1/users/${userId}/scheduling-rule-policies`,
    { headers: { 'X-API-KEY': 'YOUR_API_KEY' } }
  );
  const body = await res.json();
  return body.data.schedulingRulePolicies;
}

const policiesRes = await fetch(
  'https://api.connecteam.com/company-policies/v1/scheduling-rule-policies',
  { headers: { 'X-API-KEY': 'YOUR_API_KEY' } }
);
const policies = (await policiesRes.json()).data.schedulingRulePolicies;
const standard = policies.find((p) => p.name === 'Standard Work Week');

await assignUsersToSchedulingPolicy(standard.id, [1045, 1046, 1047]);
await getUserSchedulingRules(1045);
```

***

## Notes

> 🚧 Important Considerations
>
> * Create and edit the **contents** of a policy (rule types and values) in the Connecteam dashboard. This API lists those policies and manages who they apply to.
> * Assigning a user to a new company policy **replaces** their previous scheduling-rule assignment. It does not change custom rules on their employee profile.
> * There is no public unassign endpoint. To stop a company policy applying to someone, assign them to a different policy or delete the policy (which removes every assignment).
> * Deleting a policy cannot be undone and immediately drops its constraints for every assigned employee.
> * Pay rule assignments are a different family, with effective dates. See [Pay Rule Policies](company-policies-pay-rules).
> * Job Schedule enforces these rules when shifts are created, claimed, or auto-assigned. See the [Scheduler overview](scheduler-overview).

***

[API Reference](https://developer.connecteam.com/reference/get_scheduling_rule_policies_company_policies_v1_scheduling_rule_policies_get)