octolens
Brand mention tracking across Twitter, Reddit, GitHub, LinkedIn with sentiment analysis.
Installation
npx clawhub@latest install octolensView the full skill documentation and source below.
Documentation
Octolens API Skill
When to use this skill
Use this skill when the user needs to:
- Fetch brand mentions from social media and other platforms
- Filter mentions by source (Twitter, Reddit, GitHub, LinkedIn, YouTube, HackerNews, DevTO, StackOverflow, Bluesky, newsletters, podcasts)
- Analyze sentiment (positive, neutral, negative)
- Filter by author follower count or engagement
- Search for specific keywords or tags
- Query mentions by date range
- List available keywords or saved views
- Apply complex filtering logic with AND/OR conditions
API Authentication
The Octolens API requires a Bearer token for authentication. The user should provide their API key, which you'll use in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Important: Always ask the user for their API key before making any API calls. Store it in a variable for subsequent requests.
Base URL
All API endpoints use the base URL:
## Rate Limits
- **Limit**: 500 requests per hour
- **Check headers**: X-RateLimit- headers indicate current usage
## Available Endpoints
### 1. POST /mentions
Fetch mentions matching keywords with optional filtering. Returns posts sorted by timestamp (newest first).
**Key Parameters:**
- limit (number, 1-100): Maximum results to return (default: 20)
- cursor (string): Pagination cursor from previous response
- includeAll (boolean): Include low-relevance posts (default: false)
- view (number): View ID to use for filtering
- filters (object): Filter criteria (see filtering section)
**Example Response:**
__CODE_BLOCK_1__
### 2. GET /keywords
List all keywords configured for the organization.
**Example Response:**
__CODE_BLOCK_2__
### 3. GET /views
List all saved views (pre-configured filters).
**Example Response:**
__CODE_BLOCK_3__
## Filtering Mentions
The /mentions endpoint supports powerful filtering with two modes:
### Simple Mode (Implicit AND)
Put fields directly in filters. All conditions are ANDed together.
__CODE_BLOCK_4__
→ source IN (twitter, linkedin) AND sentiment = positive AND followers ≥ 1000
### Exclusions
Prefix any array field with ! to exclude values:
__CODE_BLOCK_5__
→ source = twitter AND keyword NOT IN (5, 6)
### Advanced Mode (AND/OR Groups)
Use operator and groups for complex logic:
__CODE_BLOCK_6__
→ (source = twitter OR source = linkedin) AND (sentiment = positive AND tag ≠ spam)
### Available Filter Fields
| Field | Type | Description |
|-------|------|-------------|
| source | string[] | Platforms: twitter, reddit, github, linkedin, youtube, hackernews, devto, stackoverflow, bluesky, newsletter, podcast |
| sentiment | string[] | Values: positive, neutral, negative |
| keyword | string[] | Keyword IDs (get from /keywords endpoint) |
| language | string[] | ISO 639-1 codes: en, es, fr, de, pt, it, nl, ja, ko, zh |
| tag | string[] | Tag names |
| bookmarked | boolean | Filter bookmarked (true) or non-bookmarked (false) posts |
| engaged | boolean | Filter engaged (true) or non-engaged (false) posts |
| minXFollowers | number | Minimum Twitter follower count |
| maxXFollowers | number | Maximum Twitter follower count |
| startDate | string | ISO 8601 format (e.g., "2024-01-15T00:00:00Z") |
| endDate | string | ISO 8601 format |
## Using the Bundled Scripts
This skill includes helper scripts for common operations. Use them to quickly interact with the API:
### Fetch Mentions
__CODE_BLOCK_7__
### List Keywords
__CODE_BLOCK_8__
### List Views
__CODE_BLOCK_9__
### Custom Filter Query
__CODE_BLOCK_10__
### Advanced Query
__CODE_BLOCK_11__
## Best Practices
1. **Always ask for the API key** before making requests
2. **Use views** when possible to leverage pre-configured filters
3. **Start with simple filters** and add complexity as needed
4. **Check rate limits** in response headers (X-RateLimit-)
5. **Use pagination** with cursor for large result sets
6. **Dates must be ISO 8601** format (e.g., "2024-01-15T00:00:00Z")
7. **Get keyword IDs** from /keywords` endpoint before filtering by keyword
Common Use Cases
Find positive Twitter mentions with high followers
{
"limit": 20,
"filters": {
"source": ["twitter"],
"sentiment": ["positive"],
"minXFollowers": 1000
}
}
Exclude spam and get Reddit + GitHub mentions
{
"limit": 50,
"filters": {
"source": ["reddit", "github"],
"!tag": ["spam", "irrelevant"]
}
}
Complex query: (Twitter OR LinkedIn) AND positive sentiment, last 7 days
{
"limit": 30,
"filters": {
"operator": "AND",
"groups": [
{
"operator": "OR",
"conditions": [
{ "source": ["twitter"] },
{ "source": ["linkedin"] }
]
},
{
"operator": "AND",
"conditions": [
{ "sentiment": ["positive"] },
{ "startDate": "2024-01-20T00:00:00Z" }
]
}
]
}
}
Error Handling
| Status | Error | Description |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Valid key but no permission |
| 404 | not_found | Resource (e.g., view ID) not found |
| 429 | rate_limit_exceeded | Too many requests |
| 400 | invalid_request | Malformed request body |
| 500 | internal_error | Server error, retry later |
Step-by-Step Workflow
When a user asks to query Octolens data:
Examples
Example 1: Simple Query
User: "Show me positive mentions from Twitter in the last 7 days"Action (using bundled script):
node scripts/query-mentions.js YOUR_API_KEY '{"source": ["twitter"], "sentiment": ["positive"], "startDate": "2024-01-20T00:00:00Z"}'
Alternative (using fetch API directly):
const response = await fetch('', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
limit: 20,
filters: {
source: ['twitter'],
sentiment: ['positive'],
startDate: '2024-01-20T00:00:00Z',
},
}),
});
const data = await response.json();
Example 2: Advanced Query
User: "Find mentions from Reddit or GitHub, exclude spam tag, with positive or neutral sentiment"Action (using bundled script):
node scripts/query-mentions.js YOUR_API_KEY '{"operator": "AND", "groups": [{"operator": "OR", "conditions": [{"source": ["reddit"]}, {"source": ["github"]}]}, {"operator": "OR", "conditions": [{"sentiment": ["positive"]}, {"sentiment": ["neutral"]}]}, {"operator": "AND", "conditions": [{"!tag": ["spam"]}]}]}'
Alternative (using fetch API directly):
const response = await fetch('', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
limit: 30,
filters: {
operator: 'AND',
groups: [
{
operator: 'OR',
conditions: [
{ source: ['reddit'] },
{ source: ['github'] },
],
},
{
operator: 'OR',
conditions: [
{ sentiment: ['positive'] },
{ sentiment: ['neutral'] },
],
},
{
operator: 'AND',
conditions: [
{ '!tag': ['spam'] },
],
},
],
},
}),
});
const data = await response.json();
Example 3: Get Keywords First
User: "Show mentions for our main product keyword"Actions:
node scripts/list-keywords.js YOUR_API_KEY
node scripts/query-mentions.js YOUR_API_KEY '{"keyword": [1]}'
Tips for Agents
- Use bundled scripts: The Node.js scripts handle JSON parsing automatically
- Cache keywords: After fetching keywords once, remember them for the session
- Explain filters: When using complex filters, explain the logic to the user
- Show examples: When users are unsure, show example filter structures
- Paginate wisely: Ask if user wants more results before fetching next page
- Summarize insights: Don't just dump data, provide analysis (sentiment trends, top authors, platform distribution)