BetaThe V4 API is in beta — endpoints and functionality may change.

Contact cards (Name & Photo)

How to manage and share your iMessage contact card — the Name & Photo identity others see in conversations

This guide covers managing your iMessage contact card (Name & Photo) and sharing it with contacts. The contact card is the identity that recipients see — your name, profile photo, and sharing preferences.

Warning

Contact card features — setting the first name / last name, setting the avatar (profile photo), and sharing your contact card — are only available on Dedicated Commercial and Dedicated Enterprise plans. On other plans these operations return 403.

Overview

The contact card system has two parts:

  1. Managing your card — Read and update the name, photo, and sharing settings for a specific number
  2. Sharing your card — Trigger the actual sharing of your card in a specific chat, so the recipient receives your identity

Note

Contact cards are scoped per number. If your API key is bound to multiple phone numbers, each number has its own contact card. Use GET /me/numbers to discover your available numbers.

Prerequisites

No separate Messages app setup is required on your end. Once a number is provisioned, you can read, update, and share its Name & Photo directly through the API.

Discovering your numbers

If your API key has multiple numbers, you need to specify which one to operate on. List your numbers first:

cURL

curl 'https://api.blooio.com/v2/api/me/numbers' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Try it

Node.js

const res = await fetch('https://api.blooio.com/v2/api/me/numbers', {
  headers: { 'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}` }
})
const { numbers } = await res.json()
console.log(numbers)
// [{ phone_number: "+15551234567", is_active: true, last_active: "2026-..." }]

Python


res = requests.get('https://api.blooio.com/v2/api/me/numbers',
  headers={'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}"}
)
numbers = res.json()['numbers']

Reading your contact card

Get the current contact card for a specific number:

cURL

curl 'https://api.blooio.com/v2/api/me/numbers/%2B15551234567/contact-card' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Try it

Node.js

const number = encodeURIComponent('+15551234567')
const res = await fetch(`https://api.blooio.com/v2/api/me/numbers/${number}/contact-card`, {
  headers: { 'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}` }
})
const card = await res.json()
// { phone_number, first_name, last_name, name, avatar, sharing: { ... } }

Python

from urllib.parse import quote

number = quote('+15551234567', safe='')
res = requests.get(f'https://api.blooio.com/v2/api/me/numbers/{number}/contact-card',
  headers={'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}"}
)
card = res.json()

The response includes:

Field Type Description
first_name string First name
last_name string Last name
name string Display name (usually first + last)
avatar string Base64-encoded JPEG profile photo
has_wallpaper boolean Whether a poster background is set
sharing.enabled boolean Whether Name & Photo sharing is on
sharing.audience integer 0 = Contacts Only, 1 = Always Ask
sharing.name_format integer 0 = First & Last, 1 = First Only

Updating your contact card

Note

Setting the first_name, last_name, or avatar requires a Dedicated Commercial or Dedicated Enterprise plan. Numbers on other plans cannot change these fields.

Update any combination of fields — only provided fields are changed:

cURL

curl -X PUT 'https://api.blooio.com/v2/api/me/numbers/%2B15551234567/contact-card' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "sharing": {
      "enabled": true,
      "audience": 1
    }
  }'
Try it

Node.js

const number = encodeURIComponent('+15551234567')
const res = await fetch(`https://api.blooio.com/v2/api/me/numbers/${number}/contact-card`, {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    first_name: 'John',
    last_name: 'Doe',
    sharing: { enabled: true, audience: 1 }
  })
})

Python

from urllib.parse import quote

number = quote('+15551234567', safe='')
res = requests.put(f'https://api.blooio.com/v2/api/me/numbers/{number}/contact-card',
  headers={
    'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}",
    'Content-Type': 'application/json'
  },
  json={
    'first_name': 'John',
    'last_name': 'Doe',
    'sharing': {'enabled': True, 'audience': 1}
  }
)

Updating the profile photo

To set a profile photo, pass a base64-encoded image in the avatar field.

Photo guidelines:

Property Recommendation
Format JPEG (preferred) or PNG
Shape Square — displayed as a circle in Messages
Size 500x500 to 1024x1024 pixels recommended
Max file size ~1 MB (approximately 1.3 MB as base64)
Transparency Not needed — use JPEG for smaller payload

const imageBuffer = fs.readFileSync('profile.jpg')
const base64Image = imageBuffer.toString('base64')

await fetch(`https://api.blooio.com/v2/api/me/numbers/${number}/contact-card`, {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ avatar: base64Image })
})

Sharing your contact card in a chat

After your card is configured, you can share it with specific contacts. Contact sharing in iMessage works as a piggyback — your card is attached to the next outgoing message you send.

Note

Sharing your contact card (the standalone endpoint and the share_contact: true flag) is only available on Dedicated Commercial and Dedicated Enterprise plans.

There are two ways to trigger this:

Option 1: Standalone endpoint (stage, then send separately)

First stage the share, then send a message in a separate call:

# Step 1: Stage the contact card share
curl -X POST 'https://api.blooio.com/v2/api/chats/%2B15551234567/contact-card' \
  -H 'Authorization: Bearer YOUR_API_KEY'

# Step 2: Send a message — the contact card automatically piggybacks on it
curl -X POST 'https://api.blooio.com/v2/api/chats/%2B15551234567/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"text": "Hi there!"}'
Try it

Option 2: Flag on send-message (one call)

Include share_contact: true when sending a message to do both in one request:

curl -X POST 'https://api.blooio.com/v2/api/chats/%2B15551234567/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"text": "Hi there!", "share_contact": true}'
Try it

This also works with attachments:

{
  "text": "Check this out",
  "attachments": ["https://example.com/photo.jpg"],
  "share_contact": true
}

Warning

The contact card is only sent once per chat. Apple tracks who has received your card, so calling the share endpoint or flag multiple times is harmless but redundant.

How sharing works

Name & Photo sharing is staged before it is attached to the next outgoing message:

  1. When you call the share endpoint, the share flow stages permission to share with that chat's participants
  2. The next outgoing message (text or attachment) automatically carries the contact card data
  3. The recipient's Messages app receives and displays your name and photo

This is the same mechanism as tapping "Share" on the Name & Photo banner in the Messages app.

Sharing settings reference

Setting Values Description
sharing.enabled true / false Master toggle for Name & Photo sharing
sharing.audience 0 Contacts Only — auto-share with people in your contacts
sharing.audience 1 Always Ask — show a prompt before sharing (default for API use)
sharing.name_format 0 Share first name and last name
sharing.name_format 1 Share first name only