Install
openclaw skills install fireflies-apiFireflies.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.
openclaw skills install fireflies-apiAccess the Fireflies.ai GraphQL API with managed OAuth authentication. Retrieve meeting transcripts, summaries, users, contacts, channels, and use AI-powered meeting analysis with AskFred.
# 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
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.
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"
Manage your Fireflies OAuth connections at https://api.maton.ai.
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
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
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.
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
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.
Fireflies uses GraphQL, which means all requests are POST requests to a single /graphql endpoint with a JSON body containing the query.
POST /fireflies/graphql
Content-Type: application/json
{
"query": "{ ... }",
"variables": { ... }
}
{
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
}
}
}
{
users {
user_id
name
email
is_admin
num_transcripts
minutes_consumed
}
}
{
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
}
}
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
}
}
}
{
channels {
id
title
created_at
updated_at
is_private
created_by
}
}
query($id: String!) {
channel(id: $id) {
id
title
created_at
is_private
members
}
}
{
contacts {
email
name
picture
last_meeting_date
}
}
{
user_groups {
id
name
}
}
{
bites {
id
name
transcript_id
thumbnail
preview
status
summary
start_time
end_time
media_type
created_at
}
}
query($id: String!) {
bite(id: $id) {
id
name
transcript_id
summary
start_time
end_time
captions
}
}
{
active_meetings {
id
title
date
}
}
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
}
}
}
mutation($input: AudioUploadInput!) {
uploadAudio(input: $input) {
success
title
message
}
}
Variables:
{
"input": {
"url": "https://example.com/audio.mp3",
"title": "Meeting Recording"
}
}
mutation($id: String!) {
deleteTranscript(id: $id) {
success
message
}
}
mutation($id: String!, $title: String!) {
updateMeetingTitle(id: $id, title: $title) {
success
}
}
mutation($id: String!, $privacy: String!) {
updateMeetingPrivacy(id: $id, privacy: $privacy) {
success
}
}
mutation($id: String!, $channelId: String!) {
updateMeetingChannel(id: $id, channelId: $channelId) {
success
}
}
mutation($userId: String!, $role: String!) {
setUserRole(userId: $userId, role: $role) {
success
}
}
mutation($input: CreateBiteInput!) {
createBite(input: $input) {
id
name
}
}
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
}
}
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
}
}
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);
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")
/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| 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"
}
]
}
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
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
fireflies. For example:https://api.maton.ai/fireflies/graphqlhttps://api.maton.ai/graphql