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

# Call Logs

> Display CometChat Calls SDK v5 call logs on iOS with call history, participants, call type, duration, and status details.

Retrieve call history for your application. Call logs provide detailed information about past calls including duration, participants, recordings, and status.

## Fetch Call Logs

Use `CallLogsRequest` to fetch call logs with pagination support. The builder pattern allows you to filter results by various criteria.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let callLogRequest = CallLogsRequest.CallLogsRequestBuilder()
        .setLimit(30)
        .build()

    callLogRequest.fetchNext(onSuccess: { callLogs in
        for callLog in callLogs {
            print("Session: \(callLog.sessionID ?? "")")
            print("Duration: \(callLog.totalDuration ?? "")")
            print("Status: \(callLog.status ?? "")")
        }
    }, onError: { error in
        print("Error: \(error?.errorDescription ?? "")")
    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objectivec theme={null}
    CallLogsRequest *callLogRequest = [[[CallLogsRequest CallLogsRequestBuilder]
        setLimit:30]
        build];

    [callLogRequest fetchNextOnSuccess:^(NSArray<CallLog *> * callLogs) {
        for (CallLog *callLog in callLogs) {
            NSLog(@"Session: %@", callLog.sessionID);
            NSLog(@"Duration: %@", callLog.totalDuration);
            NSLog(@"Status: %@", callLog.status);
        }
    } onError:^(CometChatCallException * error) {
        NSLog(@"Error: %@", error.errorDescription);
    }];
    ```
  </Tab>
</Tabs>

## CallLogsRequestBuilder

Configure the request using the builder methods:

| Method                     | Type   | Description                                                      |
| -------------------------- | ------ | ---------------------------------------------------------------- |
| `setLimit(Int)`            | Int    | Number of call logs to fetch per request (default: 30, max: 100) |
| `setSessionType(String)`   | String | Filter by call type: `video` or `audio`                          |
| `setCallStatus(String)`    | String | Filter by call status                                            |
| `setHasRecording(Bool)`    | Bool   | Filter calls that have recordings                                |
| `setCallCategory(String)`  | String | Filter by category: `call` or `meet`                             |
| `setCallDirection(String)` | String | Filter by direction: `incoming` or `outgoing`                    |
| `setUid(String)`           | String | Filter calls with a specific user                                |
| `setGuid(String)`          | String | Filter calls with a specific group                               |

### Filter Examples

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    // Fetch only video calls
    let videoCallsRequest = CallLogsRequest.CallLogsRequestBuilder()
        .setSessionType("video")
        .setLimit(20)
        .build()

    // Fetch calls with recordings
    let recordedCallsRequest = CallLogsRequest.CallLogsRequestBuilder()
        .setHasRecording(true)
        .build()

    // Fetch missed incoming calls
    let missedCallsRequest = CallLogsRequest.CallLogsRequestBuilder()
        .setCallStatus("missed")
        .setCallDirection("incoming")
        .build()

    // Fetch calls with a specific user
    let userCallsRequest = CallLogsRequest.CallLogsRequestBuilder()
        .setUid("user_id")
        .build()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objectivec theme={null}
    // Fetch only video calls
    CallLogsRequest *videoCallsRequest = [[[[CallLogsRequest CallLogsRequestBuilder]
        setSessionType:@"video"]
        setLimit:20]
        build];

    // Fetch calls with recordings
    CallLogsRequest *recordedCallsRequest = [[[CallLogsRequest CallLogsRequestBuilder]
        setHasRecording:YES]
        build];

    // Fetch missed incoming calls
    CallLogsRequest *missedCallsRequest = [[[[CallLogsRequest CallLogsRequestBuilder]
        setCallStatus:@"missed"]
        setCallDirection:@"incoming"]
        build];

    // Fetch calls with a specific user
    CallLogsRequest *userCallsRequest = [[[CallLogsRequest CallLogsRequestBuilder]
        setUid:@"user_id"]
        build];
    ```
  </Tab>
</Tabs>

## Pagination

Use `fetchNext()` and `fetchPrevious()` for pagination:

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    // Fetch next page
    callLogRequest.fetchNext(onSuccess: { callLogs in
        // Handle next page
    }, onError: { error in
        print("Error: \(error?.errorDescription ?? "")")
    })

    // Fetch previous page
    callLogRequest.fetchPrevious(onSuccess: { callLogs in
        // Handle previous page
    }, onError: { error in
        print("Error: \(error?.errorDescription ?? "")")
    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objectivec theme={null}
    // Fetch next page
    [callLogRequest fetchNextOnSuccess:^(NSArray<CallLog *> * callLogs) {
        // Handle next page
    } onError:^(CometChatCallException * error) {
        NSLog(@"Error: %@", error.errorDescription);
    }];

    // Fetch previous page
    [callLogRequest fetchPreviousOnSuccess:^(NSArray<CallLog *> * callLogs) {
        // Handle previous page
    } onError:^(CometChatCallException * error) {
        NSLog(@"Error: %@", error.errorDescription);
    }];
    ```
  </Tab>
</Tabs>

## CallLog Object

Each `CallLog` object contains detailed information about a call:

| Property                 | Type         | Description                            |
| ------------------------ | ------------ | -------------------------------------- |
| `sessionID`              | String       | Unique identifier for the call session |
| `initiator`              | CallEntity   | User who initiated the call            |
| `receiver`               | CallEntity   | User or group that received the call   |
| `receiverType`           | String       | `user` or `group`                      |
| `type`                   | String       | Call type: `video` or `audio`          |
| `status`                 | String       | Final status of the call               |
| `callCategory`           | String       | Category: `call` or `meet`             |
| `initiatedAt`            | Int          | Timestamp when call was initiated      |
| `endedAt`                | Int          | Timestamp when call ended              |
| `totalDuration`          | String       | Human-readable duration (e.g., "5:30") |
| `totalDurationInMinutes` | Double       | Duration in minutes                    |
| `totalAudioMinutes`      | Double       | Audio duration in minutes              |
| `totalVideoMinutes`      | Double       | Video duration in minutes              |
| `totalParticipants`      | Int          | Number of participants                 |
| `hasRecording`           | Bool         | Whether the call was recorded          |
| `recordings`             | \[Recording] | List of recording objects              |

## Access Recordings

If a call has recordings, access them through the `recordings` property:

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    callLogRequest.fetchNext(onSuccess: { callLogs in
        for callLog in callLogs {
            if callLog.hasRecording {
                for recording in callLog.recordings ?? [] {
                    print("Recording ID: \(recording.rid ?? "")")
                    print("Recording URL: \(recording.recordingURL ?? "")")
                    print("Duration: \(recording.duration) seconds")
                }
            }
        }
    }, onError: { error in
        print("Error: \(error?.errorDescription ?? "")")
    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objectivec theme={null}
    [callLogRequest fetchNextOnSuccess:^(NSArray<CallLog *> * callLogs) {
        for (CallLog *callLog in callLogs) {
            if (callLog.hasRecording) {
                for (Recording *recording in callLog.recordings) {
                    NSLog(@"Recording ID: %@", recording.rid);
                    NSLog(@"Recording URL: %@", recording.recordingURL);
                    NSLog(@"Duration: %f seconds", recording.duration);
                }
            }
        }
    } onError:^(CometChatCallException * error) {
        NSLog(@"Error: %@", error.errorDescription);
    }];
    ```
  </Tab>
</Tabs>

<Accordion title="Call Status Values">
  | Status       | Description                         |
  | ------------ | ----------------------------------- |
  | `ongoing`    | Call is currently in progress       |
  | `busy`       | Receiver was busy                   |
  | `rejected`   | Call was rejected                   |
  | `cancelled`  | Call was cancelled by initiator     |
  | `ended`      | Call ended normally                 |
  | `missed`     | Call was missed                     |
  | `initiated`  | Call was initiated but not answered |
  | `unanswered` | Call was not answered               |
</Accordion>

<Accordion title="Call Category Values">
  | Category | Description               |
  | -------- | ------------------------- |
  | `call`   | Direct call between users |
  | `meet`   | Meeting/conference call   |
</Accordion>

<Accordion title="Call Direction Values">
  | Direction  | Description                |
  | ---------- | -------------------------- |
  | `incoming` | Call received by the user  |
  | `outgoing` | Call initiated by the user |
</Accordion>
