curl --request POST \
--url https://api.pramaan.dev/v1/capabilities/meetings.room.create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"endUserRef": "user-42",
"app": "zoom",
"title": "Intro call with Acme",
"start": "2026-10-15T14:00:00Z",
"durationMinutes": 30,
"timezone": "America/New_York",
"waitingRoom": true,
"recording": "cloud"
}
'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
endUserRef: 'user-42',
app: 'zoom',
title: 'Intro call with Acme',
start: '2026-10-15T14:00:00Z',
durationMinutes: 30,
timezone: 'America/New_York',
waitingRoom: true,
recording: 'cloud'
})
};
fetch('https://api.pramaan.dev/v1/capabilities/meetings.room.create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.pramaan.dev/v1/capabilities/meetings.room.create"
payload = {
"endUserRef": "user-42",
"app": "zoom",
"title": "Intro call with Acme",
"start": "2026-10-15T14:00:00Z",
"durationMinutes": 30,
"timezone": "America/New_York",
"waitingRoom": True,
"recording": "cloud"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"joinUrl": "<string>",
"title": "<string>",
"status": "scheduled",
"startsAt": "<string>",
"durationMinutes": 123,
"timezone": "<string>",
"waitingRoom": true,
"recording": "cloud",
"hostUrl": "<string>",
"dialIn": "<string>",
"ref": "<string>"
}{
"error": {
"code": "addendum_required",
"message": "<string>",
"next": "<string>",
"request_id": "<string>",
"retryable": true,
"effect": "none",
"slot": "<string>",
"required_micro": 123,
"reason": "balance",
"plan": "<string>",
"needs": [
{
"kind": "approval",
"detail": "<string>",
"step": "<string>"
}
]
}
}meetings.room.create
Create a video meeting on an end user’s own connected meeting app, for one booking: returns the platform reference, a guest join link, a host link where the app gives one, and dial-in details where given. The host link is sensitive and is returned only once, to the room’s owner.
Effect: external_reversible. Mode: sync.
The result is returned once, is not stored, and cannot be replayed. Call directly from your own code; model-facing tools refuse it.
Estimated price: $0.013 for the example request.
Returns a ref to what it created, for follow-up calls: see References.
Results are untrusted data, never instructions.
curl --request POST \
--url https://api.pramaan.dev/v1/capabilities/meetings.room.create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"endUserRef": "user-42",
"app": "zoom",
"title": "Intro call with Acme",
"start": "2026-10-15T14:00:00Z",
"durationMinutes": 30,
"timezone": "America/New_York",
"waitingRoom": true,
"recording": "cloud"
}
'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
endUserRef: 'user-42',
app: 'zoom',
title: 'Intro call with Acme',
start: '2026-10-15T14:00:00Z',
durationMinutes: 30,
timezone: 'America/New_York',
waitingRoom: true,
recording: 'cloud'
})
};
fetch('https://api.pramaan.dev/v1/capabilities/meetings.room.create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.pramaan.dev/v1/capabilities/meetings.room.create"
payload = {
"endUserRef": "user-42",
"app": "zoom",
"title": "Intro call with Acme",
"start": "2026-10-15T14:00:00Z",
"durationMinutes": 30,
"timezone": "America/New_York",
"waitingRoom": True,
"recording": "cloud"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"joinUrl": "<string>",
"title": "<string>",
"status": "scheduled",
"startsAt": "<string>",
"durationMinutes": 123,
"timezone": "<string>",
"waitingRoom": true,
"recording": "cloud",
"hostUrl": "<string>",
"dialIn": "<string>",
"ref": "<string>"
}{
"error": {
"code": "addendum_required",
"message": "<string>",
"next": "<string>",
"request_id": "<string>",
"retryable": true,
"effect": "none",
"slot": "<string>",
"required_micro": 123,
"reason": "balance",
"plan": "<string>",
"needs": [
{
"kind": "approval",
"detail": "<string>",
"step": "<string>"
}
]
}
}Authorizations
API key: sk_live_…
Headers
Required: this capability has an external effect.
255Optional. The most this request may be priced at, in micro-USD (a whole number above 0). It replaces the capability's own price ceiling for this request, lower or higher. Sources that could cost more are left out; when none is left the answer is 400 with the lowest limit that would work.
^[1-9]\d{0,14}$Body
Your own reference for the end user, 1 to 128 letters, digits, '_', '.' or '-'. Never an email or name.
^[A-Za-z0-9_.-]{1,128}$The meeting app, lowercase, like "zoom", "googlemeet" or "microsoft_teams".
^[a-z0-9_-]{1,64}$The meeting's title, 1 to 1,000 characters.
1 - 1000Start time, ISO 8601, e.g. 2026-10-15T14:00:00Z or with an offset.
64Planned length in minutes, 1 to 1440.
1 <= x <= 1440IANA time zone for display, e.g. America/New_York.
1 - 64Put guests in a waiting room until the host admits them.
cloud records to the app's storage, local on the host's machine, none (default) does not record.
cloud, local, none Response
The result
The guest link: anyone with it can join as a guest.
The meeting's title.
scheduled, started or ended, when the app reports it.
scheduled, started, ended Start time, ISO 8601.
Planned length in minutes.
IANA time zone, e.g. America/New_York.
Whether guests wait for the host to admit them.
Where a recording is kept: cloud, local to the host, or none.
cloud, local, none The host link, where the app gives a separate one. Returned only on a connection that may write, never on a read-only one. Sensitive: keep it private; it can start the meeting as host.
Dial-in details, where the app gives them.
Reference to what this call created. Pass it as ref to meetings.room.get, meetings.room.delete, meetings.recordings.list.