通过托管 OAuth 代理访问 Fathom API,获取会议录像、转写、摘要并管理 Webhook。
集成
Fireflies.ai
试用通过托管 OAuth 代理调用 Fireflies.ai GraphQL 接口访问会议数据。
它能做什么
通过 Maton 代理端点,以 Bearer API Key 方式接入 Fireflies.ai 的 GraphQL API。可读取会议转写及其摘要、句子与参与者信息,也可查询用户、联系人、频道、Bites、进行中会议,以及 AskFred 自然语言对话线程。变更类操作覆盖上传音频、修改会议标题/隐私/频道、设置用户角色、创建 Bite、管理 AskFred 对话,以及实时会议状态控制。所有写入操作在执行前都需要用户明确确认。
什么时候用它
- 按会议 ID 拉取转写文本与 AI 摘要
- 使用 limit/skip 翻页列出近期转写
- 用 AskFred 对会议内容进行自然语言提问
- 上传音频或修改会议元数据(需先经用户确认)
技能文档
Fireflies
Access the Fireflies.ai GraphQL API with managed OAuth authentication. Retrieve meeting transcripts, summaries, users, contacts, channels, and use AI-powered meeting analysis with AskFred.
Quick Start
# Get current user
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': '{ user { user_id name email is_admin } }'}).encode()
req = urllib.request.Request('https://api.maton.ai/fireflies/graphql', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://api.maton.ai/fireflies/graphql
All requests are sent to a single GraphQL endpoint. Maton proxies requests to api.fireflies.ai/graphql and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Fireflies OAuth connections at https://api.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=fireflies&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'fireflies'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-11T00:45:25.802991Z",
"last_updated_time": "2026-02-11T00:46:04.771700Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "fireflies",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Fireflies connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': '{ user { user_id name email } }'}).encode()
req = urllib.request.Request('https://api.maton.ai/fireflies/graphql', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to meeting transcripts, notes, users, and audio recordings within the connected Fireflies account.
- All write operations require explicit user approval. Before executing any create, update, or delete mutation, confirm the target resource and intended effect with the user.
GraphQL API
Fireflies uses GraphQL, which means all requests are POST requests to a single /graphql endpoint with a JSON body containing the query.
Request Format
POST /fireflies/graphql
Content-Type: application/json
{
"query": "{ ... }",
"variables": { ... }
}
Queries
Get Current User
{
user {
user_id
name
email
is_admin
num_transcripts
minutes_consumed
recent_transcript
recent_meeting
}
}
Response:
{
"data": {
"user": {
"user_id": "01KH5131Z0W4TS7BBSEP66CV6V",
"name": "John Doe",
"email": "john@example.com",
"is_admin": true,
"num_transcripts": null,
"minutes_consumed": 0
}
}
}
List Users
{
users {
user_id
name
email
is_admin
num_transcripts
minutes_consumed
}
}
List Transcripts
{
transcripts {
id
title
date
duration
host_email
organizer_email
privacy
transcript_url
audio_url
video_url
dateString
calendar_type
meeting_link
}
}
With Variables (filtering):
{
"query": "query($limit: Int, $skip: Int) { transcripts(limit: $limit, skip: $skip) { id title date duration } }",
"variables": {
"limit": 10,
"skip": 0
}
}
Get Transcript by ID
query($id: String!) {
transcript(id: $id) {
id
title
date
duration
host_email
privacy
transcript_url
audio_url
summary {
overview
short_summary
action_items
outline
keywords
meeting_type
}
sentences {
text
speaker_name
start_time
end_time
}
participants
speakers {
name
}
}
}
List Channels
{
channels {
id
title
created_at
updated_at
is_private
created_by
}
}
Get Channel by ID
query($id: String!) {
channel(id: $id) {
id
title
created_at
is_private
members
}
}
List Contacts
{
contacts {
email
name
picture
last_meeting_date
}
}
List User Groups
{
user_groups {
id
name
}
}
List Bites (Soundbites)
{
bites {
id
name
transcript_id
thumbnail
preview
status
summary
start_time
end_time
media_type
created_at
}
}
Get Bite by ID
query($id: String!) {
bite(id: $id) {
id
name
transcript_id
summary
start_time
end_time
captions
}
}
List Active Meetings
{
active_meetings {
id
title
date
}
}
AskFred Threads
Query meeting content using AI.
List Threads:
{
askfred_threads {
id
title
created_at
}
}
Get Thread by ID:
query($id: String!) {
askfred_thread(id: $id) {
id
title
messages {
content
role
}
}
}
Mutations
Upload Audio
mutation($input: AudioUploadInput!) {
uploadAudio(input: $input) {
success
title
message
}
}
Variables:
{
"input": {
"url": "https://example.com/audio.mp3",
"title": "Meeting Recording"
}
}
Delete Transcript
mutation($id: String!) {
deleteTranscript(id: $id) {
success
message
}
}
Update Meeting Title
mutation($id: String!, $title: String!) {
updateMeetingTitle(id: $id, title: $title) {
success
}
}
Update Meeting Privacy
mutation($id: String!, $privacy: String!) {
updateMeetingPrivacy(id: $id, privacy: $privacy) {
success
}
}
Update Meeting Channel
mutation($id: String!, $channelId: String!) {
updateMeetingChannel(id: $id, channelId: $channelId) {
success
}
}
Set User Role
mutation($userId: String!, $role: String!) {
setUserRole(userId: $userId, role: $role) {
success
}
}
Create Bite
mutation($input: CreateBiteInput!) {
createBite(input: $input) {
id
name
}
}
AskFred Mutations
Create Thread:
mutation($input: CreateAskFredThreadInput!) {
createAskFredThread(input: $input) {
id
title
}
}
Continue Thread:
mutation($id: String!, $question: String!) {
continueAskFredThread(id: $id, question: $question) {
id
messages {
content
role
}
}
}
Delete Thread:
mutation($id: String!) {
deleteAskFredThread(id: $id) {
success
}
}
Live Meeting Mutations
Update Meeting State (pause/resume):
mutation($id: String!, $state: String!) {
updateMeetingState(id: $id, state: $state) {
success
}
}
Create Live Action Item:
mutation($meetingId: String!, $text: String!) {
createLiveActionItem(meetingId: $meetingId, text: $text) {
success
}
}
Create Live Soundbite:
mutation($meetingId: String!, $name: String!) {
createLiveSoundbite(meetingId: $meetingId, name: $name) {
success
}
}
Add Bot to Live Meeting:
mutation($meetingLink: String!) {
addToLiveMeeting(meetingLink: $meetingLink) {
success
}
}
Code Examples
JavaScript
const query = `{
user {
user_id
name
email
}
}`;
const response = await fetch(
'https://api.maton.ai/fireflies/graphql',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ query })
}
);
const data = await response.json();
console.log(data.data.user);
Python
import os
import requests
query = '''
{
transcripts {
id
title
date
duration
}
}
'''
response = requests.post(
'https://api.maton.ai/fireflies/graphql',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={'query': query}
)
data = response.json()
for transcript in data['data']['transcripts']:
print(f"{transcript['title']}: {transcript['duration']}s")
Notes
- Fireflies uses GraphQL, not REST - all requests are POST to
/graphql - User IDs are ULIDs (e.g.,
01KH5131Z0W4TS7BBSEP66CV6V) - Timestamps are Unix timestamps (milliseconds)
- The
summaryfield on transcripts contains AI-generated content: overview, action_items, outline, keywords - AskFred allows natural language queries across meeting transcripts
- Rate limits: 50 API calls/day on free plan, more on Business plan
- IMPORTANT: All GraphQL queries and mutations must be sent as POST requests with Content-Type: application/json
- IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Invalid GraphQL query or missing connection |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions |
| 429 | Rate limited |
| 500 | Internal server error |
GraphQL Errors:
{
"errors": [
{
"message": "Cannot query field \"id\" on type \"User\".",
"code": "GRAPHQL_VALIDATION_FAILED"
}
]
}
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
fireflies. For example:
- Correct:
https://api.maton.ai/fireflies/graphql - Incorrect:
https://api.maton.ai/graphql
Resources
相关技能
通过 MCP 用自然语言查询 Granola 会议记录、列出会议、获取详情和原始转录,鉴权由 Maton API Key 自动管理。
通过托管认证调用 Firecrawl API,提供网页抓取、整站爬取、URL 发现和带正文内容的搜索能力。
通过 OAuth 网关调度与管理 Zoom 会议、研讨会与云录制。
通过 OAuth 鉴权的 API 调用,管理 Front 的会话、消息、联系人、标签、收件箱、队友和团队。
通过托管 OAuth 网关读写 Calendly 排程数据。