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:
- A FaceTime link is generated
- The target contact is rung via FaceTime Audio
- The first person who joins via the link is auto-admitted
- 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
| 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:
- Generate link — Creates a shareable FaceTime link
- Ring contact — Initiates a FaceTime Audio call to the target handle (async, doesn't block the response)
- 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
| 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
Embedding a FaceTime link in a notification
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)
})