Access Phone Contacts with Contact Picker API

The Contact Picker API allows mobile web applications to request on-demand access to a user’s device contact list directly through JavaScript. This article explains how the API operates, how to check for browser support, how to invoke the native contact selector using navigator.contacts.select(), and the security constraints that govern user privacy during the selection process.

Feature Detection and Supported Properties

Before requesting access to contacts, you must verify that the user’s browser supports the Contact Picker API. You can also query which contact properties (such as names, phone numbers, or email addresses) the device supports.

const isSupported = 'contacts' in navigator && 'ContactsManager' in window;

async function checkProperties() {
  if (isSupported) {
    const supportedProperties = await navigator.contacts.getProperties();
    console.log('Supported properties:', supportedProperties);
    // Expected output: ['name', 'email', 'tel', 'address', 'icon']
  }
}

Requesting Contacts with navigator.contacts.select()

The primary method for accessing contacts is navigator.contacts.select(). This method requires two parameters: an array of properties you want to retrieve and an optional configuration object.

async function getContacts() {
  if (!isSupported) {
    console.error('Contact Picker API not supported.');
    return;
  }

  const props = ['name', 'tel', 'email'];
  const opts = { multiple: true }; // Set to false to allow only a single selection

  try {
    const contacts = await navigator.contacts.select(props, opts);
    handleContacts(contacts);
  } catch (error) {
    console.error('Contact selection failed or was canceled:', error);
  }
}

function handleContacts(contacts) {
  contacts.forEach(contact => {
    console.log('Name:', contact.name);
    console.log('Phone Numbers:', contact.tel);
    console.log('Emails:', contact.email);
  });
}

How the Request Process Works

  1. User Gesture Requirement: The API cannot be triggered automatically on page load. It must be initiated directly by a user interaction, such as tapping a button.
  2. Native OS UI Prompt: Calling select() launches the mobile operating system’s native contact picker interface over the browser window. The web application has no visibility into the user’s full contact list.
  3. User Selection: The user manually selects only the specific contacts and details they wish to share. If the user cancels the picker, the promise resolves with an empty array or rejects.
  4. Data Return: The promise resolves with an array of objects containing only the requested properties for the contacts explicitly chosen by the user.

Security and Context Requirements