Organization Management

The Organization Management API provides offline-first access to organization data with comprehensive filtering, sorting, and pagination capabilities.

Table of contents

  1. Fetch Organizations (Paginated)
    1. Parameters
    2. ZyncOrganizationSortAndFilter Options
    3. Return Value: GetOrganizationsResult
  2. Get Organization Detail
    1. Parameters
    2. Return Value: GetOrganizationResult
  3. Organization Data Models
    1. ZyncOrganization (List Item)
    2. ZyncOrganizationDetail (Full Detail)
  4. Best Practices
    1. Pagination
    2. Filtering & Sorting
    3. Offline-First Behavior
    4. Error Handling
  5. Common Use Cases
    1. Search Organizations by Keyword
    2. Filter by Specific UIDs
    3. Get Organization with Tax and Pricing Information

Fetch Organizations (Paginated)

Retrieves a paginated list of organizations with advanced filtering and sorting options.

import zync.api.organization.models.GetOrganizationsResult
import zync.api.organization.models.ZyncOrganizationSortAndFilter
import zync.api.organization.models.ZyncOrganizationSortBy
import zync.api.common.filter.ZyncSortType

val sortAndFilter = ZyncOrganizationSortAndFilter(
    sortType = ZyncSortType.Descending,
    sortBy = ZyncOrganizationSortBy.OrganizationName,
    keyword = "tech",
    isActive = true
)

when (val result = zync.organization.fetchOrganizations(
    sortAndFilter = sortAndFilter,
    page = 1,
    pageSize = 20
)) {
    is GetOrganizationsResult.Success -> {
        val organizations = result.data
        val currentPage = result.currentPage
        val totalPages = result.totalPages
        val totalRecords = result.totalRecords
        val isPartialData = result.isPartialData

        println("Fetched ${organizations.size} organizations (page $currentPage of $totalPages)")
        if (isPartialData) {
            println("Data from cache - may be incomplete")
        }
    }
    is GetOrganizationsResult.Failure -> {
        println("Error: ${result.error.message}")
    }
}
import ZuperSync

let sortAndFilter = ZyncOrganizationSortAndFilter(
    sortType: .descending,
    sortBy: .organizationName,
    keyword: "tech",
    isActive: true
)

switch onEnum(of: await zync.organization.fetchOrganizations(
    sortAndFilter: sortAndFilter,
    page: 1,
    pageSize: 20
)) {
case .success(let success):
    let organizations = success.data
    let currentPage = success.currentPage
    let totalPages = success.totalPages
    let isPartialData = success.isPartialData

    print("Fetched \(organizations.count) organizations (page \(currentPage) of \(totalPages))")
    if isPartialData {
        print("Data from cache - may be incomplete")
    }

case .failure(let failure):
    print("Error: \(failure.error.message)")
}

Parameters

ParameterTypeDescription
sortAndFilterZyncOrganizationSortAndFilterComprehensive filter and sort options
pageIntPage number (1-based)
pageSizeIntNumber of organizations per page

ZyncOrganizationSortAndFilter Options

PropertyTypeDescription
sortTypeZyncSortTypeSort direction (Ascending/Descending/DEFAULT)
sortByZyncOrganizationSortByField to sort by (OrganizationName, CreatedDate)
keywordString?Search keyword for organization name or email
customFieldZyncFilterByCustomField?Filter by custom field values
isActiveBoolean?Filter by active status
uidsList<String>?Filter by specific organization UIDs

Return Value: GetOrganizationsResult

Success Case:

  • data: List of ZyncOrganization objects
  • currentPage: Current page number
  • totalPages: Total number of pages available
  • totalRecords: Total number of organizations across all pages
  • isPartialData: true if data is from cache (may be incomplete), false if from API

Failure Case:

  • error: ZyncError with error details

Get Organization Detail

Retrieves comprehensive details for a specific organization, including related data like attachments, custom fields, tax information, and pricing.

import zync.api.organization.models.GetOrganizationResult

when (val result = zync.organization.getOrganizationDetail(
    organizationUid = "550e8400-e29b-41d4-a716-446655440000"
)) {
    is GetOrganizationResult.Success -> {
        val organization = result.data
        val lastSynced = result.lastSyncedAt
        val syncStatus = result.syncStatus

        println("Organization: ${organization.organizationName}")
        println("Email: ${organization.email}")
        println("Timezone: ${organization.organizationTimezone}")
        println("Customers: ${organization.noOfCustomers}")
        println("Custom Fields: ${organization.customFields.size}")
        println("Attachments: ${organization.attachments.size}")
        println("Tax Exempt: ${organization.isTaxExempted}")

        organization.priceList?.let { priceList ->
            println("Price List: ${priceList.name}")
        }

        if (syncStatus == ZyncDataSyncStatus.AGED) {
            println("Note: Data is older than 5 minutes. Last synced: $lastSynced")
        }
    }
    is GetOrganizationResult.Failure -> {
        println("Error: ${result.error.message}")
    }
}
import ZuperSync

