> For the complete documentation index, see [llms.txt](https://docs.buildnatively.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.buildnatively.com/natively-platform/features/contacts.md).

# Contacts

## What is Contacts?

The Contacts feature gives your app access to the device's native contact list, letting users retrieve their existing contacts or create new ones without leaving the app. This is useful for features like inviting friends, syncing a personal address book, or letting users save a new contact your app provides.

Accessing contacts requires the user to grant permission the first time the feature is used, on both iOS and Android.

## Prerequisites

{% hint style="success" %}
This feature requires any **paid** plan. [See all plans](/getting-started/subscription-plans.md)
{% endhint %}

## Natively Dashboard Setup

1. Open your Natively app dashboard and navigate to **Features** > **Contacts**.
2. Toggle the feature to **Enabled**.
3. Enter the **Permission Description**.
4. Click **Save**.
5. Rebuild your app(s).

{% hint style="info" %}
The **Permission Description** is the text shown to users when the OS asks them to grant **contacts** access. Explain clearly why your app needs this permission — for example: "We use your contacts to help you invite friends to the app".
{% endhint %}

{% hint style="warning" %}
You must rebuild your app for these changes to take effect.
{% endhint %}

## Implementation

Choose your integration method below: **Bubble.io Plugin** (No-Code), **JavaScript SDK** (Code), or **AI Agents** (for AI-powered editors like Lovable, Base44, and Replit).

### Initialization

{% tabs %}
{% tab title="Bubble.io Plugin" %}
**Check Plugin**

Before starting, verify if the Natively plugin is already installed in your Bubble project.

1. Open your Bubble editor and navigate to the Plugins tab in the left sidebar.
2. **Check Installed Plugins:** Look through your list of installed plugins for "Natively iOS & Android app builder".
   * If it IS installed: Check the version number. If an update is available (e.g., you see a button saying "Update"), click it to ensure you have the latest features and bug fixes.

<figure><img src="https://docs.buildnatively.com/~gitbook/image?url=https%3A%2F%2F3352617162-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F90tV7pYflEQdiAr2VfWu%252Fuploads%252FmfnSUug82IdnxOAoBrak%252Fnatively_app_builder_bubble_plugin_update.png%3Falt%3Dmedia%26token%3Dc193f69f-b03b-4be4-b80b-f34ba37ac212&#x26;width=768&#x26;dpr=3&#x26;quality=100&#x26;sign=a89e4510&#x26;sv=2" alt=""><figcaption></figcaption></figure>

* If it is NOT installed: Click the + Add plugins button, search for "Natively", and click Install.

<figure><img src="https://docs.buildnatively.com/~gitbook/image?url=https%3A%2F%2F3352617162-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F90tV7pYflEQdiAr2VfWu%252Fuploads%252FC5rA42yQHcN1uGKFbzmF%252Fnatively_app_builder_bubble_plugin.png%3Falt%3Dmedia%26token%3Dd9706d9b-dbe8-459b-b9b3-5667648aa4b7&#x26;width=768&#x26;dpr=3&#x26;quality=100&#x26;sign=9aae2297&#x26;sv=2" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="JavaScript SDK" %}
**Check SDK**

Before writing any logic, ensure the Natively SDK is correctly installed and up-to-date in your codebase.

1. Open your project's main HTML file (or header settings) and look for the Natively script tag inside the `<head>` section.
2. Install/Update: If missing or outdated, add the following code. You can specify the SDK version in the URL (e.g., `@2.26.0`).

```javascript
<head>
  <script async onload="nativelyOnLoad()" src="https://cdn.jsdelivr.net/npm/natively@2.26.0/natively-frontend.min.js"></script>
</head>
```

