Core Concepts

Welcome to the acre Access Control API Concepts Guide. This section provides the foundational knowledge you need to build powerful integrations with the acre Access Control platform.

Before You Begin: If you’re new to acre Access Control, we recommend starting with the Quick Start Guide to get your first integration running, then returning here to deepen your understanding.


What You’ll Learn

This concepts section covers the essential building blocks of the acre Access Control API:

Concept Description Start Here If…
Instances Multi-tenant architecture and data isolation You need to understand organizational structure
Permissions Role-based access control for API operations You’re setting up user access or troubleshooting authorization
REST Structure HTTP API patterns and navigation You’re building non-.NET integrations (Python, JavaScript, etc.)
Data Streams Efficient streaming for large datasets You’re working with ETL, bulk exports, or memory-constrained environments
Bulk Operations High-performance batch updates You need to update thousands of cards efficiently
Event Types Hardware event data structures You’re processing or analyzing access events
Exception Messages Error handling and troubleshooting You’re debugging API errors
Definitions & Acronyms Industry terminology reference You encounter unfamiliar terms

Key Architectural Principles

1. Instance-Based Data Isolation

All objects in acre Access Control are scoped to an instance. This is the most important concept to understand:

VAR Instance (Top-Level Reseller)
├── VAR Instance (Regional Partner)
│   ├── Enterprise Instance (Large Customer)
│   │   ├── Shared Instance (Region 1)
│   │   │   ├── Controllers, Readers, People...
│   │   │   └── Events, Access Levels...
│   │   └── Shared Instance (Region 2)
│   │       └── ...
│   └── Standard Instance (Small Customer)
│       └── Controllers, Readers, People...
└── Standard Instance (Direct Customer)
    └── Controllers, Readers, People...

Critical Rule: Objects that need to work together (e.g., a Reader and a Schedule in an Access Level) must be in the same instance.

Example: You cannot create an Access Level that connects a reader in Instance A with a schedule in Instance B.


2. Strongly-Typed Object Model

The acre API uses a strongly-typed object model. Every object carries type information via the $type property:

{
  "$type": "Feenics.Keep.WebApi.Model.PersonInfo, Feenics.Keep.WebApi.Model",
  "CommonName": "John Smith",
  "GivenName": "John",
  "Surname": "Smith",
  "Key": "5bcde6d2a3ac1600485092ed"
}

Why This Matters:

  • Non-.NET developers (Python, JavaScript, PHP) must include the $type property when creating or updating objects
  • The type information enables polymorphism (e.g., different address types: EmailAddressInfo, MailingAddressInfo, PhoneInfo)
  • Type names follow the pattern: Feenics.Keep.WebApi.Model.{TypeName}, Feenics.Keep.WebApi.Model

3. HATEOAS Navigation

The API follows HATEOAS (Hypermedia as the Engine of Application State) principles. Objects include navigation links:

{
  "Href": "/api/f/5bcde6c5a3ac1600485092a0",
  "Links": [
    {
      "Relation": "People",
      "Anchor": { "Href": "people", "Text": "People" }
    },
    {
      "Relation": "Controllers",
      "Anchor": { "Href": "controllers", "Text": "Controllers" }
    }
  ]
}

Navigation Pattern:

  1. Start at /api to get your current instance
  2. Use Links to discover available resources
  3. Combine Href + Anchor.Href to construct resource URLs

Variable Types Reference

The API utilizes C# types. When working with the API, these are the common patterns you’ll encounter:

Variable Used In Type Description
TimeZone ControllerInfo String POSIX.1 TZ format (e.g., "America/New_York")
MacAddress ControllerInfo String Format: XX:XX:XX:XX:XX:XX (uppercase hex)
DayMask ScheduleDurationItem Int32 Bitmask for days of week (see below)
Duration ScheduleDurationItem TimeSpan Format: "08:00:00" (8 hours)
EndsOn AccessLevelInfo DateTime? ISO 8601 format, nullable
Width BadgeTypeInfo Double Pixel value (e.g., 1012 for standard CR80 card at 300 DPI)

DayMask Bitmask Values

The DayMask uses bit manipulation to represent days of the week:

Day Binary Decimal Example
Saturday 1000000 64 Weekend only: 64 + 1 = 65
Friday 0100000 32
Thursday 0010000 16
Wednesday 0001000 8
Tuesday 0000100 4 Tuesday only: 4
Monday 0000010 2
Sunday 0000001 1

Common Patterns:

  • Monday–Friday: 62 (0111110)
  • Weekends: 65 (1000001)
  • Every Day: 127 (1111111)
// C# Example: Create a Monday-Friday schedule duration
var scheduleDuration = new ScheduleDurationItem
{
    DayMask = 62,  // Monday-Friday
    StartsOn = TimeSpan.Parse("08:00:00"),
    Duration = TimeSpan.Parse("10:00:00")  // 8 AM to 6 PM
};

Quick Reference: Object Hierarchy

Understanding the object hierarchy is essential for effective API usage:

BaseInfo (base class for all objects)
├── FolderInfo (organizational container)
│   └── InstanceInfo (top-level container - inherits from FolderInfo)
├── PersonInfo (cardholders)
│   └── CardAssignmentInfo (credentials)
├── ControllerInfo (hardware controllers)
│   └── MercuryControllerInfo (EP1501, LP1502, etc.)
├── PeripheralInfo (devices connected to controllers)
│   └── MercuryPeripheralInfo
│       ├── MercuryReaderInfo (readers on Mercury controllers)
│       ├── MercuryInputInfo (inputs)
│       └── MercuryOutputInfo (outputs)
├── EngageDeviceInfo (Allegion Engage wireless lock hardware)
│   ├── EngageReaderInfo (wireless locks)
│   └── EngageIpGatewayInfo (IP gateways)
├── EngageSiteInfo (Engage site configuration)
├── BoschPanelInfo (Bosch intrusion panels)
├── AccessLevelInfo (access rules)
├── ScheduleInfo (time-based rules)
└── EventMessageData (system events)

Best Practices

✅ DO

  1. Cache the instance hierarchy - Minimize calls to /api by caching your instance structure
  2. Use streaming for large datasets - Use SearchStream and AggregateStream for queries returning >1,000 objects
  3. Include $type in all POST/PUT requests - Required for non-.NET clients
  4. Handle token refresh - Access tokens expire; use the refresh token before expiration
  5. Scope operations to the correct instance - Always verify you’re operating on the intended instance

❌ DON’T

  1. Don’t create cross-instance relationships - Objects must be in the same instance to work together
  2. Don’t ignore pagination - Large result sets will be paginated; always check for more pages
  3. Don’t hardcode object keys - Keys are generated; use queries to find objects dynamically. EventType keys can be cached for long periods.
  4. Don’t poll for Events - Use MQTT subscriptions for real-time events instead
  5. Don’t store credentials in code - Use environment variables or secure vaults

Next Steps

Ready to dive deeper? Choose your path:

I want to… Go to…
Understand multi-tenant architecture Instances
Set up user permissions Permissions
Build a REST integration (non-.NET) REST Structure
Process large datasets efficiently Data Streams
Handle real-time events Subscribing to Events
Query historical data MongoDB Aggregates