Blooio API Reference

FaceTime calls

How to initiate FaceTime calls programmatically and get shareable links

Coming Soon -- The FaceTime API is temporarily disabled while we stabilize the call flow. The endpoint will return 501 until it is re-enabled. The documentation below describes the intended behavior.

This guide covers using the FaceTime API to initiate calls and obtain shareable FaceTime links.

Overview

The FaceTime API lets you programmatically call a contact and receive a shareable facetime.apple.com link. When you initiate a call:

  1. A FaceTime link is generated
  2. The target contact is rung via FaceTime Audio
  3. The first person who joins via the link is auto-admitted
  4. The call ends after the participant connects

The result is a shareable link that can be embedded in a web page, sent in a notification, or used in any workflow.

When this endpoint is re-enabled, you can initiate calls directly through the API without any separate setup flow.

Initiating a call

Call a contact by phone number or email address:

curl -X POST 'https://backend.blooio.com/v2/api/facetime/calls' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"handle": "+15551234567"}'
const res = await fetch('https://backend.blooio.com/v2/api/facetime/calls', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ handle: '+15551234567' })
})
const { link } = await res.json()
console.log(link)
// "https://facetime.apple.com/join#v=1&p=..."
import os, requests

res = requests.post('https://backend.blooio.com/v2/api/facetime/calls',
  headers={
    'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}",
    'Content-Type': 'application/json'
  },
  json={'handle': '+15551234567'}
)
link = res.json()['link']

You can also call by email:

curl -X POST 'https://backend.blooio.com/v2/api/facetime/calls' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"handle": "john@example.com"}'

Response fields

FieldTypeDescription
successbooleanWhether the call was initiated
linkstringShareable FaceTime link (https://facetime.apple.com/join#...)
handlestringThe phone number or email that was called

How the call flow works

When you call the endpoint, the call flow performs three steps:

  1. Generate link — Creates a shareable FaceTime link
  2. Ring contact — Initiates a FaceTime Audio call to the target handle (async, doesn't block the response)
  3. Auto-admit — Monitors the call's waiting room and automatically admits the first person who joins via the link, then the call ends

The link is returned immediately after step 1. Steps 2 and 3 happen in the background.

The auto-admit process monitors the call for up to 2 minutes. If no one joins via the link within that window, the call ends automatically. The link itself remains valid for up to 3 hours.

Error handling

StatusMeaning
200Call initiated, link returned
400Missing or invalid handle field
401Invalid or missing API key
404No active number is available for this API key
502FaceTime link generation failed (for example, if FaceTime is unavailable)

Common patterns

const { link } = await initiateFaceTimeCall(handle)

await sendPushNotification(userId, {
  title: 'Join the call',
  body: 'Tap to join the FaceTime call',
  url: link
})

Webhook-triggered calls

Combine with webhooks to auto-call when a specific event occurs:

app.post('/webhook', async (req, res) => {
  const event = req.body

  if (event.type === 'message.received' && event.data.text === 'CALL ME') {
    const sender = event.data.from
    const callRes = await fetch('https://backend.blooio.com/v2/api/facetime/calls', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ handle: sender })
    })
    const { link } = await callRes.json()
    console.log(`Call initiated: ${link}`)
  }

  res.sendStatus(200)
})

On this page