> ## Documentation Index
> Fetch the complete documentation index at: https://docs.contactsmanager.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Accessing the API

> How to access and use the ContactsManager SDK API

## Installation

Install and initialize the ContactsManager SDK in your client application.

<Tabs>
  <Tab title="Swift">
    #### Swift Package Manager

    Add the ContactsManager package to your Swift project by adding it as a dependency in your `Package.swift` file:

    ```swift theme={null}
    dependencies: [
        .package(url: "https://github.com/arpwal/contactsmanager-ios.git", from: "<latest-version>")
    ]
    ```

    Or in Xcode:

    1. Go to File > Swift Packages > Add Package Dependency
    2. Enter the repository URL: `https://github.com/arpwal/contactsmanager-ios.git`
    3. Specify a minimum version of `<latest-version>` from the repository
    4. Click Next and complete the integration

    #### SDK Initialization

    ```swift theme={null}
    import ContactsManager

    // Create user information
    let userInfo = UserInfo(
        userId: "user-123",
        email: "user@example.com",
        phone: "+15555555555",
        fullName: "John Doe",
        avatarUrl: "https://...", // Optional
        metadata: ["key": "value"] // Optional
    )

    // Initialize the SDK
    try await ContactsService.shared.initialize(
        withAPIKey: "your-api-key",
        token: "user-auth-token", // Optional but recommended for security
        userInfo: userInfo
    )

    // Enable background sync if needed
    ContactsService.shared.enableBackgroundSync()
    ```
  </Tab>

  <Tab title="React Native">
    #### Installation

    ```bash theme={null}
    npm install @contactsmanager/rn
    # or
    yarn add @contactsmanager/rn
    ```

    #### Platform Setup

    ##### iOS Setup

    1. Install CocoaPods dependencies:

    ```bash theme={null}
    cd ios && pod install && cd ..
    ```

    2. Add permissions to `Info.plist`:

    ```xml theme={null}
    <key>NSContactsUsageDescription</key>
    <string>We need access to your contacts to enable social features</string>
    ```

    ##### Android Setup

    The dependency is automatically added to your project.

    #### SDK Initialization

    ```javascript theme={null}
    import { initialize, isInitialized, enableBackgroundSync } from '@contactsmanager/rn';

    // Check if already initialized
    const alreadyInitialized = await isInitialized();

    // Initialize with your API key and token from server
    const result = await initialize({
      apiKey: 'your-api-key',
      token: 'user-auth-token', // Optional but recommended for security
      userInfo: {
        userId: 'unique-user-id',
        email: 'user@example.com', // Optional
        phone: '+15551234567', // Optional
        fullName: 'User Name', // Optional
        avatarUrl: 'https://...', // Optional
        metadata: { key: 'value' } // Optional
      }
    });

    // Enable background sync if needed
    await enableBackgroundSync();
    ```
  </Tab>

  <Tab title="Objective-C">
    #### Installation

    1. Download the latest `ContactsManager.framework` from [Releases](https://github.com/arpwal/contactsmanager-objc/releases)
    2. Drag and drop the framework into your Xcode project
    3. Add framework to "Link Binary With Libraries" in Build Phases
    4. Add to Info.plist:

    ```xml theme={null}
    <key>NSContactsUsageDescription</key>
    <string>We need access to contacts to enable social features.</string>
    ```

    #### SDK Initialization

    ```objc theme={null}
    #import <ContactsManager/ContactsManager.h>

    // Create user info
    CMUserInfo *userInfo = [[CMUserInfo alloc] init];
    userInfo.userId = @"user123";
    userInfo.email = @"user@example.com";  // Optional
    userInfo.phone = @"+1234567890";       // Optional
    userInfo.fullName = @"John Doe";       // Optional
    userInfo.avatarUrl = @"https://...";   // Optional
    userInfo.metadata = @{@"key": @"value"}; // Optional

    // Initialize with options (optional)
    CMContactsManagerOptions *options = [CMContactsManagerOptions defaultOptions];
    options.restrictedKeysToFetch = @[@(CMContactDataRestrictionNotes)]; // Optional

    // Initialize the service
    [[CMContactService sharedInstance] initializeWithAPIKey:@"your_api_key"
                                                token:@"your_token" // Optional
                                             userInfo:userInfo
                                              options:options // Optional
                                           completion:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            NSLog(@"ContactsManager initialized successfully");
        } else {
            NSLog(@"Initialization failed: %@", error.localizedDescription);
        }
    }];
    ```
  </Tab>

  <Tab title="Kotlin">
    #### Installation

    Add the library to your project's `build.gradle`:

    ```gradle theme={null}
    implementation("io.contactsmanager:contactsmanager:1.0.5")
    ```

    #### Get Latest Version

    You can check for the latest version of the SDK on [Maven Central](https://central.sonatype.com/artifact/io.contactsmanager/contactsmanager/overview).

    #### Required Permissions

    Add the following permissions to your `AndroidManifest.xml`:

    ```xml theme={null}
    <!-- Required for accessing contacts -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <!-- Required for network operations -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    ```

    #### SDK Initialization

    ```kotlin theme={null}
    // Initialize the library
    private val contactService by lazy { ContactService.getInstance(context) }

    // Create user info
    val userInfo = UserInfo(
        userId = "user-123",
        displayName = "John Doe",
        email = "user@example.com", // Optional
        phone = "+1234567890", // Optional
        avatarUrl = "https://...", // Optional
        metadata = mapOf("key" to "value") // Optional
    )

    // Create options
    val options = CMContactsManagerOptions.defaultOptions().apply {
        // Configure any custom options here if needed
    }

    // Initialize the service
    val initResult = contactService.initialize(
        apiKey = API_KEY,
        token = "user-auth-token", // Optional but recommended for security
        userInfo = userInfo,
        options = options // Optional
    )

    if (initResult.isSuccess) {
        // Service initialized successfully
        val contacts = initResult.data
    } else {
        // Handle initialization error
        val error = initResult.error
    }
    ```
  </Tab>
</Tabs>

## Accessing the Service

The ContactsManager SDK provides a comprehensive API through the `ContactsService` class. Here's how to access and use the service:

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    // Access the shared instance
    let service = ContactsService.shared

    // Check initialization status
    let isInitialized = service.isInitialized

    // Get current state
    let state = service.currentState
    ```
  </Tab>

  <Tab title="React Native">
    ```javascript theme={null}
    import { 
      ContactsService,
      isInitialized,
      currentState
    } from '@contactsmanager/rn';

    // Check initialization
    const initialized = await isInitialized();

    // Get current state
    const state = await currentState();
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    // Access shared instance
    CMContactService *service = [CMContactService sharedInstance];

    // Check initialization
    BOOL isInitialized = service.isInitialized;

    // Get current state
    CMServiceState state = service.currentState;
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Access service instance
    val service = ContactService.getInstance(context)

    // Check initialization
    val isInitialized = service.isInitialized

    // Get current state
    val state = service.currentState
    ```
  </Tab>
</Tabs>

## Error Handling

The SDK provides comprehensive error handling across all platforms:

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    do {
        try await ContactsService.shared.initialize(
            withAPIKey: "your-api-key",
            token: "user-auth-token",
            userInfo: userInfo
        )
    } catch let error as ContactsServiceError {
        switch error {
        case .invalidAPIKey:
            print("Invalid API key")
        case .apiKeyValidationFailed(let reason):
            print("API key validation failed: \(reason)")
        case .networkError(let error):
            print("Network error: \(error.localizedDescription)")
        case .initializationFailed(let error):
            print("Initialization failed: \(error.localizedDescription)")
        case .databaseError(let error):
            print("Database error: \(error.localizedDescription)")
        case .notInitialized:
            print("SDK not initialized")
        case .contactsAccessDenied:
            print("Contacts access denied")
        case .userNotAuthenticated:
            print("User not authenticated")
        case .invalidUserInfo(let reason):
            print("Invalid user info: \(reason)")
        case .customError(let message):
            print("Error: \(message)")
        }
    }
    ```
  </Tab>

  <Tab title="React Native">
    ```javascript theme={null}
    try {
      await initialize({
        apiKey: 'your-api-key',
        token: 'user-auth-token',
        userInfo: {
          userId: 'unique-user-id',
          email: 'user@example.com'
        }
      });
    } catch (error) {
      switch (error.code) {
        case 'INVALID_API_KEY':
          console.error('Invalid API key');
          break;
        case 'API_KEY_VALIDATION_FAILED':
          console.error(`API key validation failed: ${error.message}`);
          break;
        case 'NETWORK_ERROR':
          console.error(`Network error: ${error.message}`);
          break;
        case 'INITIALIZATION_FAILED':
          console.error(`Initialization failed: ${error.message}`);
          break;
        case 'DATABASE_ERROR':
          console.error(`Database error: ${error.message}`);
          break;
        case 'NOT_INITIALIZED':
          console.error('SDK not initialized');
          break;
        case 'CONTACTS_ACCESS_DENIED':
          console.error('Contacts access denied');
          break;
        case 'USER_NOT_AUTHENTICATED':
          console.error('User not authenticated');
          break;
        case 'INVALID_USER_INFO':
          console.error(`Invalid user info: ${error.message}`);
          break;
        default:
          console.error(`Unexpected error: ${error.message}`);
      }
    }
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [[CMContactService sharedInstance] initializeWithAPIKey:@"your_api_key"
                                                token:@"your_token"
                                             userInfo:userInfo
                                              options:options
                                           completion:^(BOOL success, NSError * _Nullable error) {
        if (!success) {
            switch (error.code) {
                case CMErrorInvalidAPIKey:
                    NSLog(@"Invalid API key");
                    break;
                case CMErrorAPIKeyValidationFailed:
                    NSLog(@"API key validation failed: %@", error.localizedDescription);
                    break;
                case CMErrorNetworkError:
                    NSLog(@"Network error: %@", error.localizedDescription);
                    break;
                case CMErrorInitializationFailed:
                    NSLog(@"Initialization failed: %@", error.localizedDescription);
                    break;
                case CMErrorDatabaseError:
                    NSLog(@"Database error: %@", error.localizedDescription);
                    break;
                case CMErrorNotInitialized:
                    NSLog(@"SDK not initialized");
                    break;
                case CMErrorContactsAccessDenied:
                    NSLog(@"Contacts access denied");
                    break;
                case CMErrorUserNotAuthenticated:
                    NSLog(@"User not authenticated");
                    break;
                case CMErrorInvalidUserInfo:
                    NSLog(@"Invalid user info: %@", error.localizedDescription);
                    break;
                default:
                    NSLog(@"Unexpected error: %@", error.localizedDescription);
            }
        }
    }];
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    try {
        val result = contactService.initialize(
            apiKey = API_KEY,
            token = "user-auth-token",
            userInfo = userInfo
        )
        
        if (!result.isSuccess) {
            when (result.error) {
                is ContactsError.InvalidAPIKey -> 
                    Log.e(TAG, "Invalid API key")
                is ContactsError.APIKeyValidationFailed -> 
                    Log.e(TAG, "API key validation failed: ${result.error.reason}")
                is ContactsError.NetworkError -> 
                    Log.e(TAG, "Network error: ${result.error.message}")
                is ContactsError.InitializationFailed -> 
                    Log.e(TAG, "Initialization failed: ${result.error.message}")
                is ContactsError.DatabaseError -> 
                    Log.e(TAG, "Database error: ${result.error.message}")
                is ContactsError.NotInitialized -> 
                    Log.e(TAG, "SDK not initialized")
                is ContactsError.ContactsAccessDenied -> 
                    Log.e(TAG, "Contacts access denied")
                is ContactsError.UserNotAuthenticated -> 
                    Log.e(TAG, "User not authenticated")
                is ContactsError.InvalidUserInfo -> 
                    Log.e(TAG, "Invalid user info: ${result.error.reason}")
                else -> 
                    Log.e(TAG, "Unexpected error: ${result.error}")
            }
        }
    } catch (e: Exception) {
        Log.e(TAG, "Unexpected error: ${e.message}")
    }
    ```
  </Tab>
</Tabs>

<Warning>
  **Important: Secure Your Users' Data**

  Server-side token generation is required to ensure the security of your users' contact data. By handling authentication through your server, you establish a two-factor security model:

  1. API Key verification
  2. Server-generated token validation

  This approach ensures that only authenticated devices with valid server-issued tokens can access your users' contact data. Your server maintains complete control over data access, allowing you to:

  * Authenticate users through your existing auth system
  * Immediately revoke access when needed
  * Protect against unauthorized data access
  * Monitor and audit access patterns

  See the server setup section in the [Quickstart guide](/quickstart) for implementation details.
</Warning>
