General methods are utility functions available on the Client class that work across all object types. They provide core functionality for searching, counting, aggregating, and managing objects in the acre Access Control API.
| Category | Description | Key Methods |
|---|---|---|
| Search & Query | Find objects using MongoDB queries | SearchAsync, SearchOneAsync, GetByMonikerAsync |
| Object Retrieval | Get objects by ID or href | GetByIdsAsync, GetByHrefAsync |
| Aggregation | Run MongoDB aggregation pipelines | AggregateAsync, AggregateAsJsonAsync |
| Counting | Count objects by type | GetObjectCountsAsync |
| Encryption | Encrypt/decrypt sensitive data | EncryptData, DecryptData |
| Client Properties | Access client configuration | BaseAddress, TokenResponse, UserAgent |
| SAML/SSO | Configure identity providers | SetSamlIdentityProviderConfiguration |
| Method Type | Default Return |
|---|---|
| Search methods | IEnumerable<BaseInfo> (cast to specific types) |
| Count methods | long |
| Single object | BaseInfo or specified generic <T> |
| Aggregation | BsonDocument[] or string (JSON) |
Tip: Use
.OfType<T>()to filter search results to specific object types:var people = (await client.SearchAsync(folder, query)) .OfType<PersonInfo>() .ToList();
When specifying object types in queries, use the type name without the “Info” suffix:
| C# Class | Type Name |
|---|---|
[PersonInfo](/object-model/personinfo/) |
Person |
[ControllerInfo](/object-model/controllerinfo/) |
Controller |
ReaderInfo |
Reader |
[AccessLevelInfo](/object-model/accesslevelinfo/) |
AccessLevel |
[ScheduleInfo](/object-model/scheduleinfo/) |
Schedule |
[BaseInfo](/object-model/baseinfo/) |
KeepObject |
// Search with MongoDB-style query
var results = await client.SearchAsync(
folder,
"{ '_t': 'Person', 'Surname': 'Smith' }",
includeChildFolders: true
);
// Search for exactly one object
var person = await client.SearchOneAsync<PersonInfo>(
folder,
"{ 'CommonName': 'John Smith' }"
);
// Get multiple objects by key
var objects = await client.GetByIdsAsync(new[] { key1, key2, key3 });
// Get by href path
var controller = await client.GetByHrefAsync<ControllerInfo>(
"/api/f/folder-key/controllers/controller-key"
);
// Get by moniker
var eventType = await client.GetByMonikerAsync<EventTypeInfo>(
"MercuryServiceEvents",
"mercury:access-granted"
);
// Count all people in folder
var count = await client.GetObjectCountsAsync(folder, "Person");
// Count with child folders
var totalCount = await client.GetObjectCountsAsync(
folder,
"Controller",
includeChildFolders: true
);
// Run aggregation pipeline
var pipeline = new BsonDocument[]
{
new BsonDocument("$match", new BsonDocument("_t", "Person")),
new BsonDocument("$group", new BsonDocument
{
["_id"] = "$Department",
["count"] = new BsonDocument("$sum", 1)
})
};
var results = await client.AggregateAsync(folder, "KeepObjects", pipeline);
Example in C#
// Returns: nothing
await client.AddAccessLevelAcreIntrusionEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelAcreIntrusionEntryItem entryItem);
Overview of AddAccessLevelAcreIntrusionEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelAssaAbloyEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelAssaAbloyEntryItem entryItem);
Overview of AddAccessLevelAssaAbloyEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelBatchForPersonAsync(PersonInfo person, ObjectLinkItem accessLevelLinkItems);
Overview of AddAccessLevelBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelBatchForPersonAsync(String personHref, ObjectLinkItem accessLevelLinkItems, String batchLink);
Overview of AddAccessLevelBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelElevatorEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelElevatorEntryItem entryItem);
Overview of AddAccessLevelElevatorEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelEntryItem entryItem);
Overview of AddAccessLevelEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelGroupBatchForPersonAsync(PersonInfo person, ObjectLinkItem accessLevelGroupLinkItems);
Overview of AddAccessLevelGroupBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelGroupBatchForPersonAsync(String personHref, ObjectLinkItem accessLevelGroupLinkItems, String batchLink);
Overview of AddAccessLevelGroupBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.AddAccessLevelTrakaEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelTrakaEntryItem entryItem);
Overview of AddAccessLevelTrakaEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddAcreIntrusionPanelAreaEntryItemAsync(AcreIntrusionUserProfileInfo userProfile, AcreIntrusionPanelRelationEntryItem panelRelation, AcreIntrusionAreaEntryItem entryItem);
Overview of AddAcreIntrusionPanelAreaEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddAcreIntrusionPanelRelationEntryItemAsync(AcreIntrusionUserProfileInfo userProfile, AcreIntrusionPanelRelationEntryItem entryItem);
Overview of AddAcreIntrusionPanelRelationEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.AddCardholderGroupAccessRightItemAsync(CardholderGroupInfo cardholderGroup, CardholderGroupAccessRightItem entryItem);
Overview of AddCardholderGroupAccessRightItemAsync goes here.
Example in C#
// Returns: TrakaItemInfo
var trakaItemInfo = await client.AddTrakaItemAsync(FolderInfo folder, TrakaItemInfo item);
Overview of AddTrakaItemAsync goes here.
Example in C#
// Returns: nothing
await client.AssignConnectedObjectAsync(String targetHref, String connectionLink, String connectedObjectKey, String relation, Boolean isOneToOne, Object meta, Boolean addAsTag);
Overview of AssignConnectedObjectAsync goes here.
Example in C#
// Returns: ScheduleInfo
var scheduleInfo = await client.CheckScheduleIsActiveAsync(ScheduleInfo schedule);
Overview of CheckScheduleIsActiveAsync goes here.
Example in C#
// Returns: Boolean
var item = await client.CheckScriptLastRunAsync(FitPackageInfo packageInfo, String scriptName, Int32 minTimeBetweenRunsInMilliseconds);
Overview of CheckScriptLastRunAsync goes here.
Example in C#
// Returns: nothing
await client.CleanAcreIntrusionPanelMonikersAsync(AcreIntrusionPanelInfo acreIntrusionPanel);
Overview of CleanAcreIntrusionPanelMonikersAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAccessLevelAcreIntrusionEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelAcreIntrusionEntryItem entryItem);
Overview of DeleteAccessLevelAcreIntrusionEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAccessLevelAssaAbloyEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelAssaAbloyEntryItem entryItem);
Overview of DeleteAccessLevelAssaAbloyEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAccessLevelElevatorEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelElevatorEntryItem entryItem);
Overview of DeleteAccessLevelElevatorEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAccessLevelEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelEntryItem entryItem);
Overview of DeleteAccessLevelEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAccessLevelTrakaEntryItemAsync(AccessLevelInfo accessLevel, AccessLevelTrakaEntryItem entryItem);
Overview of DeleteAccessLevelTrakaEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAcreIntrusionPanelAreaEntryItemAsync(AcreIntrusionUserProfileInfo userProfile, AcreIntrusionPanelRelationEntryItem panelRelation, AcreIntrusionAreaEntryItem entryItem);
Overview of DeleteAcreIntrusionPanelAreaEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteAcreIntrusionPanelRelationEntryItemAsync(AcreIntrusionUserProfileInfo userProfile, AcreIntrusionPanelRelationEntryItem entryItem);
Overview of DeleteAcreIntrusionPanelRelationEntryItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteCardholderGroupAccessRightItemItemAsync(CardholderGroupInfo cardholderGroup, CardholderGroupAccessRightItem entryItem);
Overview of DeleteCardholderGroupAccessRightItemItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteIconsAsync(FolderInfo folder, String tag);
Overview of DeleteIconsAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteTrakaItemAsync(TrakaItemInfo item);
Overview of DeleteTrakaItemAsync goes here.
Example in C#
// Returns: nothing
await client.DeleteWalletCredentialAsync(WalletGroupInfo walletGroup, WavelynxCardDeleteRequest deleteRequest);
Overview of DeleteWalletCredentialAsync goes here.
Example in C#
// Returns: ExtendCardExpiryResponse
var extendCardExpiryResponse = await client.DisableActiveCardsAsync(FolderInfo folder, String query, Boolean trialRun);
Overview of DisableActiveCardsAsync goes here.
Example in C#
// Returns: nothing
await client.EndBatch(InstanceInfo instance);
Overview of EndBatch goes here.
Example in C#
// Returns: Boolean
var item = client.Equals(Object obj);
The Equals method determines whether the specified object is equal to the current Client instance. This is a standard .NET object comparison method inherited from System.Object.
public override bool Equals(object obj)
The Equals method provides object equality comparison for the Client class. This method is inherited from the base Object class and can be used to:
using Feenics.Keep.WebApi.Wrapper;
// Create two client instances
var client1 = new Client("https://keep.feenics.com");
var client2 = new Client("https://keep.feenics.com");
var client3 = client1;
// Compare instances
bool areEqual1 = client1.Equals(client2); // false - different instances
bool areEqual2 = client1.Equals(client3); // true - same reference
bool areEqual3 = client1.Equals(null); // false - comparing to null
Console.WriteLine($"client1 equals client2: {areEqual1}");
Console.WriteLine($"client1 equals client3: {areEqual2}");
Console.WriteLine($"client1 equals null: {areEqual3}");
| Parameter | Type | Description |
|---|---|---|
| obj | object |
The object to compare with the current instance |
| Type | Description |
|---|---|
bool |
true if the specified object is equal to the current instance; otherwise, false |
💡 Reference Equality: By default,
Equalscompares object references, not the values of properties likeBaseAddressor configuration settings.
💡 Null Safety: Calling
Equals(null)always returnsfalseand does not throw an exception.
// If you need to compare based on configuration
bool sameServer = client1.BaseAddress == client2.BaseAddress;
bool sameUser = client1.TokenResponse?.UserId == client2.TokenResponse?.UserId;
Example in C#
// Returns: ExtendCardExpiryResponse
var extendCardExpiryResponse = await client.ExtendExpiredCardsAsync(FolderInfo folder, DateTime expiredFrom, DateTime expiryEnd, DateTime newExpiresOn, Boolean trialRun);
Overview of ExtendExpiredCardsAsync goes here.
Example in C#
// Returns: String
var item = client.BaseAddress;
Returns the base URL of the acre Access Control API that the client is connected to.
string BaseAddress { get; }
The API base URL as a string (e.g., https://api.us.acresecurity.cloud).
var client = new Client(
"https://api.us.acresecurity.cloud",
clientId,
clientSecret
);
await client.AuthenticateAsync();
// Get the base address
Console.WriteLine($"Connected to: {client.BaseAddress}");
// Output: Connected to: https://api.us.acresecurity.cloud
| Use Case | Description |
|---|---|
| Logging | Log which environment is being used |
| Multi-environment | Verify correct environment connection |
| URL construction | Build full URLs for direct HTTP calls |
Example in C#
// Returns: Int64
var item = client.BytesTransferred;
Overview of get_BytesTransferred goes here.
Example in C#
// Returns: Int64
var item = client.CallElapsed;
Overview of get_CallElapsed goes here.
Example in C#
// Returns: String
var item = client.ClientAppId;
The ClientAppId property returns the unique identifier for the client application making API requests. This ID is used by the Keep API to identify and track requests from specific client applications.
public string ClientAppId { get; set; }
The ClientAppId property provides access to the application identifier that is included in API request headers. This identifier helps the Keep API:
using Feenics.Keep.WebApi.Wrapper;
// Create and configure the client
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-client-app");
// Retrieve the current Client App ID
string appId = client.ClientAppId;
Console.WriteLine($"Current Client App ID: {appId}");
// The ClientAppId is typically set during authentication
// but can be modified if needed
client.ClientAppId = "updated-client-app-id";
| Type | Description |
|---|---|
string |
The client application identifier currently configured on the wrapper |
Example in C#
// Returns: String
var item = client.DeviceId;
The DeviceId property returns the unique identifier for the device making API requests. This ID helps the Keep API distinguish between different devices or installations of the same client application.
public string DeviceId { get; set; }
The DeviceId property provides access to the device identifier that is included in API request headers. This identifier is particularly useful for:
using Feenics.Keep.WebApi.Wrapper;
// Create and configure the client
var client = new Client("https://keep.feenics.com");
// Set a unique device identifier before authentication
client.DeviceId = Guid.NewGuid().ToString();
await client.OpenAsync("username", "password", "my-client-app");
// Retrieve the current Device ID
string deviceId = client.DeviceId;
Console.WriteLine($"Current Device ID: {deviceId}");
// For mobile applications, use a persistent device identifier
public async Task InitializeClientAsync()
{
var client = new Client("https://keep.feenics.com");
// Use a stored device ID or generate a new one
string deviceId = await SecureStorage.GetAsync("device_id");
if (string.IsNullOrEmpty(deviceId))
{
deviceId = Guid.NewGuid().ToString();
await SecureStorage.SetAsync("device_id", deviceId);
}
client.DeviceId = deviceId;
// Now authenticate
await client.OpenAsync("username", "password", "mobile-app");
}
| Type | Description |
|---|---|
string |
The device identifier currently configured on the wrapper |
Example in C#
// Returns: FlurlClient
var flurlClient = client.FlurlClient;
The FlurlClient property provides access to the underlying Flurl HTTP client used by the wrapper for all API communications. This allows advanced users to customize HTTP behavior or access low-level HTTP features.
public IFlurlClient FlurlClient { get; }
The Keep API Wrapper uses Flurl as its HTTP client library. The FlurlClient property exposes this underlying client, enabling:
using Feenics.Keep.WebApi.Wrapper;
using Flurl.Http;
// Create the wrapper client
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Access the underlying Flurl client
IFlurlClient flurlClient = client.FlurlClient;
// Configure custom timeout
flurlClient.WithTimeout(TimeSpan.FromSeconds(60));
// Add custom headers for all requests
flurlClient.WithHeader("X-Custom-Header", "CustomValue");
using Feenics.Keep.WebApi.Wrapper;
using Flurl.Http;
using Flurl.Http.Configuration;
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Configure advanced HTTP settings
var flurlClient = client.FlurlClient;
// Add request/response logging
flurlClient.BeforeCall(call =>
{
Console.WriteLine($"Request: {call.Request.Verb} {call.Request.Url}");
});
flurlClient.AfterCall(call =>
{
Console.WriteLine($"Response: {call.Response?.StatusCode}");
});
// Handle errors globally
flurlClient.OnError(call =>
{
Console.WriteLine($"Error: {call.Exception?.Message}");
call.ExceptionHandled = true; // Prevent exception from bubbling up
});
| Type | Description |
|---|---|
IFlurlClient |
The Flurl HTTP client instance used for API requests |
⚠️ Caution: Modifying the FlurlClient can affect the behavior of all wrapper methods. Make changes carefully and test thoroughly.
💡 Tip: For most use cases, the wrapper’s built-in methods are sufficient. Only access FlurlClient when you need advanced HTTP customization.
| Use Case | Configuration |
|---|---|
| Increase timeout | flurlClient.WithTimeout(TimeSpan.FromMinutes(5)) |
| Add proxy | flurlClient.Settings.HttpClientFactory = new ProxyHttpClientFactory() |
| Custom logging | Use BeforeCall and AfterCall handlers |
| Retry logic | Implement using OnError handler |
Example in C#
// Returns: TokenResponse
var tokenResponse = client.TokenResponse;
Returns the current OAuth token response containing the access token, refresh token, and expiration information.
TokenResponse TokenResponse { get; set; }
| Property | Type | Description |
|---|---|---|
access_token |
string |
Bearer token for API authentication |
refresh_token |
string |
Token for obtaining new access tokens |
expires_in |
int |
Seconds until token expiration |
token_type |
string |
Always “Bearer” |
// Check current token
var token = client.TokenResponse;
Console.WriteLine($"Token expires in: {token.expires_in} seconds");
// Create new client with existing token
var existingToken = new TokenResponse
{
access_token = "existing-token-value"
};
var newClient = new Client(
"https://api.acresecurity.cloud",
existingToken,
userAgent: "MyApp/1.0"
);
| Use Case | Description |
|---|---|
| Token reuse | Pass token to another client instance |
| Debugging | Inspect token for troubleshooting |
| Token refresh | Check expiration before calls |
Example in C#
// Returns: String
var item = client.UserAgent;
The UserAgent property returns the user agent string that is sent with all API requests. This string identifies the client application, version, and platform making requests to the Keep API.
public string UserAgent { get; }
The UserAgent property provides access to the user agent header value included in all HTTP requests. This identifier helps with:
using Feenics.Keep.WebApi.Wrapper;
// Create and authenticate the client
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Retrieve the user agent string
string userAgent = client.UserAgent;
Console.WriteLine($"User Agent: {userAgent}");
// Example output: "Keep.WebApi.Wrapper/2.0.0 (Windows NT 10.0; .NET 6.0)"
The user agent typically follows this format:
{ApplicationName}/{Version} ({Platform}; {Framework})
| Component | Description | Example |
|---|---|---|
| Application Name | Name of the wrapper library | Keep.WebApi.Wrapper |
| Version | Version of the wrapper | 2.0.0 |
| Platform | Operating system information | Windows NT 10.0, iOS 16.0 |
| Framework | Runtime framework | .NET 6.0, Xamarin.iOS |
// Windows Desktop Application
// "Keep.WebApi.Wrapper/2.0.0 (Windows NT 10.0; .NET 6.0)"
// iOS Mobile Application
// "Keep.WebApi.Wrapper/2.0.0 (iOS 16.0; Xamarin.iOS)"
// Android Mobile Application
// "Keep.WebApi.Wrapper/2.0.0 (Android 13; Xamarin.Android)"
// macOS Application
// "Keep.WebApi.Wrapper/2.0.0 (macOS 13.0; .NET 6.0)"
// Linux Server
// "Keep.WebApi.Wrapper/2.0.0 (Linux; .NET 6.0)"
using Feenics.Keep.WebApi.Wrapper;
public async Task DiagnoseConnectionAsync(Client client)
{
Console.WriteLine("=== Connection Diagnostics ===");
Console.WriteLine($"Base Address: {client.BaseAddress}");
Console.WriteLine($"User Agent: {client.UserAgent}");
Console.WriteLine($"Client App ID: {client.ClientAppId}");
Console.WriteLine($"Device ID: {client.DeviceId}");
// Test connection
try
{
var instances = await client.GetInstancesAsync();
Console.WriteLine($"Connected successfully. Found {instances.Count()} instances.");
}
catch (Exception ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
}
}
| Type | Description |
|---|---|
string |
The user agent string identifying the client application and platform |
Example in C#
// Returns: IEnumerable<String>
var item = await client.GetAllInstalledBulkActionObjectTypes(FolderInfo folder);
Overview of GetAllInstalledBulkActionObjectTypes goes here.
Example in C#
// Returns: IEnumerable<SmartControllerPortItem>
var smartControllerPortItem = await client.GetAsc1400PortsAsync(Asc1400Info controller);
Overview of GetAsc1400PortsAsync goes here.
Example in C#
// Returns: IEnumerable<TrakaCabinetInfo>
var trakaCabinetInfo = await client.GetCabinetsForTrakaServiceAsync(TrakaServiceInfo service);
Overview of GetCabinetsForTrakaServiceAsync goes here.
Example in C#
// Returns: Int32
var item = client.GetHashCode();
The GetHashCode method returns a hash code for the current Client instance. This is a standard .NET method inherited from System.Object that is used for hash-based collection operations.
public override int GetHashCode()
The GetHashCode method generates a numeric hash value that represents the current object. This hash code is used by:
Dictionary<TKey, TValue>, HashSet<T>, and Hashtable use hash codes for efficient lookupsEquals for object comparisonusing Feenics.Keep.WebApi.Wrapper;
// Create a client instance
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Get the hash code
int hashCode = client.GetHashCode();
Console.WriteLine($"Client hash code: {hashCode}");
// Example: Using client as dictionary key
var clientData = new Dictionary<Client, string>();
clientData[client] = "Primary Connection";
// Retrieve using the same reference
string data = clientData[client];
Console.WriteLine($"Data: {data}");
| Type | Description |
|---|---|
int |
A 32-bit signed integer hash code representing the object |
| Characteristic | Description |
|---|---|
| Consistency | Same object returns same hash code during its lifetime |
| Not Unique | Different objects may have the same hash code (collision) |
| Reference-Based | Default implementation is based on object reference |
| Session-Specific | Hash codes may differ between application runs |
⚠️ Not for Persistence: Hash codes should not be stored or used across application sessions
⚠️ Collision Possible: Two different objects may return the same hash code
💡 Equality Contract: If
Equalsreturns true for two objects, they must have the same hash code
Equals for object comparison, not hash codesusing Feenics.Keep.WebApi.Wrapper;
public class ClientConnectionPool
{
private readonly HashSet<Client> _activeClients = new HashSet<Client>();
public void AddClient(Client client)
{
// HashSet uses GetHashCode internally
_activeClients.Add(client);
}
public bool IsClientActive(Client client)
{
// Lookup uses GetHashCode for efficiency
return _activeClients.Contains(client);
}
public void RemoveClient(Client client)
{
_activeClients.Remove(client);
}
}
Example in C#
// Returns: MarketplaceUIPointsResponse
var item = await client.GetMarketplaceUIPointsAsync(FolderInfo folder);
Overview of GetMarketplaceUIPointsAsync goes here.
Example in C#
// Returns: Int64
var item = await client.GetNextAvailableCardNumberAsync(FolderInfo folder, Int64 startingValue);
Overview of GetNextAvailableCardNumberAsync goes here.
Example in C#
// Returns: String
var item = await client.GetNonceAsync(PersonInfo person);
Overview of GetNonceAsync goes here.
Example in C#
// Returns: Int64
var item = await client.GetRandom40BitCardNumber();
Overview of GetRandom40BitCardNumber goes here.
Example in C#
// Returns: Int64
var item = await client.GetRandomVisitCodeAsync(FolderInfo folder);
Overview of GetRandomVisitCodeAsync goes here.
Example in C#
// Returns: IEnumerable<NotificationInfo>
var notificationInfo = await client.GetReadNotificationsForUserAsync(FolderInfo folder, UserInfo user, DateTime beforeStartDate, DateTime beforeEndDate, Int32 skip, Int32 limit);
Overview of GetReadNotificationsForUserAsync goes here.
Example in C#
// Returns: IEnumerable<SmartControllerPortItem>
var smartControllerPortItem = await client.GetSmartControllerPortDefinitionsAsync(AcreControllerInfo controllerInfo);
Overview of GetSmartControllerPortDefinitionsAsync goes here.
Example in C#
// Returns: IEnumerable<SmartControllerPortItem>
var smartControllerPortItem = await client.GetSmartControllerPortDefinitionsAsync<T>();
Overview of GetSmartControllerPortDefinitionsAsync goes here.
Example in C#
// Returns: IEnumerable<SmartControllerPortItem>
var smartControllerPortItem = await client.GetSmartControllerPortDefinitionsAsync(String controllerTypeInfoName);
Overview of GetSmartControllerPortDefinitionsAsync goes here.
Example in C#
// Returns: IEnumerable<String>
var item = await client.GetSupportedReaderTypes<T>();
Overview of GetSupportedReaderTypes goes here.
Example in C#
// Returns: IEnumerable<String>
var item = await client.GetSupportedReaderTypes(String readerProfileTypeName);
Overview of GetSupportedReaderTypes goes here.
Example in C#
// Returns: TrakaItemInfo
var trakaItemInfo = await client.GetTrakaItemAsync(FolderInfo folder, String itemId);
Overview of GetTrakaItemAsync goes here.
Example in C#
// Returns: IEnumerable<TrakaItemInfo>
var trakaItemInfo = await client.GetTrakaItemsAsync(FolderInfo folder);
Overview of GetTrakaItemsAsync goes here.
Example in C#
// Returns: Type
var type = client.GetType();
The GetType method returns the runtime type of the current Client instance. This is a standard .NET method inherited from System.Object that provides reflection capabilities.
public Type GetType()
The GetType method returns a Type object that represents the exact runtime type of the current instance. This is useful for:
using Feenics.Keep.WebApi.Wrapper;
// Create a client instance
var client = new Client("https://keep.feenics.com");
// Get the runtime type
Type clientType = client.GetType();
// Display type information
Console.WriteLine($"Type Name: {clientType.Name}");
Console.WriteLine($"Full Name: {clientType.FullName}");
Console.WriteLine($"Namespace: {clientType.Namespace}");
Console.WriteLine($"Assembly: {clientType.Assembly.GetName().Name}");
Type Name: Client
Full Name: Feenics.Keep.WebApi.Wrapper.Client
Namespace: Feenics.Keep.WebApi.Wrapper
Assembly: Feenics.Keep.WebApi.Wrapper
| Type | Description |
|---|---|
Type |
A System.Type object representing the runtime type of the instance |
using Feenics.Keep.WebApi.Wrapper;
using System.Reflection;
var client = new Client("https://keep.feenics.com");
Type clientType = client.GetType();
// List all public methods
Console.WriteLine("=== Public Methods ===");
foreach (MethodInfo method in clientType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
Console.WriteLine($" {method.Name}");
}
// List all public properties
Console.WriteLine("\n=== Public Properties ===");
foreach (PropertyInfo prop in clientType.GetProperties())
{
Console.WriteLine($" {prop.Name}: {prop.PropertyType.Name}");
}
// Check for specific interface implementation
bool implementsDisposable = typeof(IDisposable).IsAssignableFrom(clientType);
Console.WriteLine($"\nImplements IDisposable: {implementsDisposable}");
using Feenics.Keep.WebApi.Wrapper;
public void ProcessObject(object obj)
{
Type objType = obj.GetType();
// Check if it's a Client
if (objType == typeof(Client))
{
var client = (Client)obj;
Console.WriteLine($"Processing Client for: {client.BaseAddress}");
}
// Alternative: Use pattern matching (preferred in modern C#)
if (obj is Client typedClient)
{
Console.WriteLine($"Processing Client for: {typedClient.BaseAddress}");
}
}
using Feenics.Keep.WebApi.Wrapper;
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Get property value dynamically
Type clientType = client.GetType();
PropertyInfo baseAddressProp = clientType.GetProperty("BaseAddress");
if (baseAddressProp != null)
{
object value = baseAddressProp.GetValue(client);
Console.WriteLine($"Base Address (via reflection): {value}");
}
💡 Runtime Type: Returns the actual runtime type, which may be a derived type
💡 Never Null: This method never returns null
💡 Performance: Reflection operations can be slower than direct property access
is and switch patternsExample in C#
// Returns: IEnumerable<NotificationInfo>
var notificationInfo = await client.GetUnreadNotificationsForUserAsync(FolderInfo folder, UserInfo user, DateTime beforeStartDate, DateTime beforeEndDate, Int32 skip, Int32 limit, DateTime afterStartDate, DateTime afterEndDate);
Overview of GetUnreadNotificationsForUserAsync goes here.
Example in C#
// Returns: nothing
await client.InitializeReader(MercuryReaderInfo reader);
Overview of InitializeReader goes here.
Example in C#
// Returns: nothing
await client.LeaveScriptQueue(FolderInfo folder, String scriptQueueObjectId);
Overview of LeaveScriptQueue goes here.
Example in C#
// Returns: Boolean
var item = await client.LogoutAsync();
Overview of LogoutAsync goes here.
Example in C#
// Returns: nothing
await client.MarkAllNotificationAsReadForUser(FolderInfo folder, UserInfo user);
Overview of MarkAllNotificationAsReadForUser goes here.
Example in C#
// Returns: nothing
await client.MarkNotificationAsReadForUser(FolderInfo folder, NotificationInfo notification, UserInfo user);
Overview of MarkNotificationAsReadForUser goes here.
Example in C#
// Returns: nothing
await client.MarkNotificationAsUnreadForUser(FolderInfo folder, NotificationInfo notification, UserInfo user);
Overview of MarkNotificationAsUnreadForUser goes here.
Example in C#
// Returns: Boolean
var item = await client.MarkPersonInAsync(PersonInfo person, String readerId);
Overview of MarkPersonInAsync goes here.
Example in C#
// Returns: Boolean
var item = await client.MarkPersonOutAsync(PersonInfo person, String readerId);
Overview of MarkPersonOutAsync goes here.
Example in C#
// Returns: nothing
await client.PatchCardAssignmentAsync(String personHref, String cardAssignmentKey, CardAssignmentInfo patchDoc, String encodedCardNumberStringOverride);
Overview of PatchCardAssignmentAsync goes here.
Example in C#
// Returns: nothing
await client.PatchWithQueryParams(item patchDoc, Object queryParameters, String uriSegments);
Overview of PatchWithQueryParams goes here.
Example in C#
// Returns: WalletVisitorCardResponse
var walletVisitorCardResponse = await client.PostCorporateCardAsync(WalletGroupInfo walletGroup, WalletCorporateCardRequest corporateCardRequest);
Overview of PostCorporateCardAsync goes here.
Example in C#
// Returns: WalletVisitorCardResponse
var walletVisitorCardResponse = await client.PostVisitorCardAsync(WalletGroupInfo walletGroup, WalletVisitorCardRequest visitorCardRequest);
Overview of PostVisitorCardAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveAccessLevelBatchForPersonAsync(PersonInfo person, ObjectLinkItem accessLevelLinkItems);
Overview of RemoveAccessLevelBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveAccessLevelBatchForPersonAsync(String personHref, ObjectLinkItem accessLevelLinkItems, String batchLink);
Overview of RemoveAccessLevelBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveAccessLevelGroupBatchForPersonAsync(PersonInfo person, ObjectLinkItem accessLevelGroupLinkItems);
Overview of RemoveAccessLevelGroupBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveAccessLevelGroupBatchForPersonAsync(String personHref, ObjectLinkItem accessLevelGroupLinkItems, String batchLink);
Overview of RemoveAccessLevelGroupBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveAsc1400PortAsync(Asc1400Info controllerInfo, Int32 port);
Overview of RemoveAsc1400PortAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveConnectedObjectAsync(String targetHref, String connectedObjectKey, String relation);
Overview of RemoveConnectedObjectAsync goes here.
Example in C#
// Returns: nothing
await client.RemoveTag2Async(String itemHref, String tag);
Overview of RemoveTag2Async goes here.
Example in C#
// Returns: nothing
await client.ResetAcreIntrusionPanelEncKeyAsync(AcreIntrusionPanelInfo acreIntrusionPanel);
Overview of ResetAcreIntrusionPanelEncKeyAsync goes here.
Example in C#
// Returns: nothing
await client.SendGroupToWavelynx(FolderInfo folder, WalletGroupInfo item);
Overview of SendGroupToWavelynx goes here.
Example in C#
// Returns: Boolean
var item = await client.SendMobileInviteAsync(PersonInfo person, String messageTemplateKey);
Overview of SendMobileInviteAsync goes here.
Example in C#
// Returns: Boolean
var item = await client.SendMobileInviteAsync(String personHref, String messageTemplateKey, String inviteHref);
Overview of SendMobileInviteAsync goes here.
Example in C#
// Returns: nothing
client.ClientAppId = clientAppId;
The ClientAppId property setter allows you to configure the unique identifier for your client application. This ID is included in API request headers and helps the Keep API track and identify requests from your application.
public string ClientAppId { get; set; }
Setting the ClientAppId establishes the application identity that will be associated with all subsequent API requests. This is important for:
using Feenics.Keep.WebApi.Wrapper;
// Create the client
var client = new Client("https://keep.feenics.com");
// Set the Client App ID before authentication
client.ClientAppId = "MyAccessControlApp-v2.0";
// Authenticate
await client.OpenAsync("username", "password", "MyAccessControlApp-v2.0");
// The ClientAppId can also be updated after authentication if needed
client.ClientAppId = "MyAccessControlApp-v2.1-hotfix";
// Include application name and version
client.ClientAppId = "VisitorManagement-v1.5";
// Include environment for development/testing
client.ClientAppId = "CardholderSync-v3.0-dev";
// Include organization for multi-tenant scenarios
client.ClientAppId = "AcmeCorp-BadgePrinter-v1.0";
| Parameter | Type | Description |
|---|---|---|
| value | string |
The application identifier to associate with API requests |
OpenAsync()// Pattern 1: Simple application name
client.ClientAppId = "MobileCredentialApp";
// Pattern 2: Name with version
client.ClientAppId = "AccessExpert-iOS-v4.2.1";
// Pattern 3: Organization and application
client.ClientAppId = "Feenics-IntegrationService-v2.0";
// Pattern 4: Environment-aware
string env = Environment.GetEnvironmentVariable("APP_ENV") ?? "prod";
client.ClientAppId = $"CardholderSync-v1.0-{env}";
Example in C#
// Returns: nothing
client.DeviceId = deviceId;
The DeviceId property setter allows you to configure the unique identifier for the device making API requests. This ID helps distinguish between different devices or installations of your application.
public string DeviceId { get; set; }
Setting the DeviceId establishes the device identity that will be associated with all subsequent API requests. This is particularly important for:
using Feenics.Keep.WebApi.Wrapper;
// Create the client
var client = new Client("https://keep.feenics.com");
// Generate or retrieve a unique device identifier
string deviceId = Guid.NewGuid().ToString();
// Set the Device ID before authentication
client.DeviceId = deviceId;
// Authenticate
await client.OpenAsync("username", "password", "my-app");
using Feenics.Keep.WebApi.Wrapper;
public class DeviceManager
{
private const string DeviceIdKey = "keep_device_id";
public async Task<Client> CreateAuthenticatedClientAsync(string baseUrl, string username, string password)
{
var client = new Client(baseUrl);
// Retrieve or create a persistent device ID
string deviceId = await GetOrCreateDeviceIdAsync();
client.DeviceId = deviceId;
await client.OpenAsync(username, password, "my-app");
return client;
}
private async Task<string> GetOrCreateDeviceIdAsync()
{
// Try to retrieve existing device ID
string deviceId = Preferences.Get(DeviceIdKey, null);
if (string.IsNullOrEmpty(deviceId))
{
// Generate new device ID and store it
deviceId = Guid.NewGuid().ToString();
Preferences.Set(DeviceIdKey, deviceId);
}
return deviceId;
}
}
| Parameter | Type | Description |
|---|---|---|
| value | string |
The unique identifier for the device making API requests |
// Format 1: GUID (recommended)
client.DeviceId = Guid.NewGuid().ToString();
// Example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
// Format 2: Custom format with device info
client.DeviceId = $"iOS-{deviceModel}-{Guid.NewGuid():N}";
// Example: "iOS-iPhone14-a1b2c3d4e5f67890abcdef1234567890"
// Format 3: Hash-based (for privacy)
client.DeviceId = ComputeSha256Hash(uniqueDeviceInfo);
OpenAsync()// iOS/macOS - Use Keychain for secure storage
client.DeviceId = await SecureStorage.GetAsync("device_id")
?? await GenerateAndStoreDeviceIdAsync();
// Android - Use EncryptedSharedPreferences
client.DeviceId = encryptedPrefs.GetString("device_id", null)
?? GenerateAndStoreDeviceId();
// Desktop - Use local app data
client.DeviceId = File.Exists(deviceIdPath)
? File.ReadAllText(deviceIdPath)
: GenerateAndStoreDeviceId(deviceIdPath);
Example in C#
// Returns: nothing
client.TokenResponse = tokenResponse;
The TokenResponse property setter allows you to manually configure authentication token information on the wrapper client. This is useful for scenarios where you need to restore a session or use tokens obtained through alternative authentication flows.
public TokenResponse TokenResponse { get; set; }
Setting the TokenResponse allows you to:
using Feenics.Keep.WebApi.Wrapper;
// Scenario: Restore a previously saved session
var client = new Client("https://keep.feenics.com");
// Load saved token response from secure storage
TokenResponse savedToken = await LoadTokenFromSecureStorageAsync();
// Set the token response to restore the session
client.TokenResponse = savedToken;
// Now you can make authenticated API calls without re-authenticating
var instances = await client.GetInstancesAsync();
using Feenics.Keep.WebApi.Wrapper;
using System.Text.Json;
public class SessionManager
{
private const string TokenKey = "keep_auth_token";
// Save session for later restoration
public async Task SaveSessionAsync(Client client)
{
if (client.TokenResponse != null)
{
string tokenJson = JsonSerializer.Serialize(client.TokenResponse);
await SecureStorage.SetAsync(TokenKey, tokenJson);
}
}
// Restore a saved session
public async Task<Client> RestoreSessionAsync(string baseUrl)
{
var client = new Client(baseUrl);
string tokenJson = await SecureStorage.GetAsync(TokenKey);
if (!string.IsNullOrEmpty(tokenJson))
{
var savedToken = JsonSerializer.Deserialize<TokenResponse>(tokenJson);
// Check if token is still valid
if (savedToken.ExpiresAt > DateTime.UtcNow)
{
client.TokenResponse = savedToken;
return client;
}
}
// Token expired or not found - need to re-authenticate
return null;
}
}
| Property | Type | Description |
|---|---|---|
AccessToken |
string |
The JWT access token for API authentication |
RefreshToken |
string |
Token used to obtain new access tokens |
ExpiresIn |
int |
Token lifetime in seconds |
ExpiresAt |
DateTime |
Absolute expiration time of the token |
TokenType |
string |
Type of token (typically “Bearer”) |
using Feenics.Keep.WebApi.Wrapper;
public class TokenRefreshHandler
{
private readonly Client _client;
public TokenRefreshHandler(Client client)
{
_client = client;
}
public async Task EnsureValidTokenAsync()
{
var token = _client.TokenResponse;
// Check if token needs refresh (e.g., within 5 minutes of expiry)
if (token != null && token.ExpiresAt <= DateTime.UtcNow.AddMinutes(5))
{
// Refresh the token
var newToken = await _client.RefreshTokenAsync();
// The wrapper automatically updates TokenResponse after refresh
Console.WriteLine($"Token refreshed. New expiry: {_client.TokenResponse.ExpiresAt}");
}
}
}
⚠️ Security: Always store TokenResponse securely (encrypted storage, keychain, etc.)
⚠️ Expiration: Check token expiration before using a restored session
💡 Tip: The wrapper automatically manages tokens during normal authentication. Only use this setter for advanced scenarios.
ExpiresAt before restoring a sessionExample in C#
// Returns: nothing
await client.SetAccessLevelBatchForPersonAsync(PersonInfo person, ObjectLinkItem accessLevelLinkItems);
Overview of SetAccessLevelBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.SetAccessLevelBatchForPersonAsync(String personHref, ObjectLinkItem accessLevelLinkItems, String batchLink);
Overview of SetAccessLevelBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.SetAccessLevelBatchForPersonByHrefsAsync(PersonInfo person, String accessLevelHrefs);
Overview of SetAccessLevelBatchForPersonByHrefsAsync goes here.
Example in C#
// Returns: nothing
await client.SetAccessLevelGroupBatchForPersonAsync(PersonInfo person, ObjectLinkItem accessLevelGroupLinkItems);
Overview of SetAccessLevelGroupBatchForPersonAsync goes here.
Example in C#
// Returns: nothing
await client.SetAccessLevelGroupBatchForPersonAsync(String personHref, ObjectLinkItem accessLevelGroupLinkItems, String batchLink);
Overview of SetAccessLevelGroupBatchForPersonAsync goes here.
Example in C#
// Returns: Asc1400Info
var asc1400Info = await client.SetAsc1400PortAsync(Asc1400Info controller, SmartControllerPortItem portItem);
Overview of SetAsc1400PortAsync goes here.
Example in C#
// Returns: Asc1400Info
var asc1400Info = await client.SetAsc1400PortAsync(Asc1400Info controller, SmartControllerPortItem portItems);
Overview of SetAsc1400PortAsync goes here.
Example in C#
// Returns: IEnumerable<MarketplaceImageInfo>
var marketplaceImageInfo = await client.SetIconsAsync(FolderInfo folder, MarketplaceImageInfo icons);
Overview of SetIconsAsync goes here.
Example in C#
// Returns: nothing
await client.SetInstanceTimeZoneAsync(InstanceInfo instance, String newTimeZone);
Overview of SetInstanceTimeZoneAsync goes here.
Example in C#
// Returns: nothing
await client.SetIsDisabledAsync(CardAssignmentInfo cardAssignment, Boolean isDisabled);
Overview of SetIsDisabledAsync goes here.
Example in C#
// Returns: nothing
await client.SetNextCronJobRunAsync(CronJobInfo cronJob);
Overview of SetNextCronJobRunAsync goes here.
Example in C#
// Returns: nothing
await client.StartBatch(InstanceInfo instance);
Overview of StartBatch goes here.
Example in C#
// Returns: String
var item = client.ToString();
The ToString method returns a string representation of the current Client instance. This is a standard .NET method inherited from System.Object that is applicable to all Wrapper (Client) methods. The BaseInfo model object also has a similar method.
public override string ToString()
The ToString method provides a human-readable string representation of the object. This is useful for:
using Feenics.Keep.WebApi.Wrapper;
// Create and configure a client
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Get string representation
string clientInfo = client.ToString();
Console.WriteLine(clientInfo);
// Use in string interpolation
Console.WriteLine($"Current client: {client}");
// Use in logging
logger.LogInformation("API Client initialized: {Client}", client);
| Type | Description |
|---|---|
string |
A string representation of the current object |
The BaseInfo model objects also implement ToString for easy inspection:
using Feenics.Keep.WebApi.Wrapper;
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Get a cardholder
var cardholder = await client.SearchOneAsync<CardholderInfo>(
instanceId,
"$filter=FirstName eq 'John'"
);
// Display cardholder information
Console.WriteLine($"Found: {cardholder}");
// Get an access level
var accessLevel = await client.SearchOneAsync<AccessLevelInfo>(
instanceId,
"$filter=CommonName eq 'Employee Access'"
);
Console.WriteLine($"Access Level: {accessLevel}");
using Feenics.Keep.WebApi.Wrapper;
using Microsoft.Extensions.Logging;
public class AccessControlService
{
private readonly Client _client;
private readonly ILogger<AccessControlService> _logger;
public AccessControlService(Client client, ILogger<AccessControlService> logger)
{
_client = client;
_logger = logger;
}
public async Task ProcessCardholderAsync(string cardholderId)
{
_logger.LogDebug("Using client: {Client}", _client);
var cardholder = await _client.GetByKeyAsync<CardholderInfo>(cardholderId);
_logger.LogInformation("Processing cardholder: {Cardholder}", cardholder);
// Process cardholder...
}
}
using Feenics.Keep.WebApi.Wrapper;
public async Task DiagnoseAsync(Client client)
{
Console.WriteLine("=== Client Diagnostics ===");
Console.WriteLine($"Client: {client}");
Console.WriteLine($"Type: {client.GetType().FullName}");
Console.WriteLine($"Hash Code: {client.GetHashCode()}");
// List some objects
var instances = await client.GetInstancesAsync();
Console.WriteLine("\n=== Instances ===");
foreach (var instance in instances.Take(5))
{
Console.WriteLine($" {instance}");
}
}
using Feenics.Keep.WebApi.Wrapper;
var client = new Client("https://keep.feenics.com");
await client.OpenAsync("username", "password", "my-app");
// Search for cardholders
var cardholders = await client.SearchAsync<CardholderInfo>(
instanceId,
"$filter=Status eq 'Active'&$top=10"
);
// Display all using ToString
Console.WriteLine("Active Cardholders:");
foreach (var ch in cardholders)
{
Console.WriteLine($" - {ch}");
}
💡 Never Null: ToString should never return null (returns empty string if no meaningful representation)
💡 Override: The Client class overrides ToString to provide meaningful output
💡 Implicit Call: ToString is called automatically in string interpolation and concatenation
Example in C#
// Returns: nothing
await client.UpdateAcreIntrusionPanelEncIVAsync(AcreIntrusionPanelInfo acreIntrusionPanel, Byte EncIv);
Overview of UpdateAcreIntrusionPanelEncIVAsync goes here.
Example in C#
// Returns: nothing
await client.UpdateAcreIntrusionPanelEncKeyAsync(AcreIntrusionPanelInfo acreIntrusionPanel, Byte EncKeyBin);
Overview of UpdateAcreIntrusionPanelEncKeyAsync goes here.
Example in C#
// Returns: BulkItemResult
var bulkItemResult = await client.UpdateDeviceStatusPropertiesAsync(FolderInfo folder, String deviceKey, Boolean propStatusValues, Int64 logId, Boolean suppressUpdateEvent);
Overview of UpdateDeviceStatusPropertiesAsync goes here.
Example in C#
// Returns: BulkItemResult
var bulkItemResult = await client.UpdateDeviceStatusPropertyAsync(FolderInfo folder, String deviceKey, String prop, Boolean statusValue, Int64 logId, Boolean suppressUpdateEvent);
Overview of UpdateDeviceStatusPropertyAsync goes here.
Example in C#
// Returns: nothing
await client.UpdatedLedConfigurationsAsync(ControllerInfo controller, LedConfigurationInfo ledConfiguration);
Overview of UpdatedLedConfigurationsAsync goes here.
Example in C#
// Returns: nothing
await client.UpdateMarketplacePackageTags(MarketplacePackageInfo item, String tags);
Overview of UpdateMarketplacePackageTags goes here.
Example in C#
// Returns: nothing
await client.UpdateMarketplacePackageVersionTags(MarketplacePackageVersionInfo item, String tags);
Overview of UpdateMarketplacePackageVersionTags goes here.
Example in C#
// Returns: Boolean
var item = await client.UpdateTrakaIfobPositionsAsync(TrakaIfobInfo ifob, Int32 currPosition);
Overview of UpdateTrakaIfobPositionsAsync goes here.
Example in C#
// Returns: nothing
await client.UpdateTrakaItemAsync(TrakaItemInfo item);
Overview of UpdateTrakaItemAsync goes here.
Example in C#
// Returns: String
var item = await client.WaitInScriptQueue(FolderInfo folder, String lockName, Boolean exitIfQueued, Int32 retryIntervalInMilliseconds, Int32 maxDelayInMilliseconds, Int32 persistenceInMilliseconds);
Overview of WaitInScriptQueue goes here.