SDK Code Examples
Complete C# workflow examples demonstrating common integration patterns with the 7G Registry Platform API.
📋 Prerequisites
These examples assume familiarity with core concepts. If you're new to the 7G API, start with these foundational guides:
- Authentication Guide - JWT tokens, refresh patterns, session management
- API Fundamentals - Response structure, error handling, versioning
- Query & Filtering - FilterField<T> operators and performance tips
- BizEntity Architecture - BizEntity-centric design philosophy
This page documents 3 foundational patterns. Additional patterns (distributions, transactions, reports, file operations) are being documented. See Documentation Roadmap below.
Pattern 1: Authentication & Token Management
When to Use This Pattern
Use this pattern at the start of every SDK integration to establish secure API access. The SDK automatically handles token refresh, but understanding the authentication lifecycle is essential for session persistence.
Complete Examples
using SevenG.API.SDK;
// Initialize SDK with environment
using var client = new SevenGClient(SevenGEnvironment.Test);
// Login returns TokenResponse directly (not wrapped in APIResponse)
var tokens = await client.Auth.LoginAsync("username", "password");
Console.WriteLine($"✓ Logged in: {tokens.AccessToken.Substring(0, 20)}...");
Console.WriteLine("Tokens automatically stored and injected into all requests");
// SDK now ready for API calls - token refresh handled automaticallyHow It Works
- Login:
LoginAsync()returnsTokenResponsedirectly (not wrapped in APIResponse) - Auto-Storage: SDK stores tokens internally and injects them into all subsequent requests
- Expiry Extraction: SDK extracts
expclaim from JWT to track expiration - Auto-Refresh: SDK checks if token expires within 30 seconds and auto-refreshes before each request
- Header Injection: Authorization header set to just the token value (no "Bearer" prefix)
Expected Response
{
"accessToken": "eyJxxCJ9.eyJxxxpYyJ9.8Csxx3S-jMxxnv-4Nxxfw",
"refreshToken": "cZkxxx4Y="
}Common Issues & Solutions
- 401 Unauthorized: Verify username/password are correct for your environment. Credentials differ between Production/Preview/Test.
- InvalidOperationException on Refresh: Refresh token expired or missing. User must re-authenticate with
LoginAsync(). - Session Persistence Issues: Use
SetAccessToken()andSetRefreshToken()to restore persisted sessions.
Related Documentation
See Authentication Guide for complete token lifecycle details and security best practices.
Pattern 2: Creating a Business Entity
When to Use This Pattern
Use this pattern when onboarding new investors, account holders, or financial entities. BizEntity is the primary aggregation point in the 7G architecture—representing the investor, account, and ledger.
Key Concepts
- Nested Resources: Persons, Addresses, Communications, PaymentDetails are nested within BizEntity
- ExternalPersonId Deduplication: Same person across multiple BizEntities (e.g., trustee for multiple trusts) uses consistent ExternalPersonId to prevent duplicates
- Lookup Data: BizEntityTypeID, AddressTypeID from
/Common/GetLookupendpoint
For comprehensive architectural details, see BizEntity Overview.
Complete Examples
using SevenG.API.SDK;
// Authenticate first
using var client = new SevenGClient(SevenGEnvironment.Test);
await client.Auth.LoginAsync("username", "password");
// Create complete BizEntity with nested resources
var newEntity = new BizEntityDTO
{
// BizEntity core properties
Name = "Smith Family Trust",
ExternalBizEntityId = "EXT-TRUST-001", // Your system's ID
BizEntityTypeID = 2, // Query /Common/Lookup?Name=bizEntityTypeID for valid types
BizEntityStatusID = 1, // Query /Common/Lookup?Name=bizEntityStatusID for valid statuses
// Nested BizEntityParties (persons associated with this entity)
BizEntityParties = new List<BizEntityPartyDTO>
{
new()
{
// IMPORTANT: ExternalPersonId enables deduplication
ExternalPersonId = "PERSON-JOHN-SMITH",
IsPrimaryContact = true,
IsSignatory = true,
Ordinal = 1,
// Person details
Person = new PersonDTO
{
FirstName = "John",
LastName = "Smith",
DateOfBirth = new DateOnly(1980, 5, 15),
TaxationCountryCode = "AU",
TaxationFileNumber = "123456789"
}
}
},
// Nested addresses
Addresses = new List<AddressDTO>
{
new()
{
AddressTypeID = 1, // Query /Common/Lookup?Name=addressTypeID for valid types
AddressLine = "123 Main Street",
Suburb = "Sydney",
StateCode = "NSW",
Postcode = "2000",
CountryCode = "AU",
ExternalAddressId = "ADDR-001"
}
},
// Nested communications (email, phone)
Communications = new List<CommunicationDTO>
{
new()
{
CommunicationTypeID = 1, // Query /Common/Lookup?Name=communicationTypeID for valid types
Name = "john.smith@example.com",
ExternalCommunicationId = "COMM-EMAIL-001"
}
},
// Nested payment details
PaymentDetails = new List<PaymentDetailDTO>
{
new()
{
PaymentTypeID = 1, // Query /Common/Lookup?Name=paymentTypeID for valid types
BSB = "123-456",
AccountNumber = "98765432",
AccountName = "Smith Family Trust",
IsForDistribution = true,
IsForRedemption = true,
IsDefault = true,
ExternalPaymentDetailId = "PAY-001"
}
}
};
// Create BizEntity (atomic transaction - all nested resources created together)
var result = await client.BizEntity.CreateAsync(newEntity);
if (result.Result)
{
Console.WriteLine("✓ BizEntity created successfully");
Console.WriteLine($"Message: {result.Message}");
}
else
{
Console.WriteLine($"✗ Creation failed: {result.Message}");
}How It Works
- BizEntity Creation: POST to
/BizEntitywith complete nested structure - ExternalPersonId Deduplication: If ExternalPersonId exists, SDK reuses that Person record instead of creating duplicate
- Atomic Transaction: All nested objects created together; failure rolls back entire operation
- Server-Side Validation: FluentValidation returns detailed field-level errors if data invalid
- Response: Returns complete BizEntity with generated IDs for all nested resources
Expected Response
{
"result": true,
"message": "BizEntity created successfully",
"recordCount": 1,
"data": {
"bizEntityID": 12345,
"externalBizEntityId": "EXT-TRUST-001",
"name": "Smith Family Trust",
"bizEntityTypeID": 2,
"bizEntityStatusID": 1,
"bizEntityParties": [
{
"bizEntityPartyID": 67890,
"personID": 54321,
"externalPersonId": "PERSON-JOHN-SMITH",
"isPrimaryContact": true,
"person": {
"personID": 54321,
"firstName": "John",
"lastName": "Smith"
}
}
]
}
}Common Issues & Solutions
- Validation Error: "Name is required": BizEntity must have a Name property (trust name, company name, or individual's full name)
- Duplicate ExternalBizEntityId: Each BizEntity must have unique ExternalBizEntityId. Use your system's primary key or UUID.
- Person Duplication: Use consistent ExternalPersonId for same person across multiple BizEntities to prevent duplicates
- BizEntityTypeID Not Found: Query
/Common/GetLookup?Category=BizEntityTypeto get valid type IDs
Related Documentation
See BizEntity POST for complete parameter reference and validation rules.
Pattern 3: Advanced Filtering & Pagination
When to Use This Pattern
Use this pattern when querying large datasets, building search interfaces, or generating reports. The SDK's
FilterField<T> provides 11 operators for flexible queries without manual query string construction.
FilterField Operators
The SDK supports 11 filtering operators: Equal, NotEqual, In, NotIn,
GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual,
Contains, StartsWith, EndsWith.
For complete operator documentation, performance comparisons, and validation rules, see Query & Filtering.
Complete Examples
using SevenG.API.SDK;
await client.Auth.LoginAsync("username", "password");
// String filtering with Contains, StartsWith, EndsWith
var filter = new BizEntityFilter
{
// Find all entities with "Trust" in the name
Name = new FilterField<string> { Contains = "Trust" },
// Pagination
PageNumber = 1,
PageSize = 50
};
var response = await client.BizEntity.GetAsync(filter);
if (response.Result)
{
Console.WriteLine($"Found {response.RecordCount} matching entities");
}How It Works
- Filter Construction: Create filter object and set FilterField properties using dot notation
- Implicit Conversion: SDK allows
FilterField<int> = 5which becomes.Equal(5) - Query String Generation: SDK converts filters to
?FieldName.OperatorName=valueformat - URI Encoding: SDK automatically URI-encodes special characters and date formats
- Pagination: PageNumber (1-indexed) and PageSize control result batching
Expected Response
{
"result": true,
"message": null,
"recordCount": 3,
"data": [
{
"bizEntityID": 100,
"name": "Smith Family Trust",
"bizEntityTypeID": 2,
"createdDate": "2024-02-15T10:30:00Z"
},
{
"bizEntityID": 101,
"name": "Jones Investment Trust",
"bizEntityTypeID": 2,
"createdDate": "2024-02-20T14:15:00Z"
},
{
"bizEntityID": 102,
"name": "ABC Pty Ltd Trust",
"bizEntityTypeID": 2,
"createdDate": "2024-03-01T09:00:00Z"
}
]
}Common Issues & Solutions
- Empty Results: Check filter operators match data types. Using
.Containson integers throws errors; use.Ininstead - Date Range Issues: Ensure DateTime values include correct timezone. SDK converts to UTC for queries
- PageSize Too Large: Maximum PageSize is typically 1000. Use 50-100 for UI, 500-1000 for batch operations
- Implicit Conversion:
filter.BizEntityTypeID = 1becomes.Equal(1);new[] { 1, 2 }becomes.In([1,2])
Related Documentation
See Query & Filtering for performance optimization tips and advanced patterns. For pagination strategies, see Pagination & Limits.
Additional Patterns Being Documented
The following SDK features are available now. Documentation examples are being completed. Refer to the API Reference for detailed endpoint specifications.
📝 Transaction Processing
Documentation in progress
Complete workflows for deposits, allotments, redemptions, conversions, and transfers. Includes validation, settlement polling, and account balance verification.
📝 Distribution Lifecycle
Documentation in progress
4-step distribution workflow (Declare → Distribute → Allotment → Complete). Account selection strategies, DRP handling, and tax component configuration.
📝 Async Report Generation
Documentation in progress
3-stage async workflow (Create → Poll Status → Get Result). Report parameter configuration, status monitoring, and stream handling.
📝 File Operations
Documentation in progress
Document upload/download patterns, statement generation, and stream disposal. Handling IFormFile, Stream, and large file processing.
📝 Error Handling & Resilience
Documentation in progress
Retry patterns, exponential backoff, circuit breakers, and logging strategies. Handling 401 refresh failures, 400 validation errors, and 500 server errors.
📝 Best Practices
Documentation in progress
Performance optimization, batching strategies, caching patterns, and security considerations. HttpClient lifecycle management and production deployment guidelines.
Need Help Now?
While these patterns are being documented, our API Reference provides complete endpoint specifications with request/response examples. For complex scenarios, contact support@7g.com.au for implementation guidance.