> 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/lockers.md).

# Lockers

The locker bank API exists for two purposes: finding a locker to assign a cardholder to, and integrating with operational locker management software that expects a bank-centric view rather than the cardholder-centric view available in the cardholder API. For those reasons a locker bank's detail page shows all its cardholder assignments.

The API does not support the creation or configuration of lockers or banks, nor the viewing of hardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and unlock time. The locker configuration tool exists for this purpose.

To change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the cardholder you are updating, not the locker. The locker bank API supplies the URL of the cardholder to PATCH.

### Locker status flags

Regardless of whether a locker is online or not, its `statusFlags` may contain one of these:

* `quarantined` means the locker cannot be allocated to a cardholder. It needs a clean.
* `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.
* `free` means it is not allocated to a cardholder.

If the locker is online its status may also contain one or more of these flags:

* `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a door.

#### Locker status flag rules

* A locker can only be one of `quarantined`, `allocated`, or `free`.
* Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags will be there and one of `locked` or `unlocked`.

### Use cases

#### Displaying all banks and lockers, and the cardholders assigned to them

1. `GET /api`
2. Follow the link at `features.lockerBanks.lockerBanks.href` ↪, adding a search term to the query to thin out the results.
3. Follow the href of the locker bank you are after.

The results of that query are the locker bank detail.

#### Assigning a locker to a cardholder

1. Find the href of the locker, as above. Normally one that does not have someone already allocated.
2. Find the href of the cardholder using the cardholders API.
3. PATCH the cardholder with the locker's href in a property called `locker` in an element of an array called `add` inside an object called `lockers`. Add `from` and `until` properties to the body of your PATCH, as you like.

#### Opening or quarantining a locker

Command Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search to request the 'open' override URLs for lockers, which in prior versions was only available on their details pages. Version 9.10 adds the ability to quarantine lockers, which prevents anyone from allocating them to a cardholder.

1. `GET /api`
2. Follow the link at `features.lockerBanks.lockerBanks.href` ↪, adding `?` or `&` as appropriate then `fields=name,lockers.name,lockers.shortName,lockers.commands`. Also add a search term to thin out the results, if you have a lot of locker banks.
3. Dig through the results for your locker bank, then through the `lockers` array of that locker bank for your locker, then into the `commands` block of that locker for another block called `open` or `quarantine` depending on your need. If your operator is able to override that locker, that block will contain a field called `href` which gives the URL you need to POST to override the locker (open, for example).

## Search locker banks

