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

Location tracking (FindMy)

How to track the real-time location of contacts who share their location via Apple FindMy

This guide covers using the Location API to access FindMy friend locations available through your blooio account. You can list all contacts sharing their location, fetch a specific contact's location, and trigger a refresh to get the latest coordinates.

Overview

Apple's FindMy app lets users share their real-time location with friends and family. The Location API exposes this data through three endpoints:

  1. List contacts — Get all contacts currently sharing their location
  2. Get contact — Get a specific contact's location by phone number or email
  3. Refresh — Trigger a refresh to fetch updated locations

Note

Location data comes from Apple's FindMy service. Contacts only appear here if they have already shared their location through FindMy. This is the same person-sharing data surfaced by Apple's FindMy experience.

Prerequisites

  • Location access must be provisioned for your blooio service
  • Contacts must already be sharing their location through FindMy

Listing all contact locations

Retrieve cached locations for all contacts sharing their location:

cURL

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

Node.js

const res = await fetch('https://api.blooio.com/v2/api/location/contacts', {
  headers: { 'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}` }
})
const { friends } = await res.json()
console.log(friends)
// [{ handle: "+15551234567", coordinates: [37.7749, -122.4194], status: "live", last_updated: 1709... }]

Python


res = requests.get('https://api.blooio.com/v2/api/location/contacts',
  headers={'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}"}
)
friends = res.json()['friends']
for friend in friends:
    print(f"{friend['handle']}: {friend['coordinates']}")

Getting a specific contact's location

Look up a single contact by their phone number or email:

cURL

curl 'https://api.blooio.com/v2/api/location/contacts/%2B15551234567' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Try it

Node.js

const handle = encodeURIComponent('+15551234567')
const res = await fetch(`https://api.blooio.com/v2/api/location/contacts/${handle}`, {
  headers: { 'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}` }
})
const location = await res.json()
// { handle: "+15551234567", coordinates: [37.7749, -122.4194], status: "live", last_updated: 1709... }

Python

from urllib.parse import quote

handle = quote('+15551234567', safe='')
res = requests.get(f'https://api.blooio.com/v2/api/location/contacts/{handle}',
  headers={'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}"}
)
location = res.json()

Returns 404 if the contact is not sharing their location or isn't in the cache.

Refreshing locations

Location data is cached. To get the latest coordinates, trigger a refresh:

cURL

curl -X POST 'https://api.blooio.com/v2/api/location/contacts/refresh' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Try it

Node.js

const res = await fetch('https://api.blooio.com/v2/api/location/contacts/refresh', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}` }
})
const { friends } = await res.json()

Python

res = requests.post('https://api.blooio.com/v2/api/location/contacts/refresh',
  headers={'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}"}
)
friends = res.json()['friends']

Warning

Refreshing locations typically takes 15-20 seconds. The endpoint returns immediately with the current cache, but the latest location data may take a moment to update. For the freshest data, call refresh, wait ~20 seconds, then list contacts.

Response fields

Field Type Description
handle string Contact's phone number or email address
coordinates number[] GPS coordinates as [latitude, longitude]
status string Location freshness (see below)
last_updated integer Timestamp of last location update (epoch milliseconds)

Location status values

Status Meaning
live Real-time location sharing is active — coordinates are current
shallow Cached location from a recent session — may be minutes old
legacy Older cached data — location may be hours or days stale

Common patterns

Polling for location updates

If you need periodic location tracking, call refresh on an interval and list contacts afterward:

async function trackLocations(apiKey, intervalMs = 60000) {
  const headers = { 'Authorization': `Bearer ${apiKey}` }
  const base = 'https://api.blooio.com/v2/api'

  setInterval(async () => {
    await fetch(`${base}/location/contacts/refresh`, { method: 'POST', headers })

    // Wait for the refresh to complete
    await new Promise(r => setTimeout(r, 20000))

    const res = await fetch(`${base}/location/contacts`, { headers })
    const { friends } = await res.json()

    for (const f of friends) {
      console.log(`${f.handle}: [${f.coordinates}] (${f.status})`)
    }
  }, intervalMs)
}

Note

Avoid refreshing more frequently than once per minute. Refreshes consume resources and can take a short time to propagate. For most use cases, refreshing every 5-10 minutes is sufficient.