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

FaceTime calls

How to initiate FaceTime calls programmatically and get shareable links

Warning

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.

Note

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

curl -X POST 'https://api.blooio.com/v2/api/facetime/calls' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"handle": "+15551234567"}'
Try it

Node.js

const res = await fetch('https://api.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=..."

Python


res = requests.post('https://api.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://api.blooio.com/v2/api/facetime/calls' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"handle": "john@example.com"}'
Try it

Response fields

Field Type Description
success boolean Whether the call was initiated
link string Shareable FaceTime link (https://facetime.apple.com/join#...)
handle string The 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.

Warning

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

Status Meaning
200 Call initiated, link returned
400 Missing or invalid handle field
401 Invalid or missing API key
404 No active number is available for this API key
502 FaceTime 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://api.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)
})