Blooio API Reference

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

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 'https://backend.blooio.com/v2/api/location/contacts' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const res = await fetch('https://backend.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... }]
import os, requests

res = requests.get('https://backend.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 'https://backend.blooio.com/v2/api/location/contacts/%2B15551234567' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const handle = encodeURIComponent('+15551234567')
const res = await fetch(`https://backend.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... }
from urllib.parse import quote

handle = quote('+15551234567', safe='')
res = requests.get(f'https://backend.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 -X POST 'https://backend.blooio.com/v2/api/location/contacts/refresh' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const res = await fetch('https://backend.blooio.com/v2/api/location/contacts/refresh', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}` }
})
const { friends } = await res.json()
res = requests.post('https://backend.blooio.com/v2/api/location/contacts/refresh',
  headers={'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}"}
)
friends = res.json()['friends']

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

FieldTypeDescription
handlestringContact's phone number or email address
coordinatesnumber[]GPS coordinates as [latitude, longitude]
statusstringLocation freshness (see below)
last_updatedintegerTimestamp of last location update (epoch milliseconds)

Location status values

StatusMeaning
liveReal-time location sharing is active — coordinates are current
shallowCached location from a recent session — may be minutes old
legacyOlder 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://backend.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)
}

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.

On this page