> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/common/permission/contact.md).

# Contacts

{% hint style="info" %}
**Permission setup is required**

`fetchContacts`You need to set contact permissions before using it. Please check the permission setup guide first.
{% endhint %}

***

### Fetch Contacts

**SDK function:** `fetchContacts`

`fetchContacts`is a function that fetches the user's contact list page by page.

**Signature**

```typescript
function fetchContacts(options: {
  size: number;
  offset: number;
  query?: {
    contains?: string;
  };
}): Promise<ContactResult>;
```

**Parameters**

* **options** · Required

  This is the options object specified when fetching contacts.

  * **options.size** · Required

    The number of contacts to fetch at once. For example, if you pass 10, it will fetch up to 10 contacts.
  * **options.offset** · Required

    The starting point for the contacts to fetch. When calling it for the first time, `0`you need to pass it. After that, use the `nextOffset` value returned from the previous call.

    * **options.query** · Required

      Additional filtering options.

      * **options.query.contains** · Required

        Use this when you want to fetch only contacts whose names contain a specific string. If you don't pass this value, it fetches all contacts.

**Properties**

* openPermissionDialog

  Displays a dialog to request contact read permission again. The user can choose one of "Allow", "Allow once", or "Don't allow". If they choose "Allow" or "Allow once", `allowed`it returns, and if they choose "Don't allow", `denied`is returned.
* getPermission

  Returns the current status of contact read permission. `allowed`indicates that the user has granted contact read permission. `denied`indicates that the user has denied contact read permission. `notDetermined`indicates that the contact read permission has never been requested. If contact permission is denied in the Toss app settings, `osPermissionDenied`is returned.

**Return value**

* `Promise<ContactResult>`

Returns an object containing the contact list and pagination information.

* `result`: The fetched contact list.
* `nextOffset`: The offset value to use for the next call. If there are no more contacts to fetch, `null`.
* `done`: Indicates whether all contacts have been fetched. If all have been fetched, `true`It is.

### Contact permission error

**Error type:** `FetchContactsPermissionError`

This error occurs when contact permission is denied. When this error occurs, `error instanceof FetchContactsPermissionError`you can check it using

**Signature**

```typescript
class FetchContactsPermissionError extends PermissionError {
  constructor();
}
```

**Example**

**Fetch a list of contacts containing a specific string**

This is an example of fetching a contact list. Press the "Check permission" button to verify the current contact read permission. If the user has denied permission or the system has restricted permission, `FetchContactsPermissionError`it returns. Press the "Request permission" button to request contact read permission.

{% tabs %}
{% tab title="js" %}

```js
import { fetchContacts, FetchContactsPermissionError } from '@apps-in-toss/web-framework';

async function handleFetchContacts() {
  try {
    const response = await fetchContacts({
      size: 10,
      offset: 0,
      query: { contains: '김' },
    });

    return response;
  } catch (error) {
    if (error instanceof FetchContactsPermissionError) {
      console.log('No contact read permission');
    }
    console.error('Failed to fetch contacts:', error);
  }
}

async function handleGetPermissionForFetchContacts() {
  const permission = await fetchContacts.getPermission();
  return permission;
}

async function handleOpenPermissionDialogForFetchContacts() {
  const permission = await fetchContacts.openPermissionDialog();
  return permission;
}
```

{% endtab %}

{% tab title="React" %}

```tsx
import { ContactEntity, fetchContacts, FetchContactsPermissionError } from '@apps-in-toss/web-framework';
import { useState } from 'react';

function ContactsList() {
  const [contacts, setContacts] = useState<{
    result: ContactEntity[];
    nextOffset: number | null;
    done: boolean;
  }>({
    result: [],
    nextOffset: null,
    done: false,
  });

  const handlePress = async () => {
    try {
      if (contacts.done) {
        console.log('All contacts have been fetched.');
        return;
      }

      const response = await fetchContacts({
        size: 10,
        offset: contacts.nextOffset ?? 0,
        query: { contains: '김' },
      });
      setContacts((prev) => ({
        result: [...prev.result, ...response.result],
        nextOffset: response.nextOffset,
        done: response.done,
      }));
    } catch (error) {
      if (error instanceof FetchContactsPermissionError) {
        console.log('No contact read permission');
      }
      console.error('Failed to fetch contacts:', error);
    }
  };

  return (
    <div>
      {contacts.result.map((contact, index) => (
        <span key={index}>
          {contact.name}: {contact.phoneNumber}
        </span>
      ))}
      <input
        type="button"
        value={contacts.done ? 'All contacts have been fetched.' : 'Fetch next contacts'}
        disabled={contacts.done}
        onClick={handlePress}
      />
      <input
        type="button"
        value="Check permission"
        onClick={async () => {
          const permission = await fetchContacts.getPermission();
          alert(permission);
        }}
      />
      <input
        type="button"
        value="Request permission"
        onClick={async () => {
          const permission = await fetchContacts.openPermissionDialog();
          alert(permission);
        }}
      />

  );
}
```

{% endtab %}

{% tab title="React Native" %}

```tsx
import { ContactEntity, fetchContacts, FetchContactsPermissionError } from '@apps-in-toss/framework';
import { useState } from 'react';
import { Alert, Button, Text, View } from 'react-native';

function ContactsList() {
  const [contacts, setContacts] = useState<{
    result: ContactEntity[];
    nextOffset: number | null;
    done: boolean;
  }>({
    result: [],
    nextOffset: null,
    done: false,
  });

  const handlePress = async () => {
    try {
      if (contacts.done) {
        console.log('All contacts have been fetched.');
        return;
      }

      const response = await fetchContacts({
        size: 10,
        offset: contacts.nextOffset ?? 0,
        query: { contains: '김' },
      });
      setContacts((prev) => ({
        result: [...prev.result, ...response.result],
        nextOffset: response.nextOffset,
        done: response.done,
      }));
    } catch (error) {
      if (error instanceof FetchContactsPermissionError) {
        console.log('No contact read permission');
      }
      console.error('Failed to fetch contacts:', error);
    }
  };

  return (
    <View>
      {contacts.result.map((contact, index) => (
        <Text key={index}>
          {contact.name}: {contact.phoneNumber}
        </Text>
      ))}
      <Button
        title={contacts.done ? 'All contacts have been fetched.' : 'Fetch next contacts'}
        disabled={contacts.done}
        onPress={handlePress}
      />
      <Button
        title="Check permission"
        onPress={async () => {
          const permission = await fetchContacts.getPermission();
          Alert.alert(permission);
        }}
      />
      <Button
        title="Request permission"
        onPress={async () => {
          const permission = await fetchContacts.openPermissionDialog();
          Alert.alert(permission);
        }}
      />
    </View>
  );
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/common/permission/contact.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
