Meetings
curl --request POST \
--url https://win.oneshotagent.com/v1/tools/meetings/listimport requests
url = "https://win.oneshotagent.com/v1/tools/meetings/list"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://win.oneshotagent.com/v1/tools/meetings/list', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://win.oneshotagent.com/v1/tools/meetings/list",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/tools/meetings/list"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/tools/meetings/list")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/tools/meetings/list")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"data.meetings": [
{}
],
"data": {}
}Connections
Meetings
Read meetings, their summaries, action items and transcripts from your connected meeting recorder
POST
/
v1
/
tools
/
meetings
/
list
Meetings
curl --request POST \
--url https://win.oneshotagent.com/v1/tools/meetings/listimport requests
url = "https://win.oneshotagent.com/v1/tools/meetings/list"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://win.oneshotagent.com/v1/tools/meetings/list', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://win.oneshotagent.com/v1/tools/meetings/list",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/tools/meetings/list"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/tools/meetings/list")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/tools/meetings/list")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"data.meetings": [
{}
],
"data": {}
}Overview
Read-only tools on a connected meeting recorder (Connections): Granola and Fireflies. An agent reads what was said and promised in a meeting, for example the follow-ups after a client meeting. No meeting starts a goal; a goal reads meetings when it runs.POST /v1/tools/meetings/list(meetings_list): meetings with title, start, duration and participants.POST /v1/tools/meetings/get(meetings_get): one meeting’s summary and action items, and its transcript when asked for.
connection_id: list your connections (GET /v1/connections or oneshot_connections_list) and pick by system and account_label.
Titles, participants, summaries and transcripts are returned in the answer only; OneShot never stores or logs them. A goal gets them in memory: its history keeps no copy, so a later step reads the meeting again.
Granola and Fireflies
Granola connects with a sign-in. Granola returns the signed-in user’s own notes, notes shared with them and notes in folders shared with the workspace, on Granola plans that allow API access. Transcripts need a paid plan. Granola states local start times without an offset and no duration. Fireflies connects with your Fireflies API key, stored encrypted and deleted on revoke.Request
Paid with x402 (payment-signature). Refusals for the body or the connection come before payment and are not charged.
| Field | Meaning |
|---|---|
connection_id | Required. The connection to read. |
since | List: meetings started on or after this day (YYYY-MM-DD, UTC). |
query | List: title, or a participant’s name or email, contains this text. |
limit, cursor | List: 1 to 100 per page (default 25); cursor is the previous next_cursor. |
meeting_id | Get: required, an id from the list. |
include | Get: any of summary, action_items, transcript; default the first two. |
{ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c", "meeting_id": "0dba4400-0000-4000-8000-000000000001", "include": ["summary", "action_items"] }
Response (200)
array
Each meeting:
id, title, started_at, duration_s, participants (name, email) and source (system, id), with next_cursor (null on the last page). With a query, a page can hold fewer than limit meetings.object
Get: the meeting, plus
summary, action_items (text, owner) and transcript (speaker, text, at in seconds). A part not in include is absent.{
"success": true,
"data": {
"id": "0dba4400-0000-4000-8000-000000000001",
"title": "Client review",
"started_at": "2026-10-20T15:00:00",
"duration_s": null,
"participants": [{ "name": "Sam Lee", "email": "[email protected]" }],
"source": { "system": "granola", "id": "0dba4400-0000-4000-8000-000000000001" },
"summary": "Reviewed the renewal terms.",
"action_items": [{ "text": "Send the revised proposal by Friday", "owner": "Sam Lee" }]
}
}
Errors
| Status | Error | Meaning |
|---|---|---|
| 400 | invalid_request, unsupported_for_system | The body, a cursor or a meeting id is not one the system answered. |
| 400 | connection_wrong_system | Not a meeting recorder. |
| 400 | not_supported | No such meeting, or no Granola transcript on this plan; returned as credit. |
| 404 | connection_not_found | No such connection for this agent. |
| 409 | connection_expired, connection_revoked | Reconnect, or start a new connection. |
| 503 | not_configured, rate_limited, system_unavailable | Not available or busy; a paid call is returned as credit. |