> This returns locker banks matching your search criteria.\
> \
> The result will contain no more than 100 or 1000 objects depending on your version; you\
> should follow the \`next\` link, if it is present, to collect more.\
> \
> If the result set is empty it means there are no locker banks in the divisions in which the\
> operator has a privilege that allows listing them, such as 'View lockers and assignments'.\
> \
> When you have loaded all the locker banks there will no \`next\` link.\
> \
> \[Do not code this URL]\(forward-compatibility-hateoas) into your application.  Take\
> it from the 'href' field in the \`features.lockerBanks.lockerBanks\` section of \`/api\`.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Lockers","description":"\nThe locker bank API exists for two purposes:  finding a locker to assign a cardholder to, and\nintegrating with operational locker management software that expects a bank-centric view rather\nthan the cardholder-centric view available in the cardholder API.  For those reasons a locker bank's detail\npage shows all its cardholder assignments.\n\nThe API does not support the creation or configuration of lockers or banks, nor the viewing of\nhardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and\nunlock time.  The locker configuration tool exists for this purpose.\n\nTo change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the\ncardholder you are updating, not the locker.  The locker bank API supplies the URL of the cardholder to PATCH.\n\n## Locker status flags\n\nRegardless of whether a locker is online or not, its `statusFlags` may contain one of these:\n\n- `quarantined` means the locker cannot be allocated to a cardholder.  It needs a clean.\n\n- `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.\n\n- `free` means it is not allocated to a cardholder.\n\nIf the locker is online its status may also contain one or more of these flags:\n\n- `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a\n  [door](rest.html#tag-Doors).\n\n### Locker status flag rules\n\n- A locker can only be one of `quarantined`, `allocated`, or `free`.\n\n- Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags\n  will be there and one of `locked` or `unlocked`.\n\n## Use cases\n\n### Displaying all banks and lockers, and the cardholders assigned to them\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding a search term to the query to thin out the\n   results.\n3. Follow the href of the locker bank you are after.\n\nThe results of that query are the [locker bank detail](models#lockerbankdetail).\n\n### Assigning a locker to a cardholder\n\n1. Find the href of the locker, as above.  Normally one that does not have someone already allocated.\n\n1. Find the href of the cardholder using the [cardholders\n   API](cardholders#get-api-cardholders).\n\n3. [PATCH](cardholders#patch-api-cardholders-id-) the cardholder with the locker's\n   href in a property called `locker` in an element of an array called `add` inside an object called `lockers`.\n   Add `from` and `until` properties to the body of your PATCH, as you like.\n\n### Opening or quarantining a locker\n\nCommand Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search\nto request the 'open' override URLs for lockers, which in prior versions was only available on\ntheir details pages.  Version 9.10 adds the ability to quarantine lockers, which prevents anyone\nfrom allocating them to a cardholder.\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding `?` or `&` as appropriate then\n   `fields=name,lockers.name,lockers.shortName,lockers.commands`.  Also add a search term to\n   thin out the results, if you have a lot of locker banks.\n3. Dig through the results for your locker bank, then through the `lockers` array of that locker\n   bank for your locker, then into the `commands` block of that locker for another block called\n   `open` or `quarantine` depending on your need.  If your operator is able to override that\n   locker, that block will contain a field called `href` which gives the URL you need to\n   POST to override the locker ([open](lockers#post-api-lockers-id-open), for example).\n"}],"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":{"LockerBankSearch":{"title":"Locker bank search","description":"An array of locker bank summaries, and a `next` link for more.\n","properties":{"results":{"type":"array","description":"An array of locker bank summaries.","items":{"$ref":"#/components/schemas/LockerBankSummary"}},"next":{"type":"object","description":"The link to the next page of results.  Absent if you have retrieved them all.","properties":{"href":{"type":"string","format":"uri-reference"}}}}},"LockerBankSummary":{"title":"Locker bank summary","description":"The locker bank search at `/api/locker_banks` returns an array of these.  It is a subset of\nwhat you get from a locker bank's detail page at `/api/locker_banks/{id}` (linked as the href\nin this object).\n\nLike the cardholder and access group summary pages in this API, this contains only\nthe basic information about a locker bank.  It is the result of a search and could\nreturn many items, and we did not want the size getting out of hand.\n\nAlso like the other summary pages in this API, you can add all the fields you want using the\n`fields` query parameter to the API routes that return it.\n\nThe most important field is the href to the detail page, covered next.\n","properties":{"href":{"type":"string","format":"uri-reference","description":"A link to the detail page for this locker bank."},"name":{"type":"string"},"shortName":{"type":"string","description":"The bank's short name."},"description":{"type":"string"},"division":{"type":"object","description":"The division containing this locker bank."}}}}},"paths":{"/api/locker_banks":{"get":{"tags":["Lockers"],"summary":"Search locker banks","description":"This returns locker banks matching your search criteria.\n\nThe result will contain no more than 100 or 1000 objects depending on your version; you\nshould follow the `next` link, if it is present, to collect more.\n\nIf the result set is empty it means there are no locker banks in the divisions in which the\noperator has a privilege that allows listing them, such as 'View lockers and assignments'.\n\nWhen you have loaded all the locker banks there will no `next` link.\n\n[Do not code this URL](forward-compatibility-hateoas) into your application.  Take\nit from the 'href' field in the `features.lockerBanks.lockerBanks` section of `/api`.\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","in":"query","required":false,"schema":{"default":["defaults"],"type":"array","items":{"type":"string","enum":["href","id","name","shortName","description","division","lockers","notes","lockers.defaults","lockers.id","lockers.href","lockers.name","lockers.shortName","lockers.description","lockers.division","lockers.notes","lockers.commands","lockers.assignments","defaults"]}},"description":"Sets which fields to return.  The values you can list are the same as the\nfield names in the [details page](models#lockerbankdetail).  Using it you can\nreturn everything on the search page that you would find on the details page.  Separate\nvalues with commas.\n\nIf you specify any value for this parameter, the default no longer applies and you will\nonly receive the fields you asked for.\n\nUse the special value `defaults` to return the locker bank fields you would have received\nhad you not given the parameter at all.  Then you can add a comma and more fields.\n\nIn v8.00 you will receive the href and internal ID even if you did not ask for them.  In\n8.10 you will not.  If you are going to send the fields parameter and need the href or ID,\nbe explicit.\n\nAll the field names beginning with `lockers.` arrived in v8.10.1112.  They affect the\nfields that appear inside the 'lockers' block.  The guideline for using `defaults` is:  if\nyou want to receive less data, specify only the fields you want.  If you want to receive\nmore, either list every field you want or simply use `lockers.defaults` plus your extras.\n\nTreat the string matches as case-sensitive.\n"},{"$ref":"#/components/parameters/pos"},{"$ref":"#/components/parameters/skip"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LockerBankSearch"}}}},"403":{"description":"The installation lacks a lockers licence, or it is missing RESTCardholders and\nRESTStatus and (in 8.60) RESTOverrides.\n"}}}}}}
```

## Get details of a locker bank

