Fireflies.ai
by @byungkyu
Fireflies.ai GraphQL API integration with managed OAuth. Access meeting transcripts, summaries, users, contacts, and AI-powered meeting analysis. Use this sk...
clawhub install fireflies-apiπ About This Skill
name: fireflies description: | Fireflies.ai GraphQL API integration with managed OAuth. Access meeting transcripts, summaries, users, contacts, and AI-powered meeting analysis. Use this skill when users want to retrieve meeting transcripts, search conversations, analyze meeting content with AskFred, or manage meeting recordings. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key. metadata: author: maton version: "1.0" clawdbot: emoji: π§ requires: env: - MATON_API_KEY
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
1. Sign in or create an account at maton.ai 2. Go to maton.ai/settings 3. 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
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 requestsquery = '''
{
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
/graphql01KH5131Z0W4TS7BBSEP66CV6V)summary field on transcripts contains AI-generated content: overview, action_items, outline, keywordsjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environmentsError 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
1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
2. 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
1. Ensure your URL path starts with fireflies. For example:
https://api.maton.ai/fireflies/graphqlhttps://api.maton.ai/graphqlResources
π‘ Examples
# 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
π Tips & Best Practices
/graphql01KH5131Z0W4TS7BBSEP66CV6V)summary field on transcripts contains AI-generated content: overview, action_items, outline, keywordsjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments