Principals
A principal represents a human identity that authenticates with Hantera. Principals are the primary way users interact with the Hantera platform.
What is a Principal?
Principals represent people who need to access Hantera - whether they’re administrators managing the portal, customer service agents, or end customers accessing their accounts.
Key characteristics:
- Email address (used as username, must be unique)
- Password or OAuth authentication
- Can be assigned multiple roles
- Can be temporarily suspended
- Dynamic properties for custom data
- Active session tracking
Example principal:
{ "id": "01933e8f-7c45-7123-9abc-123456789abc", "type": "principal", "properties": { "name": "John Admin", "phone": "+1234567890", "picture": "https://example.com/photo.jpg", "settings": { "theme": "dark", "language": "en" } }, "roles": ["system:portal:full"], "suspendedAt": null, "lastActiveAt": "2025-01-07T15:30:00Z"}When to Use Principals
✅ Use principals for:
- Portal users (administrators, staff)
- Customer accounts
- Partner or vendor users
- Any human that needs to log in
❌ Don’t use principals for:
- Application-to-application authentication (use Clients instead)
- Service accounts (use Clients instead)
- Webhook consumers (use Clients instead)
List API Features
The principals list endpoint supports comprehensive filtering, search, and cursor-based pagination for efficient data retrieval.
Cursor-Based Pagination
All list operations use cursor-based pagination for optimal performance with large datasets:
Query parameters:
limit- Items per page (default: 50, max: 100)after- Cursor for next pagebefore- Cursor for previous page
Response format:
{ "principals": [...], "totalCount": 245, "lastCursor": "01933e8f-7c45-7123-9abc-123456789abc", "firstCursor": "01933e8f-7c45-7123-9abc-123456789def"}Example - First page:
GET /resources/iam/principals?limit=50Example - Next page:
GET /resources/iam/principals?limit=50&after=01933e8f-7c45-7123-9abc-123456789abcExample - Previous page:
GET /resources/iam/principals?limit=50&before=01933e8f-7c45-7123-9abc-123456789defSearch
Search by name or email (case-insensitive, partial matches):
GET /resources/iam/principals?search=johnThis will match principals with “john” in their name or email address.
Filtering
Filter by roles:
# Filter by multiple roles (matches principals with ANY of these roles)GET /resources/iam/principals?roles=system:owner&roles=system:portal:full
# Filter by single role (convenience parameter)GET /resources/iam/principals?role=support:agent
# Filter by role prefix (all roles starting with prefix)GET /resources/iam/principals?rolePrefix=system:portal:Include suspended principals:
# By default, suspended principals are excludedGET /resources/iam/principals?includeSuspended=trueSorting
Sort results using the orderBy parameter:
# Sort by name ascending (default)GET /resources/iam/principals?orderBy=name asc
# Sort by email descendingGET /resources/iam/principals?orderBy=email desc
# Sort by last active dateGET /resources/iam/principals?orderBy=lastActiveAt descAvailable sort fields:
name- Principal’s nameemail- Email addresslastActiveAt- Last authentication timestampsuspendedAt- Suspension date
Combined Queries
You can combine search, filters, sorting, and pagination:
GET /resources/iam/principals?search=admin&roles=system:portal:full&orderBy=name asc&limit=20This query:
- Searches for “admin” in name/email
- Filters by
system:portal:fullrole - Sorts by name ascending
- Returns 20 results per page
Principal Management
Create or Update Principal
Full replacement of a principal (use for initial creation or complete updates):
PUT /resources/iam/principals/{id}If-Match: "etag-value"{ "properties": { "name": "John Admin", "phone": "+1234567890", "picture": "https://example.com/photo.jpg", "settings": { "theme": "dark", "language": "en" } }, "roles": ["system:portal:full"], "acl": { "entries": [ { "resource": "orders", "permission": "*" } ] }, "accessAttributes": { "channelKey": ["STORE-NYC"] }}Partial Update
Update specific properties without replacing the entire principal:
PATCH /resources/iam/principals/{id}If-Match: "etag-value"{ "name": "John Updated", "settings": { "theme": "light" }}Partial updates:
- Only update specified fields
- Merge settings (don’t replace them)
- Leave other properties unchanged
- Require ETag for safety
Update Roles
Replace the entire roles list:
PUT /resources/iam/principals/{id}/rolesIf-Match: "etag-value"{ "roles": ["system:portal:full", "support:agent"]}Update ACL
Replace the entire ACL:
PUT /resources/iam/principals/{id}/aclIf-Match: "etag-value"{ "acl": [ "orders:*", "customers:read" ]}Get Principal Details
Retrieve a principal with all properties:
GET /resources/iam/principals/{id}Response includes:
{ "id": "01933e8f-7c45-7123-9abc-123456789abc", "name": "John Admin", "phone": "+1234567890", "picture": "https://example.com/photo.jpg", "settings": { "theme": "dark", "language": "en" }, "roles": ["system:portal:full"], "acl": { "entries": [...] }, "accessAttributes": { "channelKey": ["STORE-NYC"] }, "suspendedAt": null, "lastActiveAt": "2025-01-07T15:30:00Z", "createdAt": "2024-01-01T10:00:00Z", "etag": "W/\"abc123\"", "passwordLogin": true, "passwordExpiresAt": null}Additional fields:
passwordLogin- Whether password authentication is enabledpasswordExpiresAt- When the password expires (null for permanent passwords)lastActiveAt- Last successful authentication timestampetag- Version identifier for safe updates
Delete Principal
Remove a principal permanently:
DELETE /resources/iam/principals/{id}Returns 204 No Content on success.
Self-Service Restrictions
Principals cannot suspend or delete themselves. If you attempt to suspend or delete your own account, the API returns 403 Forbidden with the error message: “Cannot suspend your own principal” or “Cannot delete your own principal”.
This prevents accidental account lockouts and ensures administrative continuity.
Password Management
Password Reset Flow
Password resets generate temporary passwords that expire on first use:
-
Administrator initiates reset
POST /resources/iam/principals/{id}/password/reset -
API returns temporary password
{"temporaryPassword": "TempPass123"} -
Administrator sends email to user
Use the Sendings API to send the temporary password:
POST /resources/sendings{"category": "password_reset","subject": "Password Reset","bodyHtml": "<p>Your temporary password is: TempPass123</p>"} -
User logs in with temporary password
- Session is created but marked as requiring password change
-
User must change password
POST /resources/me/password{"currentPassword": "TempPass123","newPassword": "NewSecurePass456!"}
Password Requirements
Passwords must meet these criteria:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one digit
- No common/weak passwords
Invalid passwords will be rejected with an appropriate error message.
Email and Phone Uniqueness
Email addresses and phone numbers must be unique across all principals.
Email Uniqueness
Attempting to create a principal with an existing email address returns an error:
{ "error": { "code": "EMAIL_NOT_UNIQUE", "message": "Email address already in use" }}Changing Email Addresses
When you change a principal’s email address:
- The new email must not be in use by another principal
- The change updates the principal’s login username automatically (if password authentication is enabled)
- The principal must log in with the new email address going forward
Example:
PATCH /resources/iam/principals/{id}If-Match: "etag-value"{}Principal Suspension
Principals can be suspended to temporarily block authentication without deleting the account.
Suspension vs Deletion
| Feature | Suspension | Deletion |
|---|---|---|
| Reversible | ✅ Yes | ❌ No |
| Data retained | ✅ Yes | ❌ No |
| Can authenticate | ❌ No | ❌ No |
| Roles retained | ✅ Yes | ❌ No |
| Visible in API | ❌ No (by default) | ❌ No |
Suspension Workflow
-
Suspend the principal
POST /resources/iam/principals/{id}/suspendIf-Match: "etag-value"- Sets suspension timestamp
- Automatically revokes all active sessions
- Principal cannot create new sessions
- Requires ETag for concurrency control
-
Principal attempts to log in
- Authentication fails with “suspended” status
- Error message: “Account has been suspended”
-
Reactivate when ready
POST /resources/iam/principals/{id}/reactivateIf-Match: "etag-value"- Clears suspension timestamp
- Principal can authenticate again
- Must log in to create new sessions
- Requires ETag for concurrency control
When to Use Suspension
✅ Appropriate uses:
- Security incidents (compromised account)
- Policy violations (temporary punishment)
- Account review periods
- Inactive account cleanup (temporary)
- Employee leave of absence
❌ Not appropriate:
- Permanent account removal (use deletion instead)
- Password changes (use password reset)
- Role changes (update roles directly)
Session Management
Principals can have multiple active sessions from different devices or applications. The session management endpoints allow viewing and revoking these sessions.
List Sessions
Get all active sessions for a principal:
GET /resources/iam/principals/{id}/sessionsResponse:
[ { "id": "01933e8f-7c45-7123-9abc-sessionid123", "type": "interactive", "createdAt": "2025-01-07T15:30:00Z", "accessTokenExpiresAt": "2025-01-07T16:30:00Z", "isCurrent": true, "isRevoked": false, "revokedAt": null, "clientId": "01933e8f-7c45-7123-9abc-clientid456", "clientName": "Portal Web App", "description": "Chrome on Windows" }]Session fields:
id- Unique session identifiertype- Session type (e.g.,interactive,api)isCurrent- Whether this is the current session making the requestisRevoked- Whether the session has been revokedclientId- OAuth client that created the sessionclientName- Human-readable client namedescription- Session description (e.g., browser and device info)
Revoke Session
Revoke a specific session:
DELETE /resources/iam/principals/{id}/sessions/{sessionId}Returns 204 No Content on success. The session is immediately invalidated and cannot be used for further requests.
Session Management Permissions
Session management permissions:
- Principals can view and revoke their own sessions without special permissions
- Viewing/revoking another principal’s sessions requires
iam/principals:readoriam/principals:writepermission
This enables self-service session management while allowing administrators to help users who may have lost access.
Access Attributes (ABAC)
Access attributes enable Attribute-Based Access Control (ABAC), allowing you to scope permissions to specific data.
Use case: A store manager should only access orders and inventory for their assigned locations.
Solution: Set channelKey attributes on the principal:
{ "accessAttributes": { "channelKey": ["STORE-NYC", "STORE-BOS"] }}When this principal accesses resources, they can only view/modify data where the resource’s channelKey matches one of their attribute values. Attempting to access other channels returns 403 Forbidden.
Example scenarios:
- Multi-location businesses (store managers)
- Multi-tenant applications (tenant isolation)
- Departmental access (only HR records)
- Regional restrictions (GDPR compliance)
Integration Patterns
Creating Portal Users
PUT /resources/iam/principals/{userId}{ "properties": { "name": "John Admin", }, "roles": ["system:portal:full"]}Then generate a temporary password and send via email using the Sendings API.
Role-Based Filtering
GET /resources/iam/principals?rolePrefix=system:portal:Returns only principals with portal access, useful for building user management UIs.
Bulk Role Assignment
Update multiple principals’ roles using the Graph API and batch operations:
POST /resources/graph/query{ "resource": "identity", "filters": [ { "field": "email", "op": "endsWith", "value": "@company.com" } ]}Then update each principal’s roles individually.
API Endpoints
Principal management endpoints:
GET /resources/iam/principals- List principalsGET /resources/iam/principals/{id}- Get principalPUT /resources/iam/principals/{id}- Create or update (full)PATCH /resources/iam/principals/{id}- Update properties (partial)DELETE /resources/iam/principals/{id}- Delete principalPOST /resources/iam/principals/{id}/suspend- Suspend principalPOST /resources/iam/principals/{id}/reactivate- Reactivate principalPOST /resources/iam/principals/{id}/password/reset- Reset passwordPUT /resources/iam/principals/{id}/roles- Update rolesPUT /resources/iam/principals/{id}/acl- Update ACLGET /resources/iam/principals/{id}/sessions- List sessionsDELETE /resources/iam/principals/{id}/sessions/{sessionId}- Revoke session
For complete endpoint documentation, request/response formats, and error codes, see the HTTP API Reference.
Related Resources
- IAM Overview - Introduction to IAM concepts
- Clients - Application and service identities
- Identity Graph Node - Query identities via Graph
- Access Control - Permission patterns and best practices
- Me Endpoint - Current principal information
- Sendings API - Send emails (for password resets)