Skip to main content
Version: v8

@capacitor/contacts

Access, search, pick, create, update and remove device contacts.

Installโ€‹

To use npm

npm install @capacitor/contacts

To use yarn

yarn add @capacitor/contacts

Sync native files

npx cap sync

iOSโ€‹

Add the NSContactsUsageDescription key to your app's Info.plist and describe why the app accesses the user's contacts; iOS crashes on first contacts access without it:

<key>NSContactsUsageDescription</key>
<string>We need access to contacts to search, save and remove them.</string>

Notes:

  • The plugin uses the modern Contacts framework (CNContactStore, never the deprecated AddressBook APIs), so it fully supports iOS 18+ Limited Access: find, save and remove operate on the subset the user shared with the app, and pickContact presents the system picker (which needs no permission and always shows the full contact list).
  • The note field is not supported on iOS: reading or writing it requires Apple's restricted com.apple.developer.contacts.notes entitlement. The field is omitted on read and ignored on save.
  • Contact ids are opaque CNContact identifiers; ids persisted by the legacy AddressBook-based Cordova plugin do not resolve after migration.

Androidโ€‹

The plugin declares READ_CONTACTS and WRITE_CONTACTS in its own manifest; Gradle manifest merging adds them to your app automatically. Each method requests the runtime permission it needs the first time it runs; read for find/pickContact, read + write for save/remove.

Permission modelโ€‹

This plugin intentionally exposes no checkPermissions() / requestPermissions() methods: permissions are requested implicitly by each method, matching the legacy cordova-plugin-contacts behavior. A call rejects with OS-PLUG-CONT-0020 when the user denies access.

Errorsโ€‹

Every rejection carries a structured code + message:

CodeMeaning
OS-PLUG-CONT-0000Unknown error
OS-PLUG-CONT-0001Invalid argument (e.g. unknown id)
OS-PLUG-CONT-0002Timeout (reserved, currently unused)
OS-PLUG-CONT-0003Pending operation (e.g. picker already open)
OS-PLUG-CONT-0004I/O error
OS-PLUG-CONT-0005Not supported
OS-PLUG-CONT-0006Operation cancelled (picker closed)
OS-PLUG-CONT-0020Permission denied

Usageโ€‹

import { Contacts } from '@capacitor/contacts';

// Search every field for "ada" and return all matches with a phone number
const { contacts } = await Contacts.find({
fields: ['*'],
filter: 'ada',
multiple: true,
hasPhoneNumber: true,
});

// Create a contact
const saved = await Contacts.save({
contact: {
name: { givenName: 'Ada', familyName: 'Lovelace' },
phoneNumbers: [{ type: 'mobile', value: '+351910000000' }],
emails: [{ type: 'home', value: '[email protected]' }],
},
});

// Update it (id present -> update)
await Contacts.save({ contact: { ...saved, nickname: 'Countess' } });

// Pick a contact with the native picker
const picked = await Contacts.pickContact();

// Remove it by id
await Contacts.remove({ id: saved.id! });

APIโ€‹

find(...)โ€‹

find(options: ContactFindOptions) => Promise<ContactFindResult>

Queries the device contacts database and returns the matching contacts.

Requests the READ_CONTACTS (Android) / Contacts (iOS) permission internally the first time it runs; there is no separate permission method.

iOS 18+: under Limited Access the search runs against (and returns only) the subset of contacts the user shared with the app.

ParamType
options
ContactFindOptions

Returns:

Promise<ContactFindResult>

Since: 1.0.0


save(...)โ€‹

save(options: ContactSaveOptions) => Promise<Contact>

Persists a new contact or updates an existing one (matched by contact.id). Resolves with the full saved contact.

Requests the READ/WRITE_CONTACTS (Android) / Contacts (iOS) permission internally.

iOS 18+: works under Limited Access: new contacts are added to the app's accessible set; updating requires the target contact to be in that set (otherwise the call rejects with OS-PLUG-CONT-0001).

ParamType
options
ContactSaveOptions

Returns:

Promise<Contact>

Since: 1.0.0


remove(...)โ€‹

remove(options: ContactRemoveOptions) => Promise<void>

Removes the contact with the given id from the device contacts database. Rejects with OS-PLUG-CONT-0001 when no contact has that id (on iOS 18+ Limited Access, also when the contact is outside the accessible set).

Requests the READ/WRITE_CONTACTS (Android) / Contacts (iOS) permission internally.

ParamType
options
ContactRemoveOptions

Since: 1.0.0


pickContact()โ€‹

pickContact() => Promise<Contact>

Launches the native contact picker UI and resolves with the contact the user selects. Rejects with OS-PLUG-CONT-0006 if the user cancels.