switch onEnum(of: await zync.organization.getOrganizationDetail(
    organizationUid: "550e8400-e29b-41d4-a716-446655440000"
)) {
case .success(let success):
    let organization = success.data
    let lastSynced = success.lastSyncedAt
    let syncStatus = success.syncStatus

    print("Organization: \(organization.organizationName)")
    print("Email: \(organization.email ?? "N/A")")
    print("Timezone: \(organization.organizationTimezone ?? "N/A")")
    print("Customers: \(organization.noOfCustomers ?? 0)")
    print("Custom Fields: \(organization.customFields.count)")
    print("Attachments: \(organization.attachments.count)")
    print("Tax Exempt: \(organization.isTaxExempted)")

    if let priceList = organization.priceList {
        print("Price List: \(priceList.name)")
    }

    if syncStatus == .aged {
        print("Note: Data is older than 5 minutes. Last synced: \(lastSynced)")
    }

case .failure(let failure):
    print("Error: \(failure.error.message)")
}

Parameters

ParameterTypeDescription
organizationUidStringUnique identifier of the organization

Return Value: GetOrganizationResult

Success Case:

  • data: ZyncOrganizationDetail object with comprehensive organization information
  • syncStatus: ZyncDataSyncStatus - Indicates data freshness (NONE for fresh data, AGED for data older than 5 minutes, OUTDATED_RECORD for stale data)
  • lastSyncedAt: String - ISO-8601 formatted timestamp of when this record was last synced from the server

Failure Case:

  • error: ZyncError with error details

Organization Data Models

ZyncOrganization (List Item)

Basic organization information returned in paginated lists:

PropertyTypeDescription
organizationUidStringUnique identifier
organizationNameStringOrganization name
organizationAddressZyncAddress?Primary address
organizationBillingAddressZyncAddress?Billing address
emailString?Email address
organizationTimezoneString?Organization’s timezone
organizationLogoString?Logo URL
noOfCustomersInt?Number of customers associated
isActiveBooleanActive status

ZyncOrganizationDetail (Full Detail)

Comprehensive organization information including all related data:

PropertyTypeDescription
organizationUidStringUnique identifier
organizationNameStringOrganization name
descriptionString?Organization description
organizationTimezoneString?Organization’s timezone
organizationAddressZyncAddress?Primary address
organizationBillingAddressZyncAddress?Billing address
emailString?Email address
organizationLogoString?Logo URL
noOfCustomersInt?Number of customers
isActiveBooleanActive status
createdByZyncCreatedByUser?User who created the organization
createdAtStringCreation timestamp
customFieldsList<ZyncFormField>Custom field values
attachmentsList<ZyncAttachment>Organization attachments
taxGroupZyncTaxGroup?Associated tax group
isTaxExemptedBooleanTax exemption status
priceListZyncPriceList?Associated price list

Best Practices

Pagination

Start with page 1 and use consistent page sizes across requests for predictable behavior. Monitor the isPartialData flag to determine if data is from cache.

suspend fun loadAllOrganizations() {
    val filter = ZyncOrganizationSortAndFilter(isActive = true)
    var currentPage = 1
    val pageSize = 50

    do {
        when (val result = zync.organization.fetchOrganizations(filter, currentPage, pageSize)) {
            is GetOrganizationsResult.Success -> {
                processOrganizations(result.data)
                currentPage++

                if (result.isPartialData) {
                    println("Warning: Showing cached data")
                }

                if (currentPage > result.totalPages) break
            }
            is GetOrganizationsResult.Failure -> {
                println("Error loading page $currentPage: ${result.error.message}")
                break
            }
        }
    } while (true)
}
func loadAllOrganizations() async {
    let filter = ZyncOrganizationSortAndFilter(isActive: true)
    var currentPage = 1
    let pageSize = 50

    while true {
        switch onEnum(of: await zync.organization.fetchOrganizations(
            sortAndFilter: filter,
            page: currentPage,
            pageSize: pageSize
        )) {
        case .success(let success):
            processOrganizations(success.data)
            currentPage += 1

            if success.isPartialData {
                print("Warning: Showing cached data")
            }

            if currentPage > success.totalPages { break }

        case .failure(let failure):
            print("Error loading page \(currentPage): \(failure.error.message)")
            break
        }
    }
}

Filtering & Sorting

Use keyword search to find organizations by name or email. Combine with other filters for precise results.

val filter = ZyncOrganizationSortAndFilter(
    sortType = ZyncSortType.Descending,
    sortBy = ZyncOrganizationSortBy.CreatedDate,
    keyword = "tech corp",
    isActive = true
)

val result = zync.organization.fetchOrganizations(filter, 1, 50)
let filter = ZyncOrganizationSortAndFilter(
    sortType: .descending,
    sortBy: .createdDate,
    keyword: "tech corp",
    isActive: true
)

let result = await zync.organization.fetchOrganizations(
    sortAndFilter: filter,
    page: 1,
    pageSize: 50
)

Offline-First Behavior