> This returns details for a locker bank.  In the interest of forward compatibility follow the\
> href in the \[locker bank summary]\(models#lockerbanksummary) to get here rather than\
> \[building the URL yourself]\(forward-compatibility-hateoas).<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Lockers","description":"\nThe locker bank API exists for two purposes:  finding a locker to assign a cardholder to, and\nintegrating with operational locker management software that expects a bank-centric view rather\nthan the cardholder-centric view available in the cardholder API.  For those reasons a locker bank's detail\npage shows all its cardholder assignments.\n\nThe API does not support the creation or configuration of lockers or banks, nor the viewing of\nhardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and\nunlock time.  The locker configuration tool exists for this purpose.\n\nTo change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the\ncardholder you are updating, not the locker.  The locker bank API supplies the URL of the cardholder to PATCH.\n\n## Locker status flags\n\nRegardless of whether a locker is online or not, its `statusFlags` may contain one of these:\n\n- `quarantined` means the locker cannot be allocated to a cardholder.  It needs a clean.\n\n- `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.\n\n- `free` means it is not allocated to a cardholder.\n\nIf the locker is online its status may also contain one or more of these flags:\n\n- `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a\n  [door](rest.html#tag-Doors).\n\n### Locker status flag rules\n\n- A locker can only be one of `quarantined`, `allocated`, or `free`.\n\n- Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags\n  will be there and one of `locked` or `unlocked`.\n\n## Use cases\n\n### Displaying all banks and lockers, and the cardholders assigned to them\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding a search term to the query to thin out the\n   results.\n3. Follow the href of the locker bank you are after.\n\nThe results of that query are the [locker bank detail](models#lockerbankdetail).\n\n### Assigning a locker to a cardholder\n\n1. Find the href of the locker, as above.  Normally one that does not have someone already allocated.\n\n1. Find the href of the cardholder using the [cardholders\n   API](cardholders#get-api-cardholders).\n\n3. [PATCH](cardholders#patch-api-cardholders-id-) the cardholder with the locker's\n   href in a property called `locker` in an element of an array called `add` inside an object called `lockers`.\n   Add `from` and `until` properties to the body of your PATCH, as you like.\n\n### Opening or quarantining a locker\n\nCommand Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search\nto request the 'open' override URLs for lockers, which in prior versions was only available on\ntheir details pages.  Version 9.10 adds the ability to quarantine lockers, which prevents anyone\nfrom allocating them to a cardholder.\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding `?` or `&` as appropriate then\n   `fields=name,lockers.name,lockers.shortName,lockers.commands`.  Also add a search term to\n   thin out the results, if you have a lot of locker banks.\n3. Dig through the results for your locker bank, then through the `lockers` array of that locker\n   bank for your locker, then into the `commands` block of that locker for another block called\n   `open` or `quarantine` depending on your need.  If your operator is able to override that\n   locker, that block will contain a field called `href` which gives the URL you need to\n   POST to override the locker ([open](lockers#post-api-lockers-id-open), for example).\n"}],"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":{"LockerBankDetail":{"title":"Locker bank detail","description":"[/api/locker_banks/{id}](lockers#get-api-locker_banks-id-) returns one of these.  It\ncontains an array of all the lockers in the bank, each of which contains an array of the\ncardholders assigned to that locker.\n\nThis example shows two lockers on the bank, called 'L1' and 'L2'.  L1 has two\ncardholders who can open it:  one for two years, the other for a week in April 2018.\n","properties":{"href":{"type":"string","format":"uri-reference","description":"A self-reference."},"name":{"type":"string"},"shortName":{"type":"string"},"description":{"type":"string"},"division":{"type":"object","description":"The division containing this locker bank."},"notes":{"type":"string"},"connectedController":{"type":"object","description":"This block describes this item's hardware controller.\n\nRetrieving it takes a little more time than the other fields so only ask for it if you\nneed it.\n\nAdded in 8.50.\n","properties":{"name":{"type":"string"},"href":{"type":"string","format":"uri-reference","description":"This is the REST API's identifier for the hardware controller.  It is only an\nidentifier, not a usable URL, because there is no interface for hardware\ncontrollers.  GETting the URL will return a 404.\n"},"id":{"type":"string","description":"An alphanumeric identifier, unique to the server.  This is the ID to use in the `source`\nparameter of [event filters](events#get-api-events).\n"}}},"lockers":{"description":"An array of locker objects, each containing the details of the locker and the\ncardholders who can open it.\n","type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"shortName":{"type":"string","description":"A T20 will display this instead of the long name, if it has both."},"description":{"type":"string"},"href":{"type":"string","format":"uri-reference","description":"This is the href of the locker.  Use it when creating new assignments in a\ncardholder PATCH or POST.  Trying to GET it will always yield a 404.\n"},"connectedController":{"type":"object","description":"This block describes this item's hardware controller.  Retrieving it takes a little more time\nthan the other fields so only ask for it if you need it.\n\nAdded in 8.50.\n"},"assignments":{"type":"array","description":"A locker can have many assignments.  Each contains a cardholder and up to two dates,\nbetween which the cardholder can open the locker.  If either of the dates is\nmissing, the assignment is unbounded in that direction.\n","items":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference","description":"This is the href of a cardholder's assignment to a locker.  Put it in a\n[cardholder PATCH](cardholders#patch-api-cardholders-id-) to update or delete\nit.\n\nYou can also revoke a cardholder's access to this locker by sending a\n[DELETE](cardholders#delete-api-cardholders-id-lockers-assignment_id-) to this href.\n\nIf the site does not have the RESTCardholders licence or your operator does\nnot have the privilege to view the cardholder, this link will not work in a\nDELETE or a cardholder PATCH.\n"},"cardholder":{"type":"object","description":"The name and href of the cardholder assigned to this locker.  It will be\nmissing if the site does not have the RESTCardholders licence or your operator\ndoes not have the privilege to view that cardholder.\n"},"from":{"type":"string","format":"date-time","description":"If missing, the locker assignment has no start time, meaning the cardholder\ncan open the locker provided the 'until' time is in the future.\n"},"until":{"type":"string","format":"date-time","description":"If missing, the locker assignment has no end time, meaning the cardholder can\nopen the locker provided the 'from' time is in the past.\n"}}}},"commands":{"type":"object","description":"Overrideable items return one of these blocks if your operator has the right\nprivilege and the locker is fit to be overridden.  It is a list of commands, each\nrepresented by a block containing an href that accepts a POST that will send an\noverride to the locker, changing its state.\n","properties":{"open":{"type":"object","properties":{"href":{"description":"POST to this URL to send an open override to the locker.  The server will\nignore the POST body.\n","type":"string","format":"uri-reference"}}},"quarantine":{"type":"object","properties":{"href":{"description":"POST to this URL to send a quarantine override to the locker.  Do not send a\nbody with the POST since some server versions use the same POST for\n`quarantineUntil`, which takes a time from the body.\n","type":"string","format":"uri-reference"}}},"quarantineUntil":{"type":"object","properties":{"href":{"description":"POST to this URL to send an override to the locker that will quarantine it\nuntil a timestamp you send [in the body](rest.html#definition-OverrideEndTime).\n","type":"string","format":"uri-reference"}}},"cancelQuarantine":{"type":"object","properties":{"href":{"description":"POST to this URL to send a quarantine cancel override to the locker.  The\nserver will ignore the POST body.\n","type":"string","format":"uri-reference"}}}}},"updates":{"description":"This is not a default field:  you must ask for it by adding `lockers.updates` to\nthe `fields` query parameter.  Since it can only monitor one locker at a time we\ndiscourage its use in favour of [bulk status\nmonitoring](items#status-subscriptions).\n"}}}}}}}},"paths":{"/api/locker_banks/{id}":{"get":{"tags":["Lockers"],"summary":"Get details of a locker bank","description":"This returns details for a locker bank.  In the interest of forward compatibility follow the\nhref in the [locker bank summary](models#lockerbanksummary) to get here rather than\n[building the URL yourself](forward-compatibility-hateoas).\n","parameters":[{"name":"fields","in":"query","required":false,"schema":{"default":["defaults"],"type":"array","items":{"type":"string","enum":["href","id","name","shortName","description","division","notes","connectedController","lockers","lockers.defaults","lockers.connectedController","...","defaults"]}},"description":"Sets which fields to return.  The values you can list are the same as the field names you\nwould get in the [details page](models#lockerbankdetail).  Use it to cut back on\nthe size of the response for large locker banks.  Separate values with commas.\n\nTreat the string matches as case-sensitive.\n\nIn v8.00 you will receive the href and internal ID even if you did not ask for them.  In\n8.10 you will not.  If you are going to send the fields parameter and need the href or ID,\nbe explicit.\n"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LockerBankDetail"}}}},"403":{"description":"The installation lacks a lockers licence, or it is missing RESTCardholders and\nRESTStatus and (in 8.60) RESTOverrides.\n"},"404":{"description":"Your REST operator does not have the privilege to view that locker bank.\n"}}}}}}
```

## Get details of a locker

> This returns details for a locker.  Follow the href in the \[locker bank\
> summary]\(models#lockerbanksummary) or \[locker bank\
> detail]\(models#lockerbankdetail) to get here rather than \[building the URL\
> yourself]\(forward-compatibility-hateoas).\
> \
> Prior to v8.20 this endpoint was at \`/api/locker\_banks/{locker\_bank\_id}/lockers/{id}\` .<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Lockers","description":"\nThe locker bank API exists for two purposes:  finding a locker to assign a cardholder to, and\nintegrating with operational locker management software that expects a bank-centric view rather\nthan the cardholder-centric view available in the cardholder API.  For those reasons a locker bank's detail\npage shows all its cardholder assignments.\n\nThe API does not support the creation or configuration of lockers or banks, nor the viewing of\nhardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and\nunlock time.  The locker configuration tool exists for this purpose.\n\nTo change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the\ncardholder you are updating, not the locker.  The locker bank API supplies the URL of the cardholder to PATCH.\n\n## Locker status flags\n\nRegardless of whether a locker is online or not, its `statusFlags` may contain one of these:\n\n- `quarantined` means the locker cannot be allocated to a cardholder.  It needs a clean.\n\n- `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.\n\n- `free` means it is not allocated to a cardholder.\n\nIf the locker is online its status may also contain one or more of these flags:\n\n- `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a\n  [door](rest.html#tag-Doors).\n\n### Locker status flag rules\n\n- A locker can only be one of `quarantined`, `allocated`, or `free`.\n\n- Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags\n  will be there and one of `locked` or `unlocked`.\n\n## Use cases\n\n### Displaying all banks and lockers, and the cardholders assigned to them\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding a search term to the query to thin out the\n   results.\n3. Follow the href of the locker bank you are after.\n\nThe results of that query are the [locker bank detail](models#lockerbankdetail).\n\n### Assigning a locker to a cardholder\n\n1. Find the href of the locker, as above.  Normally one that does not have someone already allocated.\n\n1. Find the href of the cardholder using the [cardholders\n   API](cardholders#get-api-cardholders).\n\n3. [PATCH](cardholders#patch-api-cardholders-id-) the cardholder with the locker's\n   href in a property called `locker` in an element of an array called `add` inside an object called `lockers`.\n   Add `from` and `until` properties to the body of your PATCH, as you like.\n\n### Opening or quarantining a locker\n\nCommand Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search\nto request the 'open' override URLs for lockers, which in prior versions was only available on\ntheir details pages.  Version 9.10 adds the ability to quarantine lockers, which prevents anyone\nfrom allocating them to a cardholder.\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding `?` or `&` as appropriate then\n   `fields=name,lockers.name,lockers.shortName,lockers.commands`.  Also add a search term to\n   thin out the results, if you have a lot of locker banks.\n3. Dig through the results for your locker bank, then through the `lockers` array of that locker\n   bank for your locker, then into the `commands` block of that locker for another block called\n   `open` or `quarantine` depending on your need.  If your operator is able to override that\n   locker, that block will contain a field called `href` which gives the URL you need to\n   POST to override the locker ([open](lockers#post-api-lockers-id-open), for example).\n"}],"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":{"LockerDetail":{"title":"Locker detail","description":"[/api/lockers/{id}](lockers#get-api-locker-id-) returns one of these.  It contains some\nbasic data about a locker, its assignments (the cardholders who can open it), and a link to\noverride it open.\n","properties":{"href":{"type":"string","format":"uri-reference","description":"A self-reference."},"name":{"type":"string"},"shortName":{"type":"string"},"description":{"type":"string"},"division":{"type":"object","description":"The division containing this locker."},"notes":{"type":"string","description":"The notes field is not in the default result set.  You must ask for it using `fields`."},"connectedController":{"type":"object","description":"This block describes this item's hardware controller.\n\nRetrieving it takes a little more time than the other fields so only ask for it if you\nneed it.\n\nAdded in 8.50.\n","properties":{"name":{"type":"string"},"href":{"type":"string","format":"uri-reference","description":"This is the REST API's identifier for the hardware controller.  It is only an\nidentifier, not a usable URL, because there is no interface for hardware\ncontrollers.  GETting the URL will return a 404.\n"},"id":{"type":"string","description":"An alphanumeric identifier, unique to the server.  This is the ID to use in the `source`\nparameter of [event filters](events#get-api-events).\n"}}},"assignments":{"type":"array","description":"A locker can have many assignments.  Each contains a cardholder and up to two dates,\nbetween which the cardholder can open the locker.  If either of the dates is missing, the\nassignment is unbounded in that direction.\n","items":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference","description":"This is the href of a cardholder's assignment to a locker.  Put it in a [cardholder\nPATCH](cardholders#patch-api-cardholders-id-) to update or delete it.\n\nYou can also revoke a cardholder's access to this locker by sending a\n[DELETE](cardholders#delete-api-cardholders-id-lockers-assignment_id-) to this\nhref.\n\nIf the site does not have the RESTCardholders licence or your operator does not have\nthe privilege to view the cardholder, this link will not work in a DELETE or a\ncardholder PATCH.\n"},"cardholder":{"type":"object","description":"The name and href of the cardholder assigned to this locker.  It will be missing if\nthe site does not have the RESTCardholders licence or your operator does not have\nthe privilege to view that cardholder.\n"},"from":{"type":"string","format":"date-time","description":"If missing, the locker assignment has no start time, meaning the cardholder can open\nthe locker while the 'until' time is in the future.\n"},"until":{"type":"string","format":"date-time","description":"If missing, the locker assignment has no end time, meaning the cardholder can open\nthe locker after the 'from' time.\n"}}}},"commands":{"type":"object","description":"Overrideable items return one of these blocks if your operator has the right\nprivilege and the locker is fit to be overridden.  It is a list of commands, each\nrepresented by a block containing an href that accepts a POST that will send an\noverride to the locker, changing its state.\n","properties":{"open":{"type":"object","properties":{"href":{"description":"POST to this URL to send an open override to the locker.  The server will\nignore the POST body.\n","type":"string","format":"uri-reference"}}},"quarantine":{"type":"object","properties":{"href":{"description":"POST to this URL to send a quarantine override to the locker.  Do not send a\nbody with the POST since some server versions use the same POST for\n`quarantineUntil`, which takes a time from the body.\n","type":"string","format":"uri-reference"}}},"quarantineUntil":{"type":"object","properties":{"href":{"description":"POST to this URL to send an override to the locker that will quarantine it\nuntil a timestamp you send [in the body](rest.html#definition-OverrideEndTime).\n","type":"string","format":"uri-reference"}}},"cancelQuarantine":{"type":"object","properties":{"href":{"description":"POST to this URL to send a quarantine cancel override to the locker.  The\nserver will ignore the POST body.\n","type":"string","format":"uri-reference"}}}}},"updates":{"type":"object","properties":{"href":{"type":"string","format":"uri-reference"}},"description":"Follow the URL in the href inside this block to receive the locker's current status, then\nfollow the `next` link in the results to long poll for changes to that status.\n\n`updates` was added to the lockers controller in 9.10 for consistency with other\ncontrollers, but we discourage its use in favour of [bulk status\nmonitoring](items#status-subscriptions).\n\nAlthough a locker's status includes 'free' or 'allocated', allocating or un-allocating a\nlocker does not cause the API to report a change of status.  Opening, closing,\nquarantining, and unquarantining a locker do.\n"}}}}},"paths":{"/api/lockers/{id}":{"get":{"tags":["Lockers"],"summary":"Get details of a locker","description":"This returns details for a locker.  Follow the href in the [locker bank\nsummary](models#lockerbanksummary) or [locker bank\ndetail](models#lockerbankdetail) to get here rather than [building the URL\nyourself](forward-compatibility-hateoas).\n\nPrior to v8.20 this endpoint was at `/api/locker_banks/{locker_bank_id}/lockers/{id}` .\n","parameters":[{"name":"fields","in":"query","required":false,"schema":{"type":"array","default":["defaults"],"items":{"type":"string","enum":["href","id","name","shortName","description","division","assignments","notes","commands","connectedController","defaults"]}},"description":"Sets which fields to return.  Use it to cut back on the size of the response for a locker\nwith many assignments.  Separate values with commas.\n\nTreat the string matches as case-sensitive.\n"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LockerDetail"}}}},"403":{"description":"The installation lacks a lockers licence, or it is missing both RESTCardholders and\nRESTStatus and (in 8.60) RESTOverrides.\n"},"404":{"description":"Your REST operator does not have the privilege to view that locker bank ('Locker\nassignments').\n"}}}}}}
```

## Open a locker

> Sends an override to open a locker.\
> \
> You should get this URL from a \[locker detail]\(models#lockerdetail) or \[locker bank\
> detail]\(models#lockerbankdetail) rather than \[building it\
> yourself]\(forward-compatibility-hateoas).\
> \
> New in 8.10.1112.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Lockers","description":"\nThe locker bank API exists for two purposes:  finding a locker to assign a cardholder to, and\nintegrating with operational locker management software that expects a bank-centric view rather\nthan the cardholder-centric view available in the cardholder API.  For those reasons a locker bank's detail\npage shows all its cardholder assignments.\n\nThe API does not support the creation or configuration of lockers or banks, nor the viewing of\nhardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and\nunlock time.  The locker configuration tool exists for this purpose.\n\nTo change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the\ncardholder you are updating, not the locker.  The locker bank API supplies the URL of the cardholder to PATCH.\n\n## Locker status flags\n\nRegardless of whether a locker is online or not, its `statusFlags` may contain one of these:\n\n- `quarantined` means the locker cannot be allocated to a cardholder.  It needs a clean.\n\n- `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.\n\n- `free` means it is not allocated to a cardholder.\n\nIf the locker is online its status may also contain one or more of these flags:\n\n- `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a\n  [door](rest.html#tag-Doors).\n\n### Locker status flag rules\n\n- A locker can only be one of `quarantined`, `allocated`, or `free`.\n\n- Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags\n  will be there and one of `locked` or `unlocked`.\n\n## Use cases\n\n### Displaying all banks and lockers, and the cardholders assigned to them\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding a search term to the query to thin out the\n   results.\n3. Follow the href of the locker bank you are after.\n\nThe results of that query are the [locker bank detail](models#lockerbankdetail).\n\n### Assigning a locker to a cardholder\n\n1. Find the href of the locker, as above.  Normally one that does not have someone already allocated.\n\n1. Find the href of the cardholder using the [cardholders\n   API](cardholders#get-api-cardholders).\n\n3. [PATCH](cardholders#patch-api-cardholders-id-) the cardholder with the locker's\n   href in a property called `locker` in an element of an array called `add` inside an object called `lockers`.\n   Add `from` and `until` properties to the body of your PATCH, as you like.\n\n### Opening or quarantining a locker\n\nCommand Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search\nto request the 'open' override URLs for lockers, which in prior versions was only available on\ntheir details pages.  Version 9.10 adds the ability to quarantine lockers, which prevents anyone\nfrom allocating them to a cardholder.\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding `?` or `&` as appropriate then\n   `fields=name,lockers.name,lockers.shortName,lockers.commands`.  Also add a search term to\n   thin out the results, if you have a lot of locker banks.\n3. Dig through the results for your locker bank, then through the `lockers` array of that locker\n   bank for your locker, then into the `commands` block of that locker for another block called\n   `open` or `quarantine` depending on your need.  If your operator is able to override that\n   locker, that block will contain a field called `href` which gives the URL you need to\n   POST to override the locker ([open](lockers#post-api-lockers-id-open), for example).\n"}],"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"}}},"paths":{"/api/lockers/{id}/open":{"post":{"tags":["Lockers"],"summary":"Open a locker","description":"Sends an override to open a locker.\n\nYou should get this URL from a [locker detail](models#lockerdetail) or [locker bank\ndetail](models#lockerbankdetail) rather than [building it\nyourself](forward-compatibility-hateoas).\n\nNew in 8.10.1112.\n","responses":{"200":{"description":"Success.  Future versions will contain feedback from the server."},"204":{"description":"Success."},"403":{"description":"The site does not have the RESTOverrides licence (in which case the body of the result\nwill say so), or your operator does not have 'Override - Open Locker' on the locker's\ndivision.\n"},"404":{"description":"That is not the URL of a locker, or it is the URL of a locker your operator does not\nhave the privilege to see.\n"}}}}}}
```

## Quarantine a locker

> Sends an override to quarantine a locker.  If the override succeeds, the locker will not be\
> allocatable until its quarantine ends.\
> \
> The call will fail if the locker is allocated to a cardholder.\
> \
> You should get this URL from a \[locker detail]\(models#lockerdetail) or \[locker bank\
> detail]\(models#lockerbankdetail) rather than \[building it\
> yourself]\(forward-compatibility-hateoas).\
> \
> New in 9.10.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Lockers","description":"\nThe locker bank API exists for two purposes:  finding a locker to assign a cardholder to, and\nintegrating with operational locker management software that expects a bank-centric view rather\nthan the cardholder-centric view available in the cardholder API.  For those reasons a locker bank's detail\npage shows all its cardholder assignments.\n\nThe API does not support the creation or configuration of lockers or banks, nor the viewing of\nhardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and\nunlock time.  The locker configuration tool exists for this purpose.\n\nTo change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the\ncardholder you are updating, not the locker.  The locker bank API supplies the URL of the cardholder to PATCH.\n\n## Locker status flags\n\nRegardless of whether a locker is online or not, its `statusFlags` may contain one of these:\n\n- `quarantined` means the locker cannot be allocated to a cardholder.  It needs a clean.\n\n- `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.\n\n- `free` means it is not allocated to a cardholder.\n\nIf the locker is online its status may also contain one or more of these flags:\n\n- `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a\n  [door](rest.html#tag-Doors).\n\n### Locker status flag rules\n\n- A locker can only be one of `quarantined`, `allocated`, or `free`.\n\n- Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags\n  will be there and one of `locked` or `unlocked`.\n\n## Use cases\n\n### Displaying all banks and lockers, and the cardholders assigned to them\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding a search term to the query to thin out the\n   results.\n3. Follow the href of the locker bank you are after.\n\nThe results of that query are the [locker bank detail](models#lockerbankdetail).\n\n### Assigning a locker to a cardholder\n\n1. Find the href of the locker, as above.  Normally one that does not have someone already allocated.\n\n1. Find the href of the cardholder using the [cardholders\n   API](cardholders#get-api-cardholders).\n\n3. [PATCH](cardholders#patch-api-cardholders-id-) the cardholder with the locker's\n   href in a property called `locker` in an element of an array called `add` inside an object called `lockers`.\n   Add `from` and `until` properties to the body of your PATCH, as you like.\n\n### Opening or quarantining a locker\n\nCommand Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search\nto request the 'open' override URLs for lockers, which in prior versions was only available on\ntheir details pages.  Version 9.10 adds the ability to quarantine lockers, which prevents anyone\nfrom allocating them to a cardholder.\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding `?` or `&` as appropriate then\n   `fields=name,lockers.name,lockers.shortName,lockers.commands`.  Also add a search term to\n   thin out the results, if you have a lot of locker banks.\n3. Dig through the results for your locker bank, then through the `lockers` array of that locker\n   bank for your locker, then into the `commands` block of that locker for another block called\n   `open` or `quarantine` depending on your need.  If your operator is able to override that\n   locker, that block will contain a field called `href` which gives the URL you need to\n   POST to override the locker ([open](lockers#post-api-lockers-id-open), for example).\n"}],"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"}}},"paths":{"/api/lockers/{id}/quarantine":{"post":{"tags":["Lockers"],"summary":"Quarantine a locker","description":"Sends an override to quarantine a locker.  If the override succeeds, the locker will not be\nallocatable until its quarantine ends.\n\nThe call will fail if the locker is allocated to a cardholder.\n\nYou should get this URL from a [locker detail](models#lockerdetail) or [locker bank\ndetail](models#lockerbankdetail) rather than [building it\nyourself](forward-compatibility-hateoas).\n\nNew in 9.10.\n","responses":{"200":{"description":"Success.  The response body will contain feedback from the server."},"204":{"description":"Success."},"400":{"description":"Check the response body for an error message.  A common fault is the locker being allocated."},"403":{"description":"The site does not have the RESTOverrides licence (in which case the body of the result\nwill say so), or your operator does not have 'Override' on the locker's division.\n"},"404":{"description":"That is not the URL of a locker, or it is the URL of a locker your operator does not\nhave the privilege to see.\n"}}}}}}
```

## Un-quarantine a locker

> Sends an override to remove the quarantine from a locker, making it available for\
> allocation.\
> \
> You should get this URL from a \[locker detail]\(models#lockerdetail) or \[locker bank\
> detail]\(models#lockerbankdetail) rather than \[building it\
> yourself]\(forward-compatibility-hateoas).\
> \
> New in 9.10.<br>

```json
{"openapi":"3.2.0","info":{"title":"Command Centre REST API","version":"2.0"},"tags":[{"name":"Lockers","description":"\nThe locker bank API exists for two purposes:  finding a locker to assign a cardholder to, and\nintegrating with operational locker management software that expects a bank-centric view rather\nthan the cardholder-centric view available in the cardholder API.  For those reasons a locker bank's detail\npage shows all its cardholder assignments.\n\nThe API does not support the creation or configuration of lockers or banks, nor the viewing of\nhardware and door-like settings of a locker such as readers, inputs, outputs, lock type, and\nunlock time.  The locker configuration tool exists for this purpose.\n\nTo change the cardholder assignments to lockers you should PATCH the cardholder's href, since it is the\ncardholder you are updating, not the locker.  The locker bank API supplies the URL of the cardholder to PATCH.\n\n## Locker status flags\n\nRegardless of whether a locker is online or not, its `statusFlags` may contain one of these:\n\n- `quarantined` means the locker cannot be allocated to a cardholder.  It needs a clean.\n\n- `allocated` means it is allocated to a cardholder, so another cardholder cannot self-allocate it.\n\n- `free` means it is not allocated to a cardholder.\n\nIf the locker is online its status may also contain one or more of these flags:\n\n- `forced`, `openTooLong`, `tamper`, `closed`, `open`, `locked`, `unlocked`, the same as a\n  [door](rest.html#tag-Doors).\n\n### Locker status flag rules\n\n- A locker can only be one of `quarantined`, `allocated`, or `free`.\n\n- Like a door, if and only if the locker is online, exactly one of the `closed` or `open` flags\n  will be there and one of `locked` or `unlocked`.\n\n## Use cases\n\n### Displaying all banks and lockers, and the cardholders assigned to them\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding a search term to the query to thin out the\n   results.\n3. Follow the href of the locker bank you are after.\n\nThe results of that query are the [locker bank detail](models#lockerbankdetail).\n\n### Assigning a locker to a cardholder\n\n1. Find the href of the locker, as above.  Normally one that does not have someone already allocated.\n\n1. Find the href of the cardholder using the [cardholders\n   API](cardholders#get-api-cardholders).\n\n3. [PATCH](cardholders#patch-api-cardholders-id-) the cardholder with the locker's\n   href in a property called `locker` in an element of an array called `add` inside an object called `lockers`.\n   Add `from` and `until` properties to the body of your PATCH, as you like.\n\n### Opening or quarantining a locker\n\nCommand Centre version 8.10.1112 lets you use the 'fields' parameter on the locker bank search\nto request the 'open' override URLs for lockers, which in prior versions was only available on\ntheir details pages.  Version 9.10 adds the ability to quarantine lockers, which prevents anyone\nfrom allocating them to a cardholder.\n\n1. `GET /api`\n2. Follow the link at `features.lockerBanks.lockerBanks.href`\n   [↪](lockers#get-api-locker_banks), adding `?` or `&` as appropriate then\n   `fields=name,lockers.name,lockers.shortName,lockers.commands`.  Also add a search term to\n   thin out the results, if you have a lot of locker banks.\n3. Dig through the results for your locker bank, then through the `lockers` array of that locker\n   bank for your locker, then into the `commands` block of that locker for another block called\n   `open` or `quarantine` depending on your need.  If your operator is able to override that\n   locker, that block will contain a field called `href` which gives the URL you need to\n   POST to override the locker ([open](lockers#post-api-lockers-id-open), for example).\n"}],"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"}}},"paths":{"/api/lockers/{id}/cancel_quarantine":{"post":{"tags":["Lockers"],"summary":"Un-quarantine a locker","description":"Sends an override to remove the quarantine from a locker, making it available for\nallocation.\n\nYou should get this URL from a [locker detail](models#lockerdetail) or [locker bank\ndetail](models#lockerbankdetail) rather than [building it\nyourself](forward-compatibility-hateoas).\n\nNew in 9.10.\n","responses":{"200":{"description":"Success.  Future versions will return feedback from the server."},"204":{"description":"Success."},"403":{"description":"The site does not have the RESTOverrides licence (in which case the body of the result\nwill say so), or your operator does not have 'Override' on the locker's division.\n"},"404":{"description":"That is not the URL of a locker, or it is the URL of a locker your operator does not\nhave the privilege to see.\n"}}}}}}
```


---

# 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/lockers.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.