{% hint style="info" %}
To ensure you are using the most up-to-date version, check the [Natively GitHub releases page](https://github.com/buildnatively/js-sdk/releases) for the latest version number.
{% endhint %}
{% endtab %}

{% tab title="AI Agents" %}
**Initialize the SDK**

AI-powered editors like Lovable, Base44, and Replit use the JavaScript SDK to implement Natively features. Before implementing any feature, the Natively SDK must be initialized in your project.

Copy the line below and paste it into your AI agent to check and set up the Natively SDK in your project.

```
Check if the following Natively SDK script is present in the <head> of index.html. If missing or outdated, add it: <script async onload="nativelyOnLoad()" src="https://cdn.jsdelivr.net/npm/natively@2.26.0/natively-frontend.min.js"></script><script>function nativelyOnLoad() { window.natively.setDebug(true); console.log("✅ Natively SDK loaded successfully."); }</script> For reference: https://docs.buildnatively.com/guides/integration/how-to-get-started https://github.com/buildnatively/js-sdk/releases
```

{% endtab %}
{% endtabs %}

### Setup Logic

{% tabs %}
{% tab title="Bubble.io Plugin" %}

### \[Element] Natively - Contacts

{% hint style="danger" %}
Set the element's data type field to **ContactObject (Natively - ...)**.
{% endhint %}

<figure><img src="/files/TlIxqpoH4UsDhNgIlRCG" alt=""><figcaption></figcaption></figure>

#### Events:

* **Get All Contacts Success** - fires when contacts are successfully retrieved.
* **Get All Contacts Failed** - fires if retrieving contacts fails.
* **Create Contact Success** - fires when a new contact is successfully created.
* **Create Contact Failed** - fires if creating a contact fails.

#### States:

* **Get Contacts Result** — list of `ContactObject`, each with:
  * **FirstName**;
  * **LastName**;
  * **Phones** — comma-separated if the contact has multiple phone numbers (e.g. `"0543523,124334234"`);
  * **Emails** — comma-separated if the contact has multiple emails (e.g. `"test@test.com,help@buildnatively.com"`);
  * **ID** — unique contact identifier on the device.
* **Create Contact ID Result** — the ID of the newly created contact, after **Create Contact**.
* **Create/Get Contacts Status** — result status after calling **Create Contact** or **Get All Contacts**.

#### Actions:

* **Get All Contacts** — returns a list of `ContactObject` .
* **Create Contact** — returns the new contact's ID:
  * **First name**;
  * **Last name**;
  * **Phone**;
  * **Email**;
    {% endtab %}

{% tab title="JavaScript SDK" %}

```javascript
// ============================================================================
// NATIVELY CONTACTS - DOCUMENTATION & EXAMPLES
// ============================================================================

const contacts = new NativelyContacts();

// ============================================================================
// ALL AVAILABLE METHODS
// ============================================================================
// contacts.getAllContacts(callback)
//   - Retrieves all contacts stored on the device.
//
// contacts.createContact(firstName, lastName, email, phone, callback)
//   - Creates a new contact on the device.
//   - firstName: string
//   - lastName: string
//   - email: string
//   - phone: string

// ============================================================================
// CALLBACK RESPONSE FIELDS - getAllContacts
// ============================================================================
// resp.status: string — "SUCCESS" or "FAILED"
// resp.contacts: array — list of contact objects, each with:
//   id: string, firstName: string, lastName: string,
//   phones: array of strings, emails: array of strings

// ============================================================================
// CALLBACK RESPONSE FIELDS - createContact
// ============================================================================
// resp.status: string — "SUCCESS" or "FAILED"
// resp.id: string — the new contact's ID

// --- Contacts. Get All Contacts Example. Start ---

const get_all_contacts_callback = function (resp) {
  console.log(resp.status); // "SUCCESS" or "FAILED"

  resp.contacts.forEach(contact => {
    console.log(contact.id);         // unique contact identifier on the device
    console.log(contact.firstName);
    console.log(contact.lastName);
    console.log(contact.phones);     // array of phone numbers
    console.log(contact.emails);     // array of email addresses
  });
};

contacts.getAllContacts(get_all_contacts_callback);

// --- Contacts. Get All Contacts Example. End ---


// --- Contacts. Create Contact Example. Start ---

const firstName = "Jane";
const lastName = "Doe";
const email = "jane.doe@example.com";
const phone = "+1234567890";

const create_contact_callback = function (resp) {
  console.log(resp.status); // "SUCCESS" or "FAILED"
  console.log(resp.id);     // the new contact's ID
};

contacts.createContact(firstName, lastName, email, phone, create_contact_callback);

// --- Contacts. Create Contact Example. End ---
```

{% endtab %}

{% tab title="AI Agents" %}
AI-powered editors like Lovable, Base44, and Replit use the JavaScript SDK to implement Natively features.&#x20;

Copy the line below and paste it into your AI agent.&#x20;

<pre><code>[<a data-footnote-ref href="#user-content-fn-1">Your feature description</a>] using the Natively Contacts SDK: const contacts = new NativelyContacts(); contacts.getAllContacts(callback) retrieves all contacts stored on the device, returning resp.status ("SUCCESS" or "FAILED") and resp.contacts (array of contact objects, each with id, firstName, lastName, phones (array), emails (array)). contacts.createContact(firstName, lastName, email, phone, callback) creates a new contact, returning resp.status ("SUCCESS" or "FAILED") and resp.id (the new contact's ID). For reference: https://docs.buildnatively.com/guides/integration/contacts
</code></pre>

{% hint style="warning" %}
Replace the placeholder at the beginning with a description of what you want to build - for example: "Let the user create a new contact from a form with name, email, and phone fields".
{% endhint %}
{% endtab %}
{% endtabs %}

### How to use

#### Check `resp.status` before using the result

Both `getAllContacts` and `createContact` return a `status` field - always confirm it's `"SUCCESS"` before iterating over `resp.contacts` or using `resp.id`.

#### Handle multiple phone numbers and emails

A contact may have more than one entry in `phones` or `emails` - don't assume a single value; iterate over the array or pick the one relevant to your use case (e.g., the first entry).

#### Use this to power an invite-a-friend flow

A common use case is letting users pick from their existing contacts to invite friends to your app - retrieve contacts with `getAllContacts`, then let the user select recipients from the results.

## Troubleshooting

<details>

<summary>Contacts permission denied</summary>

If the user previously denied contacts access, the feature can't prompt again automatically. Direct them to [Open App Settings](/guides/integration/open-app-settings.md) to manually re-enable the permission.

</details>

<details>

<summary><code>getAllContacts</code> returns an empty list</summary>

This is expected if the user's device genuinely has no contacts.

</details>

<details>

<summary>Not working in a web browser</summary>

This is a native feature and will not work in a standard web browser. Test on a real device using a Natively build or the Preview app.

</details>

[^1]: Replace this placeholder
