# Presence
## Methods
### getGet
Get the current presence member set for this channel. In the REST client library this method directly queries [Ably's REST presence API](https://ably.com/docs/api/rest-api.md#presence)
`get(Object params?): Promise`
`PaginatedResult get(Hash options)`
`PaginatedResult get(kwargs_options)`
`PaginatedResult get(Array options)`
`PaginatedResult get(Param[] options)`
`Task> GetAsync(int? limit = null, string clientId = null, string connectionId = null);`
`get(query: ARTPresenceQuery, callback: ([ARTPresenceMessage], ARTErrorInfo?) -> Void)`
`(p *RestPresence) Get(options *PaginateParams) (*PaginatedResult, error)`
`get(Object options, callback(ErrorInfo err, PaginatedResult resultPage))`
Gets an array of members present on the channel as [`PresenceMessage`](#presence-message) objects.
#### Parameters
| Name | Description |
|------|-------------|
| query | an optional object containing query parameters as specified below. |
| callback | called with a [`PaginatedResult`](#paginated-result)\<[`PresenceMessage`](#presence-message)>, or with an error |
| Name | Description |
|------|-------------|
| paramsquery[`Param[]`](#param) optionsoptions | an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of symbol key and value pairs containing the query parametersan optional Associate Array containing the query parameters as specified below. |
#### `options` parameters`params` parameters`ARTPresenceQuery` propertiesArguments
| Name | Description |
|------|-------------|
| clientIdclient_id:client_id| when provided, will filter array of members returned that match the provided [`clientId`](https://ably.com/docs/api/rest-sdk.md#client-options)[`client_id`](https://ably.com/docs/api/rest-sdk.md#client-options)[`ClientId`](https://ably.com/docs/api/rest-sdk.md#client-options) string |
| connectionIdconnection_id:connection_id | when provided, will filter array of members returned that match the provided [`connectionId`](https://ably.com/docs/api/realtime-sdk/connection.md#id)[`ConnectionId`](https://ably.com/docs/api/realtime-sdk/connection.md#id)[`connection_id`](https://ably.com/docs/api/realtime-sdk/connection.md#id) string |
#### Returns
Returns a promise. On success, the promise is fulfilled with an array of [`PresenceMessage`](#presence-message) objects corresponding to the current set of present members on the channel. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/rest-sdk/types.md#error-info) object that details the reason why it was rejected.
#### Returns
This method is asynchronous and needs to be awaited.
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of members currently present on the channel. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result)[`NextAsync`](#paginated-result) and [`first`](#paginated-result)[`FirstAsync`](#paginated-result) methods.
Failure to retrieve the current presence member set will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types.md#ably-exception)
#### Returns
This method is asynchronous and needs to be awaited.
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of members currently present on the channel. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
Failure to retrieve the current presence member, the `error` contains an [`ErrorInfo`](#error-info) object with the failure reason.
### historyHistory
`history(Object params?): Promise>`
`PaginatedResult history(Hash options)`
`PaginatedResult history(kwargs_options)`
`PaginatedResult history(Array options)`
`PaginatedResult history(Param[] options)`
`Task> HistoryAsync(PaginatedRequestParams query);`
`history(query: ARTDataQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void) throws`
`(p *RestPresence) History(params *PaginateParams) (*PaginatedResult, error)`
Gets a [paginated](#paginated-result) set of historical presence message events for this channel. If the [channel is configured to persist messages to disk](https://faqs.ably.com/how-long-are-messages-stored-for), then the presence message event history will [typically be available for 24 - 72 hours](https://faqs.ably.com/how-long-are-messages-stored-for). If not, presence message events are only retained in memory by the Ably service for two minutes.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| query | an optional object containing query parameters, as specified in the [presence history API documentation](https://ably.com/docs/storage-history/history.md#presence-history). | `ARTDataQuery` |
| callback | called with a [`ARTPaginatedResult`](#paginated-result)\<[`ARTPresenceMessage`](#presence-message)> object or an error | Callback |
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsquery[`Param[]`](#param) optionsoptions | an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing query parametersan optional Associate Array containing the query parameters, as specified in the [presence history API documentation](https://ably.com/docs/storage-history/history.md#presence-history). | Object[`PaginatedRequestParams`](#paginated-request-params)[`Param[]`](#param)Object |
#### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginated-result) object containing an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/rest-sdk/types.md#error-info) object that details the reason why it was rejected.
#### Callback result
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
On failure to retrieve message history, `err` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### Returns
This method is asynchronous and needs to be awaited.
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result)[`NextAsync`](#paginated-result) and [`first`](#paginated-result)[`FirstAsync`](#paginated-result) methods.
Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types.md#ably-exception)
#### Returns
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
Upon failure to retrieve the message history, the `error` contains an [`ErrorInfo`](#error-info) object with the failure reason.
## Related types
### PresenceMessageARTPresenceMessageAbly::Models::PresenceMessageio.ably.lib.types.PresenceMessageIO.Ably.PresenceMessage
A `PresenceMessage` represents an individual presence update that is sent to or received from Ably.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|-------------|------|
| actionActionAction | the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`Presence action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceAction`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage::action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { Absent, Present, Enter, Leave, Update }``int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { :absent, :present, :enter, :leave, :update }``const PresenceMessage::ABSENT,PRESENT,ENTER,LEAVE,UPDATE``ARTPresenceAction``const PresenceMessage::PresenceAbsent,PresencePresent,PresenceEnter,PresenceLeave,PresenceUpdate` |
| dataData | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, plain C# object that can be converted to Json`String`, `StringBuffer`, `JSON Object``String`, `[]byte``String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``String`, `Bytearray`, `Dict`, `List``String`, `NSData`, `Dictionary`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *``String`, `Binary String`, `Associative Array`, `Array` |
| extrasExtras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](https://ably.com/docs/push/publish.md#sub-channels), [`ref`](https://ably.com/docs/channels/messages.md#interactions) and [`privileged`](https://ably.com/docs/platform/integrations/webhooks.md#skipping) objects. | `JSONObject`, `JSONArray`plain C# object that can be converted to Json`String`, `[]byte``JSON Object``Hash`, `Array``Dict`, `List``Dictionary`, `Array``NSDictionary *`, `NSArray *``Associative Array`, `Array``Map`, `List` |
| idId | Unique ID assigned by Ably to this presence update | `String` |
| clientIdclient_idClientId | The client ID of the publisher of this presence update | `String` |
| connectionIdconnection_idConnectionId | The connection ID of the publisher of this presence update | `String` |
| timestampTimestamp | Timestamp when the presence update was received by Ably, as milliseconds since the epoch. | `Integer``Long Integer``DateTimeOffset``Time``NSDate` |
| encodingEncoding | This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload | `String` |
### PresenceMessage constructors
#### PresenceMessage.fromEncoded
`PresenceMessage.fromEncoded(Object encodedPresMsg, ChannelOptions channelOptions?) -> PresenceMessage`
A static factory method to create a [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types.md#presence-message) from a deserialized `PresenceMessage`-like object encoded using Ably's wire protocol.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedPresMsg | a `PresenceMessage`-like deserialized object. | `Object` |
| channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types.md#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` |
#### Returns
A [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types.md#presence-message) object
#### PresenceMessage.fromEncodedArray
`PresenceMessage.fromEncodedArray(Object[] encodedPresMsgs, ChannelOptions channelOptions?) -> PresenceMessage[]`
A static factory method to create an array of [`PresenceMessages`](https://ably.com/docs/api/realtime-sdk/types.md#presence-message) from an array of deserialized `PresenceMessage`-like object encoded using Ably's wire protocol.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedPresMsgs | an array of `PresenceMessage`-like deserialized objects. | `Array` |
| channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types.md#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` |
#### Returns
An `Array` of [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types.md#presence-message) objects
### Presence actionPresenceActionARTPresenceActionio.ably.lib.types.PresenceMessage.ActionAbly::Models::PresenceMessage::ACTIONIO.Ably.PresenceAction
`Presence` `action` is a String with a value matching any of the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```javascript
var PresenceActions = [
'absent', // (reserved for internal use)
'present',
'enter',
'leave',
'update'
]
```
```nodejs
var PresenceActions = [
'absent', // (reserved for internal use)
'present',
'enter',
'leave',
'update'
]
```
`io.ably.lib.types.PresenceMessage.Action` is an enum representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```java
public enum Action {
ABSENT, // 0 (reserved for internal use)
PRESENT, // 1
ENTER, // 2
LEAVE, // 3
UPDATE // 4
}
```
`IO.Ably.PresenceAction` is an enum representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```csharp
public enum Action {
Absent, // 0 (reserved for internal use)
Present, // 1
Enter, // 2
Leave, // 3
Update // 4
}
```
`PresenceAction` is an enum-like class representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```python
class PresenceAction(object):
ABSENT = 0 # (reserved for internal use)
PRESENT = 1
ENTER = 2
LEAVE = 3
UPDATE = 4
```
`PresenceMessage Action` is one of the class constants representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```php
namespace Ably\Models;
class PresenceMessages {
const ABSENT = 0; /* (reserved for internal use) */
const PRESENT = 1;
const ENTER = 2;
const LEAVE = 3;
const UPDATE = 4;
}
```
#### Example usage
```php
if ($presenceMessage->action == Ably\Models\PresenceMesage::ENTER) {
/* do something */
}
```
`Ably::Models::PresenceMessage::ACTION` is an enum-like value representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events). `ACTION` can be represented interchangeably as either symbols or constants.
#### Symbol states
```ruby
:absent # => 0 (reserved for internal use)
:present # => 1
:enter # => 2
:leave # => 3
:update # => 4
```
#### Constant states
```ruby
PresenceMessage::ACTION.Absent # => 0 (internal use)
PresenceMessage::ACTION.Present # => 1
PresenceMessage::ACTION.Enter # => 2
PresenceMessage::ACTION.Leave # => 3
PresenceMessage::ACTION.Update # => 4
```
#### Example usage
```ruby
# Example with symbols
presence.on(:attached) { ... }
# Example with constants
presence.on(Ably::Models::PresenceMessage::ACTION.Enter) { ... }
# Interchangeable
Ably::Models::PresenceMessage::ACTION.Enter == :enter # => true
```
`ARTPresenceAction` is an enum representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```objc
typedef NS_ENUM(NSUInteger, ARTPresenceAction) {
ARTPresenceAbsent, // reserved for internal use
ARTPresencePresent,
ARTPresenceEnter,
ARTPresenceLeave,
ARTPresenceUpdate
};
```
```swift
enum ARTPresenceAction : UInt {
case Absent // reserved for internal use
case Present
case Enter
case Leave
case Update
}
```
`Presence` `action` is a String with a value matching any of the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```go
const (
PresenceAbsent = 0
PresencePresent = 1
PresenceEnter = 2
PresenceLeave = 3
PresenceUpdate = 4
)
```
### PaginatedRequestParams
`HistoryRequestParams` is a type that encapsulates the parameters for a history queries. For example usage see [`Channel#History`](https://ably.com/docs/api/realtime-sdk/history.md#channel-history).
#### Members
| Member | Description | Type |
|--------|-------------|------|
| Start | The start of the queried interval | `DateTimeOffset` |
| End | The end of the queried interval | `DateTimeOffset` |
| Limit | By default it is null. Limits the number of items returned by history or stats | `Integer` |
| Direction | _Backwards_ Enum which is either `Forwards` or `Backwards` | `Direction` enum |
| ExtraParameters | Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging. | `Dictionary` |
### PaginatedResultARTPaginatedResultAbly::Models::PaginatedResultio.ably.lib.types.PaginatedResultIO.Ably.PaginatedResult
A `PaginatedResult` is a type that represents a page of results for all message and presence history, stats and REST presence requests. The response from a [Ably REST API paginated query](https://ably.com/docs/api/rest-api.md#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|-------------|------|
| itemsItemsItemsitems | contains the current page of results (for example an Array of `Message` or `PresenceMessage` objects for a channel history request) | `Array ``List ``Array ``List ` |
#### Methods
##### firstFirst
`first(): Promise`
`PaginatedResult first`
`PaginatedResult first()`
`PaginatedResult first()`
`PaginatedResult first()`
`Task> FirstAsync()`
`first(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
`First() (PaginatedResult, error)`
Returns a new `PaginatedResult` for the first page of results. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and yields a [PaginatedResult](#paginated-result).The method is asynchronous and returns a Task which needs to be awaited to get the [PaginatedResult](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` for the first page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### hasNextHasNexthas_next?has_next
`Boolean hasNext()`
`Boolean has_next?`
`Boolean has_next()`
`Boolean HasNext()`
`HasNext() (bool)`
Returns `true` if there are more pages available by calling `next``Next` and returns `false` if this page is the last page available.
##### isLastIsLastlast?is_last
`Boolean isLast()`
`Boolean last?`
`Boolean is_last()`
`Boolean IsLast()`
`IsLast() (bool)`
Returns `true` if this page is the last page and returns `false` if there are more pages available by calling `next``Next` available.
##### nextNext
`next(): Promise`
`PaginatedResult next`
`PaginatedResult next()`
`PaginatedResult next()`
`PaginatedResult next()`
`Task> NextAsync()`
`next(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
`Next() (PaginatedResult, error)`
Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null`a blank PaginatedResult will be returned`Null``None``nil` is returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult`When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and yields a [PaginatedResult](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null` is returned. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### current
`current(): Promise`
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the current page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
#### Example
```javascript
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```nodejs
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```java
PaginatedResult firstPage = channel.history();
System.out.println("Page 0 item 0:" + firstPage.items[0].data);
if (firstPage.hasNext) {
PaginatedResult nextPage = firstPage.next();
System.out.println("Page 1 item 1:" + nextPage.items[1].data);
System.out.println("More pages?:" + Strong.valueOf(nextPage.hasNext()));
};
```
```csharp
PaginatedResult firstPage = await channel.HistoryAsync(null);
Message firstMessage = firstPage.Items[0];
Console.WriteLine("Page 0 item 0: " + firstMessage.data);
if (firstPage.HasNext)
{
var nextPage = await firstPage.NextAsync();
Console.WriteLine("Page 1 item 1:" + nextPage.Items[1].data);
Console.WriteLine("More pages?: " + nextPage.HasNext());
}
```
```ruby
# When using the REST sync library
first_page = channel.history
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
next_page = first_page.next
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
# When using the Realtime EventMachine library
channel.history do |first_page|
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
first_page.next do |next_page|
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
end
end
```
```python
result_page = channel.history()
print 'Page 0 item 0: ' + str(result_page.items[0].data)
if result_page.has_next():
next_page = result_page.next()
print 'Page 1 item 1: ' + str(next_page.items[1].data)
print 'Last page?: ' + str(next_page.is_last())
```
```php
$firstPage = $channel.history();
echo("Page 0 item 0: " . $firstPage->items[0]->data);
if ($firstPage->hasNext()) {
$nextPage = $firstPage->next();
echo("Page 1 item 1: " . $nextPage->items[1]->data);
echo("Last page?: " . $nextPage->isLast());
}
```
```objc
[channel history:^(ARTPaginatedResult *paginatedResult, ARTErrorInfo *error) {
NSLog(@"Page 0 item 0: %@", paginatedResult.items[0].data);
[paginatedResult next:^(ARTPaginatedResult *nextPage, ARTErrorInfo *error) {
NSLog(@"Page 1 item 1: %@", nextPage.items[1].data);
NSLog(@"Last page?: %d", nextPage.isLast());
}];
}];
```
```swift
channel.history { paginatedResult, error in
guard let paginatedResult = paginatedResult else {
print("No results available")
return
}
print("Page 0 item 0: \((paginatedResult.items[0] as! ARTMessage).data)")
paginatedResult.next { nextPage, error in
guard let nextPage = nextPage else {
print("No next page available")
return
}
print("Page 1 item 1: \((nextPage.items[1] as! ARTMessage).data)")
print("Last page? \(nextPage.isLast())")
}
}
```
```go
page0, err := channel.History(nil)
fmt.Println("Page. 0 item 0: %s\n", page0.Messages[0].Data)
page1, err := page0.Next()
fmt.Println("Page. 1 item 1: %s\n", page1.Messages[1].Data)
fmt.Println("Last page? %s\n", page1.IsLast())
```
### io.ably.lib.types.Param
`Param` is a type encapsulating a key/value pair. This type is used frequently in method parameters allowing key/value pairs to be used more flexible, see [`Channel#history`](https://ably.com/docs/api/realtime-sdk/history.md#channel-history) for an example.
Please note that `key` and `value` attributes are always strings. If an `Integer` or other value type is expected, then you must coerce that type into a `String`.
#### Members
| Name | Description | Type |
|------|-------------|------|
| key | The key value | `String` |
| value | The value associated with the `key` | `String` |