📋 Prerequisites

These examples assume familiarity with core concepts. If you're new to the 7G API, start with these foundational guides:

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

json
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 automatically

How It Works

  1. Login: LoginAsync() returns TokenResponse directly (not wrapped in APIResponse)
  2. Auto-Storage: SDK stores tokens internally and injects them into all subsequent requests
  3. Expiry Extraction: SDK extracts exp claim from JWT to track expiration
  4. Auto-Refresh: SDK checks if token expires within 30 seconds and auto-refreshes before each request
  5. Header Injection: Authorization header set to just the token value (no "Bearer" prefix)

Expected Response

json
{
  "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() and SetRefreshToken() 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/GetLookup endpoint

For comprehensive architectural details, see BizEntity Overview.

Complete Examples

json
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

  1. BizEntity Creation: POST to /BizEntity with complete nested structure
  2. ExternalPersonId Deduplication: If ExternalPersonId exists, SDK reuses that Person record instead of creating duplicate
  3. Atomic Transaction: All nested objects created together; failure rolls back entire operation
  4. Server-Side Validation: FluentValidation returns detailed field-level errors if data invalid
  5. Response: Returns complete BizEntity with generated IDs for all nested resources

Expected Response

json
{
  "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=BizEntityType to 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

json
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

  1. Filter Construction: Create filter object and set FilterField properties using dot notation
  2. Implicit Conversion: SDK allows FilterField<int> = 5 which becomes .Equal(5)
  3. Query String Generation: SDK converts filters to ?FieldName.OperatorName=value format
  4. URI Encoding: SDK automatically URI-encodes special characters and date formats
  5. Pagination: PageNumber (1-indexed) and PageSize control result batching

Expected Response

json
{
  "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 .Contains on integers throws errors; use .In instead
  • 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 = 1 becomes .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.