> For the complete documentation index, see [llms.txt](https://help.security.gallagher.com/knowledge-hub/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.security.gallagher.com/knowledge-hub/developer/rest-api/schedules.md).

# Schedules

These methods give you read/write access to seven types of schedules. Avigilon Engage schedules are not included.

The main entry point is a paginated search that gives you any number of schedules. The most useful field on a schedule is a list of state changes and the days and times that those changes should occur.

There is also a method that allows creating new schedules.

Schedules are new to 8.50.

### Licensing

The schedules APIs are licensed a little differently from most others. RESTCardholders gives you Cardholder Access Schedules, while RESTStatus and RESTOverrides give you all schedule types.

## Search schedules

> This returns a summary of the schedules matching your search criteria.\
> \
> The result will contain no more than 100 or 1000, depending on your version, or as many as\
> you asked for; you should follow the \`next\` link, if it is present, to\
> collect the next batch.\
> \
> If your result set is empty it means your operator does not have the privilege to view\
> schedules, such as 'View Schedules', 'Edit Schedules', or 'Schedule Access Zone'.  Perhaps\
> there are no schedules in the divisions in which your operator has privileges, or your\
> operator has no privileges at all.\
> \
> Note that the privilege 'Schedule Access Zone' only lets you see Access Zone schedules, not\
> the other six types.\
> \
> When you have loaded them all there will be no \`next\` link.\
> \
> Do not code this URL into your application.  Take it from the 'href' field in the\
> \`features.schedules.schedules\` section of \`/api\`.\
> \
> Added in 8.50.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Schedules","description":"These methods give you read/write access to seven types of schedules.  Avigilon Engage schedules\nare not included.\n\nThe main entry point is a paginated search that gives you any number of schedules.  The most\nuseful field on a schedule is a list of state changes and the days and times that those changes\nshould occur.\n\nThere is also a method that allows creating new schedules.\n\nSchedules are new to 8.50.\n\n## Licensing\n\nThe schedules APIs are licensed a little differently from most others.  RESTCardholders gives\nyou Cardholder Access Schedules, while RESTStatus and RESTOverrides give you all schedule types."}],"servers":[{"url":"https://127.0.0.1:8904"}],"security":[{"API_key":[]},{"basic":[]}],"components":{"securitySchemes":{"API_key":{"type":"apiKey","name":"Authorization","in":"header","description":"\nClients authenticate by including a pre-shared API key in the `Authorization` header of each\nrequest after an authorisation method of `GGL-API-KEY`:\n\n`Authorization: GGL-API-KEY C774-B01F-D695-AA4B-215F-A158-AC22-ADEB`\n\nFor a fuller description see [API authentication](api-authentication).\n"},"basic":{"type":"http","scheme":"basic","description":"This is HTTP Basic authentication using a blank username and the API key as the password.\n\nExample:  `Authorization: Basic OkM3NzQtQjAxRi1ENjk1LUFBNEItMjE1Ri1BMTU4LUFDMjItQURFQg==`\n\nThat example is equivalent to the example in the description of the api_Key method:\nprepending a colon to the API key beginning with `C774` then encoding it into Base64\nproduces the 56 characters beginning with `OkM3`.\n\nThe colon is a separator between a username, which is blank in our case, and the password,\nwhich is our API key.\n\nFor a fuller description see [API authentication](api-authentication)\n"}},"parameters":{"sort":{"name":"sort","in":"query","schema":{"type":"string","enum":["id","name","-id","-name"]},"required":false,"description":"Changes the sort field between database ID and name.\n\nIf you prefix `id` or `name` with a minus sign (ASCII 45), the sort order is reversed.\n\nThere are two very strong reasons to sort by ID:\n\n1. Sorting by name carries a risk of missing or duplicating objects if your result set spans\n   multiple pages and another operator is editing the database while your REST client is\n   enumerating them.  This is known as \"page drift.\"  Sorting by ID does not carry that risk.\n2. Following a `next` link is _dramatically_ quicker when sorting by ID.\n\nWe _strongly_ recommend sorting by ID.  In case you were still in doubt, we will do that by\ndefault in a future version of Command Centre.\n\nThe server silently ignores anything except the options listed here.\n"},"top":{"name":"top","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"Limits the results to no more than this many items per page.\n\nOlder versions of Command Centre returned 100 items per page in the absence of this parameter.  That is acceptable for GUI\napplications that will only display the first page, but for integrations that intend to\nproceed through the entire database it causes a lot of chatter.\n\n8.70 and later versions will default to 1000 items per request.  This is about where a graph\nof throughput versus page size begins to level out.\n"},"name":{"name":"name","in":"query","schema":{"type":"string"},"description":"Limits the returned items to those with a name that matches this string.  Without surrounding\nquotes or a percent sign or underscore, it is a substring match; surround the parameter with\ndouble quotes `\"...\"` for an exact match.  Without quotes, a percent sign `%` will match any\nsubstring and an underscore will match any single character.\n\nThe search is always case-insensitive.  Results are undefined if you do a substring search for\nthe empty string (`name=`).  You will receive no items if you search for those with no name\n(`name=\"\"`), as all items must have a name.\n\nSearch parameters are ANDed together.\n"},"division":{"name":"division","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"Limits the returned items to those that are in these divisions.\n\nThat includes all the items in those divisions' child divisions, because Command Centre treats\nitems as though they are also in their division's parent, and its parent, and so on up to the\nroot division.\n\nSeparate the IDs of the divisions in you are interested with commas.  Item IDs are short\nalphanumeric strings, not URLs.\n\nResults are undefined if you provide an ID that is not in the form of a division ID.\n\nSearch parameters are ANDed together.\n"},"directDivision":{"name":"directDivision","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"Restricts items to those whose division is in this list.\n\nUnlike `division=`, it does not follow ancestry.  That means it will limit the search to items\nthat are directly assigned to the divisions you list, whereas `division` (without the\n`direct`) will also include items that are assigned to their descendants.\n\nList the IDs of the divisions you are interested in separated by commas.  Item IDs are short\nalphanumeric strings, not URLs.\n\nBecause this is the first query parameter we added that contains a capital letter, this will\nbe the first time you have had to think about case sensitivity.  `directDivision` works,\n`directdivision` does not.\n\nResults are undefined if you provide an ID that is not in the form of a division ID.\n\nSearch parameters are ANDed together.\n\nAdded in 9.20.\n"},"description":{"name":"description","in":"query","required":false,"schema":{"type":"string"},"description":"Limits the returned items to those with a description that matches this string.  By default it\nis a substring match; surround it with double quotes `\"...\"` for an exact match.  A `_` will\nmatch any single character, and a `%` will match any substring.  With or without quotes,\nhaving either of these wildcards in the string will anchor it at both ends as though you had\nsurrounded it with `\"`.\n\nThe search is always case-insensitive.  Results are undefined if you search for the empty\nstring (`description=` or `description=\"\"`).\n\nSearch parameters are ANDed together.\n"},"pos":{"name":"pos","in":"query","required":false,"schema":{"type":"integer"},"description":"Reserved for internal use.  You may see it in URLs you receive from the server, but you must never add it yourself."},"skip":{"name":"skip","in":"query","required":false,"schema":{"type":"integer"},"description":"Reserved for internal use.  Do not add it to your queries."}},"schemas":{"ScheduleSearch":{"title":"Schedule search","type":"object","properties":{"results":{"type":"array","description":"An array of schedule summaries.","items":{"$ref":"#/components/schemas/ScheduleSummary"}},"next":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"}},"description":"The link to the next page.  Absent if you have retrieved them all."}},"description":"An array of schedule summaries, and a `next` link for more."},"ScheduleSummary":{"title":"Schedule summary","type":"object","properties":{"href":{"type":"string","description":"A link to a [schedule detail](models#scheduledetail).\n","format":"uri-reference"},"name":{"type":"string"}},"description":"A [schedule search](schedules#get-api-schedules) returns an array of these.  It is a\nsubset of what you get from a detail page at `/api/schedules/{id}` (linked as the href in this\nobject).\n"}}},"paths":{"/api/schedules":{"get":{"tags":["Schedules"],"summary":"Search schedules","description":"This returns a summary of the schedules matching your search criteria.\n\nThe result will contain no more than 100 or 1000, depending on your version, or as many as\nyou asked for; you should follow the `next` link, if it is present, to\ncollect the next batch.\n\nIf your result set is empty it means your operator does not have the privilege to view\nschedules, such as 'View Schedules', 'Edit Schedules', or 'Schedule Access Zone'.  Perhaps\nthere are no schedules in the divisions in which your operator has privileges, or your\noperator has no privileges at all.\n\nNote that the privilege 'Schedule Access Zone' only lets you see Access Zone schedules, not\nthe other six types.\n\nWhen you have loaded them all there will be no `next` link.\n\nDo not code this URL into your application.  Take it from the 'href' field in the\n`features.schedules.schedules` section of `/api`.\n\nAdded in 8.50.\n","parameters":[{"$ref":"#/components/parameters/sort"},{"$ref":"#/components/parameters/top"},{"$ref":"#/components/parameters/name"},{"$ref":"#/components/parameters/division"},{"$ref":"#/components/parameters/directDivision"},{"$ref":"#/components/parameters/description"},{"name":"fields","description":"This instructs the server to return only these fields in the search results.  The values you can list are the same as the field\nnames in the details page.  Using this you can return everything on the summary page that you\nwould find on the details page.  Separate values with commas.\n\nUse the special value `defaults` to return the fields you would have received had you not given\nthe parameter at all.  Obviously only do that if you have more to add.\n\nTreat the string matches as case-sensitive.\n","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","enum":["href","name","description","division","notes","type","dayCategories","defaults"]}}},{"$ref":"#/components/parameters/pos"},{"$ref":"#/components/parameters/skip"}],"responses":{"200":{"description":"Success.  See the note in the description about privileges if your result set is empty.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleSearch"}}}},"403":{"description":"The site does not have the RESTStatus, RESTOverrides, or RESTCardholders licence.\n"}}}}}}
```

## Create a schedule

> This is how you create a new schedule.\
> \
> Your POST needs a body containing JSON in the same form received from a GET, containing a\
> division and type, and (if you want it to be useful) \`dayCategories\`.\
> \
> Do not code this URL into your application.  Take it from the 'href' field in the\
> \`features.schedules.schedules\` section of \`/api\`.\
> \
> Added in 8.50.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Schedules","description":"These methods give you read/write access to seven types of schedules.  Avigilon Engage schedules\nare not included.\n\nThe main entry point is a paginated search that gives you any number of schedules.  The most\nuseful field on a schedule is a list of state changes and the days and times that those changes\nshould occur.\n\nThere is also a method that allows creating new schedules.\n\nSchedules are new to 8.50.\n\n## Licensing\n\nThe schedules APIs are licensed a little differently from most others.  RESTCardholders gives\nyou Cardholder Access Schedules, while RESTStatus and RESTOverrides give you all schedule types."}],"servers":[{"url":"https://127.0.0.1:8904"}],"security":[{"API_key":[]},{"basic":[]}],"components":{"securitySchemes":{"API_key":{"type":"apiKey","name":"Authorization","in":"header","description":"\nClients authenticate by including a pre-shared API key in the `Authorization` header of each\nrequest after an authorisation method of `GGL-API-KEY`:\n\n`Authorization: GGL-API-KEY C774-B01F-D695-AA4B-215F-A158-AC22-ADEB`\n\nFor a fuller description see [API authentication](api-authentication).\n"},"basic":{"type":"http","scheme":"basic","description":"This is HTTP Basic authentication using a blank username and the API key as the password.\n\nExample:  `Authorization: Basic OkM3NzQtQjAxRi1ENjk1LUFBNEItMjE1Ri1BMTU4LUFDMjItQURFQg==`\n\nThat example is equivalent to the example in the description of the api_Key method:\nprepending a colon to the API key beginning with `C774` then encoding it into Base64\nproduces the 56 characters beginning with `OkM3`.\n\nThe colon is a separator between a username, which is blank in our case, and the password,\nwhich is our API key.\n\nFor a fuller description see [API authentication](api-authentication)\n"}},"schemas":{"ScheduleDetail":{"title":"Schedule detail","description":"[/api/schedules/{id}](schedules#get-api-schedules-id-) returns one of these, and you put\n one of these in the body of a POST or PATCH to create or edit a schedule.\n","allOf":[{"$ref":"#/components/schemas/ScheduleSummary"},{"type":"object","properties":{"description":{"type":"string"},"division":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"}},"description":"The division containing this schedule.  It is possible to change a schedule's\ndivision after creating it.\n"},"notes":{"type":"string","description":"Because of their potential size, notes are only available by request.  Use the 'fields'\nparameter:\n\n`?fields=defaults,notes,...`\n"},"type":{"type":"object","properties":{"type":{"type":"string","enum":["accessZoneSchedule","accessSchedule","alarmZoneSchedule","outputSchedule","notificationSchedule","hVLFSchedule","elevatorKioskControlSchedule"]}},"description":"This block contains a string field `type` which will (in the server's response to a\nGET) or must (in the body of your POST) be one of the seven schedule types.  It is not a\nvalid field in a PATCH, because you cannot change the type of an existing schedule.\n\nElevator kiosk control schedules arrived in 8.60.\n"},"dayCategories":{"description":"This is the part of the schedule that controls when changes occur on its scheduled\nitems.\n\nIt is an array of objects, each containing a day category and an array of times.  The\nday category picks days of the year, and the `times` array sets what will happen and\nat what times on those days.\n\nIn the body of your POST:\n\n  * The `time` field of each object inside `times` must be a string of the form\n    `HH:MM` between 00:00 and 23:59.  If you find another format that works (four\n    zeroes, for example), it may not work in future versions.\n\n  * Each day category must have an entry at 00:00.  This means an item does not need\n    to search back in time to find what state it should be in when it first comes\n    online.\n\n  * Each day category cannot have more than one entry at the same time.\n\nIf you receive a 400 response to your POST or PATCH and one of those rules is the\ncause, the body of the response should contain a reminder.\n\nThe `state` field is an array describing what should happen at that time.  It is\ncomparable to the `statusFlags` arrays on access zones, alarm zones, outputs, and\nfence zones.  For most schedule types it will contain only one word, but the extra\nflag `usePin` may accompany access zone state changes.\n\nWhen building your JSON, treat these string comparisons as case-sensitive.\n\nAll schedule types can have a state change called 'cancelUntimedOverrides'.  That sets\nan item back to its scheduled state if it was under the effect of an override with no\nend time.\n\nOther than that, each schedule type has its own set of state changes:\n\n  * An Access Schedule, also known as a Cardholder Access Schedule, controls the\n    ability of the members of an access group to pass into an access zone.  The valid\n    states are `grant` and `deny`.  Note that 'deny' is a misnomer:  a cardholder will\n    gain access through a door if they are a member of a different access group that\n    still has access.\n\n  * An Access Zone Schedule controls the mode of an access zone.  The valid states are\n    the same as the [zone's status flags](models#accesszonedetail):  `secure`,\n    `dualAuth`, `codeOrCard`, or `free`.  The extra flag `usePin` means the same here\n    as it does in the status flags:  people will need their PINs at readers and alarm\n    terminals.\n\n  * An Alarm Zone Schedule switches an alarm zone between its four modes: `set`,\n    `unset`, `user1`, and `user2`.  Use the words `user1` and `user2` here even if you\n    have renamed them in the server properties.\n\n  * An Output Schedule can be `on` or `off`, plain and simple.\n\n  * A Notification Schedule controls when notifications go out.  They can make sure\n    that notifications go to the people who are on shift, and they can prevent\n    bothering people at night.  Like the access and output schedules it is binary, but\n    the valid states are called `notificationEnabled` and `notificationDisabled`.\n\n  * A HV/LF Schedule controls the voltage on an electric fence.  'lowFeel' mode allows\n    detection without the deterrent of `highVoltage`.\n\nThis example sets an access zone to secure mode between 7.30am and 6:00pm on work\ndays, and secure plus PIN mode at all other times.\n","type":"array","items":{"type":"object","properties":{"dayCategory":{"type":"object","properties":{"name":{"type":"string","readOnly":true},"href":{"type":"string","format":"uri-reference","description":"The API's identifier for an item."}}},"times":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string","pattern":"^[012][0-9]:[0-6][0-9]$"},"state":{"type":"array","items":{"type":"string"}}}}}}}},"scheduledItems":{"readOnly":true,"description":"An array containing the names and hrefs of all the items that this schedule controls\nand that the operator has the privilege to view.\n\nThis is generated data.  A schedule resides in the configuration of the items that use\nit, rather than the other way around, so this block is a handy aggregation of the\ninverse of those relationships.  As such it is read-only:  the server will ignore it\nif you send it in a POST or a PATCH.\n","type":"array","items":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"},"name":{"type":"string"}}}}}}]},"ScheduleSummary":{"title":"Schedule summary","type":"object","properties":{"href":{"type":"string","description":"A link to a [schedule detail](models#scheduledetail).\n","format":"uri-reference"},"name":{"type":"string"}},"description":"A [schedule search](schedules#get-api-schedules) returns an array of these.  It is a\nsubset of what you get from a detail page at `/api/schedules/{id}` (linked as the href in this\nobject).\n"}}},"paths":{"/api/schedules":{"post":{"tags":["Schedules"],"summary":"Create a schedule","description":"This is how you create a new schedule.\n\nYour POST needs a body containing JSON in the same form received from a GET, containing a\ndivision and type, and (if you want it to be useful) `dayCategories`.\n\nDo not code this URL into your application.  Take it from the 'href' field in the\n`features.schedules.schedules` section of `/api`.\n\nAdded in 8.50.\n","requestBody":{"description":"The only fields you must supply in a POST are `division` and `type`.  The server can\nmake up a name for you, and is happy to leave the timetable empty.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleDetail"}}},"required":true},"responses":{"201":{"description":"Success.","headers":{"location":{"description":"The href of the new schedule.","schema":{"type":"string","format":"uri-reference"}}}},"400":{"description":"The parameters are invalid.  Check the body of the response: it may be helpful.\n\nIf you see 'No schedule found', the server could not parse the JSON in the body of your\nPOST.  Remember that the `state` field is an array.\n"},"403":{"description":"The operator does not have a privilege that allows creating schedules, or the site does\nnot have any of the RESTCardholders, RESTOverrides, or RESTStatus licences.\n"}}}}}}
```

## Get details of a schedule

> This returns the detail of one schedule.\
> \
> Follow the 'href' field in a \[schedule summary]\(models#schedulesummary) to get here.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Schedules","description":"These methods give you read/write access to seven types of schedules.  Avigilon Engage schedules\nare not included.\n\nThe main entry point is a paginated search that gives you any number of schedules.  The most\nuseful field on a schedule is a list of state changes and the days and times that those changes\nshould occur.\n\nThere is also a method that allows creating new schedules.\n\nSchedules are new to 8.50.\n\n## Licensing\n\nThe schedules APIs are licensed a little differently from most others.  RESTCardholders gives\nyou Cardholder Access Schedules, while RESTStatus and RESTOverrides give you all schedule types."}],"servers":[{"url":"https://127.0.0.1:8904"}],"security":[{"API_key":[]},{"basic":[]}],"components":{"securitySchemes":{"API_key":{"type":"apiKey","name":"Authorization","in":"header","description":"\nClients authenticate by including a pre-shared API key in the `Authorization` header of each\nrequest after an authorisation method of `GGL-API-KEY`:\n\n`Authorization: GGL-API-KEY C774-B01F-D695-AA4B-215F-A158-AC22-ADEB`\n\nFor a fuller description see [API authentication](api-authentication).\n"},"basic":{"type":"http","scheme":"basic","description":"This is HTTP Basic authentication using a blank username and the API key as the password.\n\nExample:  `Authorization: Basic OkM3NzQtQjAxRi1ENjk1LUFBNEItMjE1Ri1BMTU4LUFDMjItQURFQg==`\n\nThat example is equivalent to the example in the description of the api_Key method:\nprepending a colon to the API key beginning with `C774` then encoding it into Base64\nproduces the 56 characters beginning with `OkM3`.\n\nThe colon is a separator between a username, which is blank in our case, and the password,\nwhich is our API key.\n\nFor a fuller description see [API authentication](api-authentication)\n"}},"schemas":{"ScheduleDetail":{"title":"Schedule detail","description":"[/api/schedules/{id}](schedules#get-api-schedules-id-) returns one of these, and you put\n one of these in the body of a POST or PATCH to create or edit a schedule.\n","allOf":[{"$ref":"#/components/schemas/ScheduleSummary"},{"type":"object","properties":{"description":{"type":"string"},"division":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"}},"description":"The division containing this schedule.  It is possible to change a schedule's\ndivision after creating it.\n"},"notes":{"type":"string","description":"Because of their potential size, notes are only available by request.  Use the 'fields'\nparameter:\n\n`?fields=defaults,notes,...`\n"},"type":{"type":"object","properties":{"type":{"type":"string","enum":["accessZoneSchedule","accessSchedule","alarmZoneSchedule","outputSchedule","notificationSchedule","hVLFSchedule","elevatorKioskControlSchedule"]}},"description":"This block contains a string field `type` which will (in the server's response to a\nGET) or must (in the body of your POST) be one of the seven schedule types.  It is not a\nvalid field in a PATCH, because you cannot change the type of an existing schedule.\n\nElevator kiosk control schedules arrived in 8.60.\n"},"dayCategories":{"description":"This is the part of the schedule that controls when changes occur on its scheduled\nitems.\n\nIt is an array of objects, each containing a day category and an array of times.  The\nday category picks days of the year, and the `times` array sets what will happen and\nat what times on those days.\n\nIn the body of your POST:\n\n  * The `time` field of each object inside `times` must be a string of the form\n    `HH:MM` between 00:00 and 23:59.  If you find another format that works (four\n    zeroes, for example), it may not work in future versions.\n\n  * Each day category must have an entry at 00:00.  This means an item does not need\n    to search back in time to find what state it should be in when it first comes\n    online.\n\n  * Each day category cannot have more than one entry at the same time.\n\nIf you receive a 400 response to your POST or PATCH and one of those rules is the\ncause, the body of the response should contain a reminder.\n\nThe `state` field is an array describing what should happen at that time.  It is\ncomparable to the `statusFlags` arrays on access zones, alarm zones, outputs, and\nfence zones.  For most schedule types it will contain only one word, but the extra\nflag `usePin` may accompany access zone state changes.\n\nWhen building your JSON, treat these string comparisons as case-sensitive.\n\nAll schedule types can have a state change called 'cancelUntimedOverrides'.  That sets\nan item back to its scheduled state if it was under the effect of an override with no\nend time.\n\nOther than that, each schedule type has its own set of state changes:\n\n  * An Access Schedule, also known as a Cardholder Access Schedule, controls the\n    ability of the members of an access group to pass into an access zone.  The valid\n    states are `grant` and `deny`.  Note that 'deny' is a misnomer:  a cardholder will\n    gain access through a door if they are a member of a different access group that\n    still has access.\n\n  * An Access Zone Schedule controls the mode of an access zone.  The valid states are\n    the same as the [zone's status flags](models#accesszonedetail):  `secure`,\n    `dualAuth`, `codeOrCard`, or `free`.  The extra flag `usePin` means the same here\n    as it does in the status flags:  people will need their PINs at readers and alarm\n    terminals.\n\n  * An Alarm Zone Schedule switches an alarm zone between its four modes: `set`,\n    `unset`, `user1`, and `user2`.  Use the words `user1` and `user2` here even if you\n    have renamed them in the server properties.\n\n  * An Output Schedule can be `on` or `off`, plain and simple.\n\n  * A Notification Schedule controls when notifications go out.  They can make sure\n    that notifications go to the people who are on shift, and they can prevent\n    bothering people at night.  Like the access and output schedules it is binary, but\n    the valid states are called `notificationEnabled` and `notificationDisabled`.\n\n  * A HV/LF Schedule controls the voltage on an electric fence.  'lowFeel' mode allows\n    detection without the deterrent of `highVoltage`.\n\nThis example sets an access zone to secure mode between 7.30am and 6:00pm on work\ndays, and secure plus PIN mode at all other times.\n","type":"array","items":{"type":"object","properties":{"dayCategory":{"type":"object","properties":{"name":{"type":"string","readOnly":true},"href":{"type":"string","format":"uri-reference","description":"The API's identifier for an item."}}},"times":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string","pattern":"^[012][0-9]:[0-6][0-9]$"},"state":{"type":"array","items":{"type":"string"}}}}}}}},"scheduledItems":{"readOnly":true,"description":"An array containing the names and hrefs of all the items that this schedule controls\nand that the operator has the privilege to view.\n\nThis is generated data.  A schedule resides in the configuration of the items that use\nit, rather than the other way around, so this block is a handy aggregation of the\ninverse of those relationships.  As such it is read-only:  the server will ignore it\nif you send it in a POST or a PATCH.\n","type":"array","items":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"},"name":{"type":"string"}}}}}}]},"ScheduleSummary":{"title":"Schedule summary","type":"object","properties":{"href":{"type":"string","description":"A link to a [schedule detail](models#scheduledetail).\n","format":"uri-reference"},"name":{"type":"string"}},"description":"A [schedule search](schedules#get-api-schedules) returns an array of these.  It is a\nsubset of what you get from a detail page at `/api/schedules/{id}` (linked as the href in this\nobject).\n"}},"responses":{"403nolicence":{"description":"A server running 8.50 or earlier is missing the RESTStatus licence.  A server running 8.60\nor later is missing both the RESTStatus and RESTOverrides licences.  One of those is enough\nfor this API call in 8.60 and later.\n"},"404schedule":{"description":"The request's URL does not represent a schedule, or the operator does not have a privilege on\nthe schedule's division that allows viewing schedules, such as 'View Schedules', 'Edit\nSchedules', or 'Schedule Access Zone'.\n"}}},"paths":{"/api/schedules/{id}":{"get":{"tags":["Schedules"],"summary":"Get details of a schedule","description":"This returns the detail of one schedule.\n\nFollow the 'href' field in a [schedule summary](models#schedulesummary) to get here.\n","parameters":[{"name":"id","in":"path","description":"The ID of the schedule.","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"This instructs the server to return only these fields in the details page instead of the default set.  The values you can list\nare the same as the field names you would see in the results.  Use it to cut back on the size\nof the response.  Separate values with commas.\n\nTreat the string matches as case-sensitive.\n","schema":{"type":"string","enum":["href","name","description","division","notes","type","dayCategories"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleDetail"}}}},"403":{"$ref":"#/components/responses/403nolicence"},"404":{"$ref":"#/components/responses/404schedule"}}}}}}
```

## Delete a schedule

> Deletes the schedule identified by the request's URL.\
> \
> Added in 8.50.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Schedules","description":"These methods give you read/write access to seven types of schedules.  Avigilon Engage schedules\nare not included.\n\nThe main entry point is a paginated search that gives you any number of schedules.  The most\nuseful field on a schedule is a list of state changes and the days and times that those changes\nshould occur.\n\nThere is also a method that allows creating new schedules.\n\nSchedules are new to 8.50.\n\n## Licensing\n\nThe schedules APIs are licensed a little differently from most others.  RESTCardholders gives\nyou Cardholder Access Schedules, while RESTStatus and RESTOverrides give you all schedule types."}],"servers":[{"url":"https://127.0.0.1:8904"}],"security":[{"API_key":[]},{"basic":[]}],"components":{"securitySchemes":{"API_key":{"type":"apiKey","name":"Authorization","in":"header","description":"\nClients authenticate by including a pre-shared API key in the `Authorization` header of each\nrequest after an authorisation method of `GGL-API-KEY`:\n\n`Authorization: GGL-API-KEY C774-B01F-D695-AA4B-215F-A158-AC22-ADEB`\n\nFor a fuller description see [API authentication](api-authentication).\n"},"basic":{"type":"http","scheme":"basic","description":"This is HTTP Basic authentication using a blank username and the API key as the password.\n\nExample:  `Authorization: Basic OkM3NzQtQjAxRi1ENjk1LUFBNEItMjE1Ri1BMTU4LUFDMjItQURFQg==`\n\nThat example is equivalent to the example in the description of the api_Key method:\nprepending a colon to the API key beginning with `C774` then encoding it into Base64\nproduces the 56 characters beginning with `OkM3`.\n\nThe colon is a separator between a username, which is blank in our case, and the password,\nwhich is our API key.\n\nFor a fuller description see [API authentication](api-authentication)\n"}},"responses":{"404schedule":{"description":"The request's URL does not represent a schedule, or the operator does not have a privilege on\nthe schedule's division that allows viewing schedules, such as 'View Schedules', 'Edit\nSchedules', or 'Schedule Access Zone'.\n"}}},"paths":{"/api/schedules/{id}":{"delete":{"tags":["Schedules"],"summary":"Delete a schedule","description":"Deletes the schedule identified by the request's URL.\n\nAdded in 8.50.\n","parameters":[{"name":"id","in":"path","description":"The ID of the schedule.  Do not add it yourself:  you will receive this URL from other\nAPI calls.\n","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Success."},"400":{"description":"You cannot delete a schedule that is in use.  The body of the 400 response will tell you\nif that is the case.  One way to find out which items are holding you up is to GET the\nsame URL and look in the `scheduledItems` block.\n"},"403":{"description":"The operator does not have a privilege that allows deleting that schedule ('Edit\nSchedules'), or the site does not have any of the RESTCardholders, RESTOverrides,\nor RESTStatus licences.\n"},"404":{"$ref":"#/components/responses/404schedule"}}}}}}
```

## Modify a schedule

> Modifies a schedule according to the body of the PATCH.\
> \
> Added in 8.50.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Schedules","description":"These methods give you read/write access to seven types of schedules.  Avigilon Engage schedules\nare not included.\n\nThe main entry point is a paginated search that gives you any number of schedules.  The most\nuseful field on a schedule is a list of state changes and the days and times that those changes\nshould occur.\n\nThere is also a method that allows creating new schedules.\n\nSchedules are new to 8.50.\n\n## Licensing\n\nThe schedules APIs are licensed a little differently from most others.  RESTCardholders gives\nyou Cardholder Access Schedules, while RESTStatus and RESTOverrides give you all schedule types."}],"servers":[{"url":"https://127.0.0.1:8904"}],"security":[{"API_key":[]},{"basic":[]}],"components":{"securitySchemes":{"API_key":{"type":"apiKey","name":"Authorization","in":"header","description":"\nClients authenticate by including a pre-shared API key in the `Authorization` header of each\nrequest after an authorisation method of `GGL-API-KEY`:\n\n`Authorization: GGL-API-KEY C774-B01F-D695-AA4B-215F-A158-AC22-ADEB`\n\nFor a fuller description see [API authentication](api-authentication).\n"},"basic":{"type":"http","scheme":"basic","description":"This is HTTP Basic authentication using a blank username and the API key as the password.\n\nExample:  `Authorization: Basic OkM3NzQtQjAxRi1ENjk1LUFBNEItMjE1Ri1BMTU4LUFDMjItQURFQg==`\n\nThat example is equivalent to the example in the description of the api_Key method:\nprepending a colon to the API key beginning with `C774` then encoding it into Base64\nproduces the 56 characters beginning with `OkM3`.\n\nThe colon is a separator between a username, which is blank in our case, and the password,\nwhich is our API key.\n\nFor a fuller description see [API authentication](api-authentication)\n"}},"schemas":{"ScheduleDetail":{"title":"Schedule detail","description":"[/api/schedules/{id}](schedules#get-api-schedules-id-) returns one of these, and you put\n one of these in the body of a POST or PATCH to create or edit a schedule.\n","allOf":[{"$ref":"#/components/schemas/ScheduleSummary"},{"type":"object","properties":{"description":{"type":"string"},"division":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"}},"description":"The division containing this schedule.  It is possible to change a schedule's\ndivision after creating it.\n"},"notes":{"type":"string","description":"Because of their potential size, notes are only available by request.  Use the 'fields'\nparameter:\n\n`?fields=defaults,notes,...`\n"},"type":{"type":"object","properties":{"type":{"type":"string","enum":["accessZoneSchedule","accessSchedule","alarmZoneSchedule","outputSchedule","notificationSchedule","hVLFSchedule","elevatorKioskControlSchedule"]}},"description":"This block contains a string field `type` which will (in the server's response to a\nGET) or must (in the body of your POST) be one of the seven schedule types.  It is not a\nvalid field in a PATCH, because you cannot change the type of an existing schedule.\n\nElevator kiosk control schedules arrived in 8.60.\n"},"dayCategories":{"description":"This is the part of the schedule that controls when changes occur on its scheduled\nitems.\n\nIt is an array of objects, each containing a day category and an array of times.  The\nday category picks days of the year, and the `times` array sets what will happen and\nat what times on those days.\n\nIn the body of your POST:\n\n  * The `time` field of each object inside `times` must be a string of the form\n    `HH:MM` between 00:00 and 23:59.  If you find another format that works (four\n    zeroes, for example), it may not work in future versions.\n\n  * Each day category must have an entry at 00:00.  This means an item does not need\n    to search back in time to find what state it should be in when it first comes\n    online.\n\n  * Each day category cannot have more than one entry at the same time.\n\nIf you receive a 400 response to your POST or PATCH and one of those rules is the\ncause, the body of the response should contain a reminder.\n\nThe `state` field is an array describing what should happen at that time.  It is\ncomparable to the `statusFlags` arrays on access zones, alarm zones, outputs, and\nfence zones.  For most schedule types it will contain only one word, but the extra\nflag `usePin` may accompany access zone state changes.\n\nWhen building your JSON, treat these string comparisons as case-sensitive.\n\nAll schedule types can have a state change called 'cancelUntimedOverrides'.  That sets\nan item back to its scheduled state if it was under the effect of an override with no\nend time.\n\nOther than that, each schedule type has its own set of state changes:\n\n  * An Access Schedule, also known as a Cardholder Access Schedule, controls the\n    ability of the members of an access group to pass into an access zone.  The valid\n    states are `grant` and `deny`.  Note that 'deny' is a misnomer:  a cardholder will\n    gain access through a door if they are a member of a different access group that\n    still has access.\n\n  * An Access Zone Schedule controls the mode of an access zone.  The valid states are\n    the same as the [zone's status flags](models#accesszonedetail):  `secure`,\n    `dualAuth`, `codeOrCard`, or `free`.  The extra flag `usePin` means the same here\n    as it does in the status flags:  people will need their PINs at readers and alarm\n    terminals.\n\n  * An Alarm Zone Schedule switches an alarm zone between its four modes: `set`,\n    `unset`, `user1`, and `user2`.  Use the words `user1` and `user2` here even if you\n    have renamed them in the server properties.\n\n  * An Output Schedule can be `on` or `off`, plain and simple.\n\n  * A Notification Schedule controls when notifications go out.  They can make sure\n    that notifications go to the people who are on shift, and they can prevent\n    bothering people at night.  Like the access and output schedules it is binary, but\n    the valid states are called `notificationEnabled` and `notificationDisabled`.\n\n  * A HV/LF Schedule controls the voltage on an electric fence.  'lowFeel' mode allows\n    detection without the deterrent of `highVoltage`.\n\nThis example sets an access zone to secure mode between 7.30am and 6:00pm on work\ndays, and secure plus PIN mode at all other times.\n","type":"array","items":{"type":"object","properties":{"dayCategory":{"type":"object","properties":{"name":{"type":"string","readOnly":true},"href":{"type":"string","format":"uri-reference","description":"The API's identifier for an item."}}},"times":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string","pattern":"^[012][0-9]:[0-6][0-9]$"},"state":{"type":"array","items":{"type":"string"}}}}}}}},"scheduledItems":{"readOnly":true,"description":"An array containing the names and hrefs of all the items that this schedule controls\nand that the operator has the privilege to view.\n\nThis is generated data.  A schedule resides in the configuration of the items that use\nit, rather than the other way around, so this block is a handy aggregation of the\ninverse of those relationships.  As such it is read-only:  the server will ignore it\nif you send it in a POST or a PATCH.\n","type":"array","items":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"},"name":{"type":"string"}}}}}}]},"ScheduleSummary":{"title":"Schedule summary","type":"object","properties":{"href":{"type":"string","description":"A link to a [schedule detail](models#scheduledetail).\n","format":"uri-reference"},"name":{"type":"string"}},"description":"A [schedule search](schedules#get-api-schedules) returns an array of these.  It is a\nsubset of what you get from a detail page at `/api/schedules/{id}` (linked as the href in this\nobject).\n"}},"responses":{"404schedule":{"description":"The request's URL does not represent a schedule, or the operator does not have a privilege on\nthe schedule's division that allows viewing schedules, such as 'View Schedules', 'Edit\nSchedules', or 'Schedule Access Zone'.\n"}}},"paths":{"/api/schedules/{id}":{"patch":{"tags":["Schedules"],"summary":"Modify a schedule","description":"Modifies a schedule according to the body of the PATCH.\n\nAdded in 8.50.\n","parameters":[{"name":"id","in":"path","description":"The ID of the schedule.  Do not add it yourself:  you will receive this URL from other\nAPI calls.\n","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"You do not need to supply any fields in the body of this PATCH, but if you want it to\nachieve something you should add at least one.  Probably `dayCategories`.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleDetail"}}},"required":true},"responses":{"200":{"description":"Success.  Future versions will return feedback from the server about your PATCH.\n"},"204":{"description":"Success."},"400":{"description":"The parameters are invalid.  Check the body of the response: it may be helpful.\n\nIf you see 'No schedule found', the server could not parse the JSON in the body of your\nrequest.  Remember that the `state` field is an array.\n"},"403":{"description":"The operator does not have a privilege that allows modifying that schedule, or the site\ndoes not have any of the RESTCardholders, RESTOverrides, or RESTStatus licences.\n"},"404":{"$ref":"#/components/responses/404schedule"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.security.gallagher.com/knowledge-hub/developer/rest-api/schedules.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