The Organization Management API follows an offline-first approach. Data is immediately available from cache, with background synchronization when online. Always check the isPartialData flag to determine data freshness.

The SDK returns cached data when offline and syncs in the background when online.

Error Handling

Always handle both Success and Failure cases. Use error.message for user-friendly messages and error.httpStatusCode for specific error handling.

when (val result = zync.organization.getOrganizationDetail(organizationUid)) {
    is GetOrganizationResult.Success -> {
        // Handle success
    }
    is GetOrganizationResult.Failure -> {
        when (result.error.httpStatusCode) {
            404 -> println("Organization not found")
            401 -> println("Authentication required")
            else -> println("Error: ${result.error.message}")
        }
    }
}
switch onEnum(of: await zync.organization.getOrganizationDetail(organizationUid: organizationUid)) {
case .success(let success):
    // Handle success

case .failure(let failure):
    switch failure.error.httpStatusCode {
    case 404:
        print("Organization not found")
    case 401:
        print("Authentication required")
    default:
        print("Error: \(failure.error.message)")
    }
}

Common Use Cases

Search Organizations by Keyword

val searchFilter = ZyncOrganizationSortAndFilter(
    keyword = "tech solutions",
    isActive = true
)

when (val result = zync.organization.fetchOrganizations(searchFilter, 1, 20)) {
    is GetOrganizationsResult.Success -> {
        println("Found ${result.totalRecords} organizations matching 'tech solutions'")
        result.data.forEach { org ->
            println("${org.organizationName} - ${org.email}")
        }
    }
    is GetOrganizationsResult.Failure -> {
        println("Search failed: ${result.error.message}")
    }
}
let searchFilter = ZyncOrganizationSortAndFilter(
    keyword: "tech solutions",
    isActive: true
)

switch onEnum(of: await zync.organization.fetchOrganizations(
    sortAndFilter: searchFilter,
    page: 1,
    pageSize: 20
)) {
case .success(let success):
    print("Found \(success.totalRecords) organizations matching 'tech solutions'")
    success.data.forEach { org in
        print("\(org.organizationName) - \(org.email ?? "N/A")")
    }

case .failure(let failure):
    print("Search failed: \(failure.error.message)")
}

Filter by Specific UIDs

val uidFilter = ZyncOrganizationSortAndFilter(
    uids = listOf("org-uid-1", "org-uid-2", "org-uid-3"),
    sortBy = ZyncOrganizationSortBy.OrganizationName
)

val result = zync.organization.fetchOrganizations(uidFilter, 1, 50)
let uidFilter = ZyncOrganizationSortAndFilter(
    uids: ["org-uid-1", "org-uid-2", "org-uid-3"],
    sortBy: .organizationName
)

let result = await zync.organization.fetchOrganizations(
    sortAndFilter: uidFilter,
    page: 1,
    pageSize: 50
)

Get Organization with Tax and Pricing Information

when (val result = zync.organization.getOrganizationDetail(organizationUid)) {
    is GetOrganizationResult.Success -> {
        val organization = result.data

        println("Organization: ${organization.organizationName}")
        println("Customers: ${organization.noOfCustomers}")

        // Access tax information
        if (organization.isTaxExempted) {
            println("Tax Status: Exempt")
        } else {
            organization.taxGroup?.let { taxGroup ->
                println("Tax Group: ${taxGroup.name}")
                println("Tax Rate: ${taxGroup.totalTax}%")
            }
        }

        // Access pricing information
        organization.priceList?.let { priceList ->
            println("Price List: ${priceList.name}")
            println("Discount: ${priceList.discount}%")
        }

        // Access custom fields
        organization.customFields.forEach { field ->
            println("${field.fieldName}: ${field.fieldValue}")
        }

        // Access attachments
        organization.attachments.forEach { attachment ->
            println("Attachment: ${attachment.fileName}")
        }
    }
    is GetOrganizationResult.Failure -> {
        println("Error: ${result.error.message}")
    }
}
switch onEnum(of: await zync.organization.getOrganizationDetail(organizationUid: organizationUid)) {
case .success(let success):
    let organization = success.data

    print("Organization: \(organization.organizationName)")
    print("Customers: \(organization.noOfCustomers ?? 0)")

    // Access tax information
    if organization.isTaxExempted {
        print("Tax Status: Exempt")
    } else if let taxGroup = organization.taxGroup {
        print("Tax Group: \(taxGroup.name)")
        print("Tax Rate: \(taxGroup.totalTax ?? 0)%")
    }

    // Access pricing information
    if let priceList = organization.priceList {
        print("Price List: \(priceList.name)")
        print("Discount: \(priceList.discount ?? 0)%")
    }

    // Access custom fields
    organization.customFields.forEach { field in
        print("\(field.fieldName): \(field.fieldValue ?? "N/A")")
    }

    // Access attachments
    organization.attachments.forEach { attachment in
        print("Attachment: \(attachment.fileName)")
    }

case .failure(let failure):
    print("Error: \(failure.error.message)")
}

Copyright © 2025 Zuper Inc. All rights reserved. This software is proprietary and confidential.