On iOS the system picker requires no permission and always shows the full contact list, even under iOS 18+ Limited Access (the picked contact is returned without joining the app's accessible set). On Android the READ_CONTACTS permission is requested internally to read the picked contact's details.

Returns:

Promise<Contact>

Since: 1.0.0


Interfacesโ€‹

ContactFindResultโ€‹

Result of a {@link ContactsPlugin.find} call.

PropTypeDescriptionSince
contactsContact[]The contacts matching the search criteria.1.0.0

Contactโ€‹

A single device contact.

PropTypeDescriptionSince
idstringGlobally unique, platform-assigned identifier. Absent for contacts not yet saved to the device.1.0.0
rawIdstringAndroid raw-contact id backing this aggregated contact. iOS leaves this unset.1.0.0
displayNamestringName suitable for display to end users.1.0.0
name
ContactName
The structured name components.1.0.0
nicknamestringA casual name by which to address the contact.1.0.0
phoneNumbersContactField[]The contact's phone numbers.1.0.0
emailsContactField[]The contact's email addresses.1.0.0
addressesContactAddress[]The contact's postal addresses.1.0.0
imsContactField[]The contact's instant-messaging handles.1.0.0
organizationsContactOrganization[]The contact's organizations.1.0.0
birthdaynumberThe contact's birthday as epoch milliseconds.1.0.0
notestringA free-form note about the contact. iOS: not supported by default: reading/writing a contact's note requires Apple's restricted com.apple.developer.contacts.notes entitlement. Without it the field is omitted on read and ignored on save. Android has no such restriction.1.0.0
photosContactField[]The contact's photos. Reads return type: 'url' with the value holding a reference to the image, never image bytes: on Android the contact's content:// photo URI, on iOS the path of a copy written to the app's temporary directory (cleared by the system). On save, the first entry is applied: pass type: 'base64' with base64 data, or type: 'url' with a local file:///content:// URI to import.1.0.0
categoriesContactField[]User-defined categories associated with the contact. Read-only: populated from the contact's group memberships on Android, never returned on iOS (the Contacts framework has no equivalent), and ignored on save.1.0.0
urlsContactField[]Web pages associated with the contact.1.0.0

ContactNameโ€‹

Structured name of a {@link Contact}.

PropTypeDescriptionSince
formattedstringThe complete formatted name.1.0.0
familyNamestringFamily (last) name.1.0.0
givenNamestringGiven (first) name.1.0.0
middleNamestringMiddle name.1.0.0
honorificPrefixstringHonorific prefix (e.g. Mr., Dr.).1.0.0
honorificSuffixstringHonorific suffix (e.g. Esq.).1.0.0

ContactFieldโ€‹

A generic, repeatable contact field (phone number, email, IM, photo, URL, category).

PropTypeDescriptionSince
typestringThe kind of field, e.g. home, work, mobile. For photos, url or base64.1.0.0
valuestringThe field value (phone number, email address, URI, etc.).1.0.0
prefbooleantrue if this is the contact's preferred value for the field.1.0.0
idstringPlatform-assigned id of this individual field entry.1.0.0

ContactAddressโ€‹

A postal address of a {@link Contact}.

PropTypeDescriptionSince
idstringPlatform-assigned id of this address entry.1.0.0
prefbooleantrue if this is the contact's preferred address.1.0.0
typestringThe kind of address, e.g. home, work.1.0.0
formattedstringThe full address formatted for display.1.0.0
streetAddressstringThe street address.1.0.0
localitystringThe city or locality.1.0.0
regionstringThe state or region.1.0.0
postalCodestringThe ZIP or postal code.1.0.0
countrystringThe country name.1.0.0

ContactOrganizationโ€‹

An organization a {@link Contact} belongs to.

PropTypeDescriptionSince
idstringPlatform-assigned id of this organization entry. Android only; iOS models the organization as flat contact properties without an id.1.0.0
prefbooleantrue if this is the contact's preferred organization.1.0.0
typestringThe kind of organization, e.g. work.1.0.0
namestringThe organization name.1.0.0
departmentstringThe department within the organization.1.0.0
titlestringThe contact's title at the organization.1.0.0

ContactFindOptionsโ€‹

Search options accepted by {@link ContactsPlugin.find}.

PropTypeDescriptionSince
fieldsContactFieldType[]Fields to search against. Pass ['*'] to match every field. An empty array is invalid and rejects with OS-PLUG-CONT-0001. The id field matches by exact identifier; all other fields match case-insensitive substrings. photos and categories are not searchable.1.0.0
filterstringSearch string matched (case-insensitively) against the selected fields. An empty/omitted filter returns every contact.1.0.0
multiplebooleanWhen true, returns every match; when false (default), returns at most one contact.1.0.0
desiredFieldsContactFieldType[]If set, each returned {@link Contact} only includes these fields (plus the always-present id).1.0.0
hasPhoneNumberbooleanOutSystems extension: when true, only contacts that have at least one phone number are returned. Defaults to false.1.0.0

ContactSaveOptionsโ€‹

Options accepted by {@link ContactsPlugin.save}.

PropTypeDescriptionSince
contact
Contact
The contact to create (no id) or update (existing id). Update semantics: every field present on the contact replaces the stored value entirely (e.g. name replaces the whole structured name, phoneNumbers replaces all phone numbers); omitted fields are left unchanged.1.0.0

ContactRemoveOptionsโ€‹

Options accepted by {@link ContactsPlugin.remove}.

PropTypeDescriptionSince
idstringThe native id of the contact to remove.1.0.0

Type Aliasesโ€‹

ContactFieldTypeโ€‹

The set of contact fields a {@link ContactsPlugin.find} call can search against or request back. Mirrors the legacy Cordova ContactFieldType string values exactly.

'addresses' | 'birthday' | 'categories' | 'country' | 'department' | 'displayName' | 'emails' | 'familyName' | 'formatted' | 'givenName' | 'honorificPrefix' | 'honorificSuffix' | 'id' | 'ims' | 'locality' | 'middleName' | 'name' | 'nickname' | 'note' | 'organizations' | 'phoneNumbers' | 'photos' | 'postalCode' | 'region' | 'streetAddress' | 'title' | 'urls'