Fireflies.ai GraphQL API integration with managed OAuth. Access meeting transcripts, summaries, users, contacts, and AI-powered meeting analysis. Use this sk...
---
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
```bash
# 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`:
```bash
export MATON_API_KEY="YOUR_API_KEY"
```
### Getting Your API Key
1. Sign in or create an account at [maton.ai](https://maton.ai)
2. Go to [maton.ai/settings](https://maton.ai/settings)
3. Copy your API key
## Connection Management
Manage your Fireflies OAuth connections at `https://api.maton.ai`.
### List Connections
```bash
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
```bash
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
```bash
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:**
```json
{
"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
```bash
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:
```bash
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
```bash
POST /fireflies/graphql
Content-Type: application/json
{
"query": "{ ... }",
"variables": { ... }
}
```
---
## Queries
### Get Current User
```graphql
{
user {
user_id
name
email
is_admin
num_transcripts
minutes_consumed
recent_transcript
recent_meeting
}
}
```
**Response:**
```json
{
"data": {
"user": {
"user_id": "01KH5131Z0W4TS7BBSEP66CV6V",
"name": "John Doe",
"email": "john@example.com",
"is_admin": true,
"num_transcripts": null,
"minutes_consumed": 0
}
}
}
```
### List Users
```graphql
{
users {
user_id
name
email
is_admin
num_transcripts
minutes_consumed
}
}
```
### List Transcripts
```graphql
{
transcripts {
id
title
date
duration
host_email
organizer_email
privacy
transcript_url
audio_url
video_url
dateString
calendar_type
meeting_link
}
}
```
**With Variables (filtering):**
```json
{
"query": "query($limit: Int, $skip: Int) { transcripts(limit: $limit, skip: $skip) { id title date duration } }",
"variables": {
"limit": 10,
"skip": 0
}
}
```
### Get Transcript by ID
```graphql
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
```graphql
{
channels {
id
title
created_at
updated_at
is_private
created_by
}
}
```
### Get Channel by ID
```graphql
query($id: String!) {
channel(id: $id) {
id
title
created_at
is_private
members
}
}
```
### List Contacts
```graphql
{
contacts {
email
name
picture
last_meeting_date
}
}
```
### List User Groups
```graphql
{
user_groups {
id
name
}
}
```
### List Bites (Soundbites)
```graphql
{
bites {
id
name
transcript_id
thumbnail
preview
status
summary
start_time
end_time
media_type
created_at
}
}
```
### Get Bite by ID
```graphql
query($id: String!) {
bite(id: $id) {
id
name
transcript_id
summary
start_time
end_time
captions
}
}
```
### List Active Meetings
```graphql
{
active_meetings {
id
title
date
}
}
```
### AskFred Threads
Query meeting content using AI.
**List Threads:**
```graphql
{
askfred_threads {
id
title
created_at
}
}
```
**Get Thread by ID:**
```graphql
query($id: String!) {
askfred_thread(id: $id) {
id
title
messages {
content
role
}
}
}
```
---
## Mutations
### Upload Audio
```graphql
mutation($input: AudioUploadInput!) {
uploadAudio(input: $input) {
success
title
message
}
}
```
**Variables:**
```json
{
"input": {
"url": "https://example.com/audio.mp3",
"title": "Meeting Recording"
}
}
```
### Delete Transcript
```graphql
mutation($id: String!) {
deleteTranscript(id: $id) {
success
message
}
}
```
### Update Meeting Title
```graphql
mutation($id: String!, $title: String!) {
updateMeetingTitle(id: $id, title: $title) {
success
}
}
```
### Update Meeting Privacy
```graphql
mutation($id: String!, $privacy: String!) {
updateMeetingPrivacy(id: $id, privacy: $privacy) {
success
}
}
```
### Update Meeting Channel
```graphql
mutation($id: String!, $channelId: String!) {
updateMeetingChannel(id: $id, channelId: $channelId) {
success
}
}
```
### Set User Role
```graphql
mutation($userId: String!, $role: String!) {
setUserRole(userId: $userId, role: $role) {
success
}
}
```
### Create Bite
```graphql
mutation($input: CreateBiteInput!) {
createBite(input: $input) {
id
name
}
}
```
### AskFred Mutations
**Create Thread:**
```graphql
mutation($input: CreateAskFredThreadInput!) {
createAskFredThread(input: $input) {
id
title
}
}
```
**Continue Thread:**
```graphql
mutation($id: String!, $question: String!) {
continueAskFredThread(id: $id, question: $question) {
id
messages {
content
role
}
}
}
```
**Delete Thread:**
```graphql
mutation($id: String!) {
deleteAskFredThread(id: $id) {
success
}
}
```
### Live Meeting Mutations
**Update Meeting State (pause/resume):**
```graphql
mutation($id: String!, $state: String!) {
updateMeetingState(id: $id, state: $state) {
success
}
}
```
**Create Live Action Item:**
```graphql
mutation($meetingId: String!, $text: String!) {
createLiveActionItem(meetingId: $meetingId, text: $text) {
success
}
}
```
**Create Live Soundbite:**
```graphql
mutation($meetingId: String!, $name: String!) {
createLiveSoundbite(meetingId: $meetingId, name: $name) {
success
}
}
```
**Add Bot to Live Meeting:**
```graphql
mutation($meetingLink: String!) {
addToLiveMeeting(meetingLink: $meetingLink) {
success
}
}
```
---
## Code Examples
### JavaScript
```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
```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 `summary` field 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 `jq` or other commands, environment variables like `$MATON_API_KEY` may 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:**
```json
{
"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:
```bash
echo $MATON_API_KEY
```
2. Verify the API key is valid by listing connections:
```bash
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:
- Correct: `https://api.maton.ai/fireflies/graphql`
- Incorrect: `https://api.maton.ai/graphql`
## Resources
- [Fireflies API Documentation](https://docs.fireflies.ai/)
- [Fireflies GraphQL API Reference](https://docs.fireflies.ai/graphql-api)
- [Fireflies Developer Program](https://docs.fireflies.ai/getting-started/developer-program)
- [Maton Community](https://discord.com/invite/dBfFAcefs2)
- [Maton Support](mailto:support@maton.ai)
don't have the plugin yet? install it then click "run inline in claude" again.