@blogger-mon/sdk
v1.3.2
Published
TypeScript SDK for BloggerMon API - easy integration for blog management
Maintainers
Readme
BloggerMon SDK
TypeScript SDK for BloggerMon API - easy integration for blog management with full type safety.
Features
- 🚀 Full TypeScript support with comprehensive type definitions
- 🔑 API Key Authentication with scoped permissions
- 📝 Complete CRUD operations for blog posts
- 🔄 Async/await support with proper error handling
- 📊 Comments and Ratings integration
- 🌐 RSS Feed support
- 📋 OpenAPI spec access
- 🤖 AI-powered features: Blog analysis, content refinement, idea generation, and automated workflows
- ⚡ Lightweight with zero dependencies
Installation
npm install @blogger-mon/sdkyarn add @blogger-mon/sdkpnpm add @blogger-mon/sdkQuick Start
1. Get Your API Key
First, create an API key in your BloggerMon dashboard:
- Go to Dashboard → API Keys
- Click "Create API Key"
- Select the scopes you need (
write_posts,upload_media,manage_posts) - Copy the generated key (starts with
bmk_)
2. Initialize the SDK
import { BlogSDK } from '@blogger-mon/sdk';
const blog = new BlogSDK({
apiKey: 'bmk_your_api_key_here'
});
// Optional: override the API host if you're pointing at another environment
// const blog = new BlogSDK({ baseUrl: 'https://custom-api.yourdomain.com', apiKey: 'bmk_custom_key' });
// (Defaults to https://ysqzeskcvmalzhvjyncp.supabase.co)Prefer Python? Install
pip install blogger-mon-sdk-pyand use the companion client inpackages/blogger-mon-python-sdk.
3. Start Using It
// Get all published posts
const { posts, total } = await blog.getPosts({
limit: 10,
offset: 0
});
// Get a single post with comments and ratings
const post = await blog.getPost('post-id');
// Create a new post
const newPost = await blog.createPost({
title: 'My Amazing Blog Post',
content: '# Hello World\n\nThis is my first post!',
status: 'published',
meta_description: 'A great post about...'
});
// Update a post
await blog.updatePost({
id: 'post-id',
title: 'Updated Title',
content: 'Updated content...'
});
// Delete a post
await blog.deletePost('post-id');API Reference
Constructor
new BlogSDK(config: BlogSDKConfig | string)BlogSDKConfig:
baseUrl(string): Optional override for the BloggerMon API (defaults to https://ysqzeskcvmalzhvjyncp.supabase.co)baseUrl(string, optional): Your API base URL (defaults to https://ysqzeskcvmalzhvjyncp.supabase.co)apiKey(string, optional): Your BloggerMon API key
Methods
getPosts(options?: GetPostsOptions): Promise<GetPostsResponse>
Get a list of blog posts.
Options:
limit(number, default: 10): Maximum number of posts to returnoffset(number, default: 0): Number of posts to skipstatus('draft' | 'published', optional): Filter by post status
Returns:
{
posts: Post[];
total: number;
}getPost(postId: string): Promise<PostWithDetails>
Get a single post with comments and ratings.
createPost(data: CreatePostData): Promise<Post>
Create a new blog post. Requires write_posts scope.
CreatePostData:
{
title: string;
content: string;
status?: 'draft' | 'published';
category_id?: string;
meta_description?: string;
featured_image_url?: string;
slug?: string;
}updatePost(data: UpdatePostData): Promise<Post>
Update an existing post. Requires write_posts scope.
deletePost(postId: string): Promise<void>
Delete a post. Requires manage_posts scope.
getRssFeedUrl(): string
Get the URL for the RSS feed.
getOpenApiSpec(): Promise<any>
Fetch the OpenAPI specification for the API.
AI-Powered Features
All AI features require authentication (API key or JWT token).
analyzeBlog(title: string, content: string): Promise<AnalysisResult>
Analyze blog content and get AI-powered improvement suggestions with detailed scores.
Returns:
{
score: number; // Overall quality score (0-100)
readabilityScore: number; // How easy to read (0-100)
seoScore: number; // SEO optimization score (0-100)
structureScore: number; // Content structure score (0-100)
suggestions: string[]; // List of improvement suggestions
}Example:
const analysis = await blog.analyzeBlog(
'My Blog Post Title',
'# Introduction\n\nContent here...'
);
console.log(`Overall Score: ${analysis.score}/100`);
console.log(`SEO Score: ${analysis.seoScore}/100`);
console.log('Suggestions:', analysis.suggestions);generateIdeas(userInput: string, niche?: string): Promise<GenerateIdeasResult>
Generate blog post ideas based on user interests and trending topics.
Parameters:
userInput(string): User interests or topicsniche(string, optional): Specific niche/category
Returns:
{
ideas: Array<{
title: string;
description: string;
targetAudience: string;
keywords: string[];
trending: boolean;
}>;
trendingTopics: string[];
}Example:
const result = await blog.generateIdeas(
'AI and machine learning',
'technology'
);
result.ideas.forEach(idea => {
console.log(`${idea.title} (${idea.trending ? 'Trending' : 'Evergreen'})`);
console.log(`Target: ${idea.targetAudience}`);
console.log(`Keywords: ${idea.keywords.join(', ')}`);
});refineContent(title: string, content: string): Promise<RefineContentResult>
Refine blog content using AI to fix structural issues and improve formatting.
Returns:
{
refinedContent: string; // Improved markdown content
}Example:
const result = await blog.refineContent(
'My Blog Title',
'# My Blog Title\n\n## Section\n\nContent...'
);
console.log('Refined content:', result.refinedContent);runAiWorkflow(options: AiWorkflowOptions): Promise<AiWorkflowResult>
Orchestrate idea generation, drafting, analysis, refinement, and optional publishing in one call. Perfect for automation scripts and back office tools.
Options:
interface AiWorkflowOptions {
userInput: string;
niche?: string;
draftContent?: string;
selectIdea?: (ideas: BlogIdea[]) => BlogIdea | Promise<BlogIdea>;
targetScore?: number; // defaults to 90
forceRefine?: boolean;
autoPublish?: boolean;
publishStatus?: 'draft' | 'published';
}Returns:
interface AiWorkflowResult {
idea: BlogIdea;
ideas: BlogIdea[];
trendingTopics: string[];
initialDraft: string;
finalContent: string;
analysis: AnalysisResult;
refinedContent?: string;
publishedPost?: Post;
}Example:
const workflow = await blog.runAiWorkflow({
userInput: 'AI automation for marketers',
niche: 'Marketing',
targetScore: 92,
autoPublish: true,
publishStatus: 'draft'
});
console.log('Selected idea:', workflow.idea.title);
console.log('Score:', workflow.analysis.score);
console.log('Final draft preview:', workflow.finalContent.slice(0, 200));
if (workflow.publishedPost) {
console.log('New post id:', workflow.publishedPost.id);
}Error Handling
The SDK throws BlogSDKError for API errors:
import { BlogSDK, BlogSDKError } from '@blogger-mon/sdk';
try {
await blog.createPost({ title: '', content: '' }); // Invalid data
} catch (error) {
if (error instanceof BlogSDKError) {
console.log('Status:', error.status); // HTTP status code
console.log('Code:', error.code); // API error code
console.log('Message:', error.message); // Error description
}
}Examples
Blog Integration
import { BlogSDK } from '@blogger-mon/sdk';
const blog = new BlogSDK({
baseUrl: process.env.SUPABASE_URL!,
apiKey: process.env.BLOGGER_MON_API_KEY!
});
// Get recent posts for homepage
async function getRecentPosts() {
const { posts } = await blog.getPosts({
limit: 5,
status: 'published'
});
return posts;
}
// Get post with engagement data
async function getPostWithEngagement(slug: string) {
const post = await blog.getPost(slug);
return {
...post,
commentCount: post.comments.length,
avgRating: post.average_rating
};
}Next.js API Route
// pages/api/posts/index.ts
import { BlogSDK } from '@blogger-mon/sdk';
const blog = new BlogSDK({
baseUrl: process.env.SUPABASE_URL!,
apiKey: process.env.BLOGGER_MON_API_KEY!
});
export default async function handler(req, res) {
if (req.method === 'GET') {
const { limit = 10, offset = 0 } = req.query;
try {
const result = await blog.getPosts({
limit: Number(limit),
offset: Number(offset)
});
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
}CI/CD Integration
// scripts/publish-post.ts
import { BlogSDK } from '@blogger-mon/sdk';
import fs from 'fs';
const blog = new BlogSDK({
baseUrl: process.env.SUPABASE_URL!,
apiKey: process.env.BLOGGER_MON_API_KEY!
});
async function publishMarkdownFile(filePath: string) {
const content = fs.readFileSync(filePath, 'utf-8');
const [, frontmatter, body] = content.split('---');
const meta = parseFrontmatter(frontmatter);
await blog.createPost({
title: meta.title,
content: body.trim(),
status: 'published',
meta_description: meta.description,
slug: meta.slug
});
}Rate Limits
AI-powered features have daily rate limits on the free tier to ensure fair usage:
Free Tier Limits (per user, per day)
| Feature | Daily Limit | Reset Time |
|---------|-------------|------------|
| Content Analysis (analyzeBlog) | 10 requests | Midnight UTC |
| Content Refinement (refineContent) | 5 requests | Midnight UTC |
| Idea Generation (generateIdeas) | 10 requests | Midnight UTC |
Rate Limit Responses
When you exceed a rate limit, the API returns a 429 status code with details:
try {
const analysis = await blog.analyzeBlog(title, content);
} catch (error) {
if (error instanceof BlogSDKError && error.status === 429) {
console.log('Rate limit exceeded');
console.log('Message:', error.message);
// Error contains: limit, current, resetAt
}
}Response format when rate limited:
{
"error": "Daily analysis limit reached",
"message": "You have reached the daily limit of 10 content analyses. Limit resets at midnight UTC.",
"limit": 10,
"current": 10,
"resetAt": "2024-01-02T00:00:00.000Z"
}Best Practices
- Cache results: Store analysis results to avoid redundant API calls
- Batch operations: Analyze multiple pieces of content in a single session
- Handle errors gracefully: Always catch and handle rate limit errors
- Monitor usage: Keep track of your daily API usage to stay within limits
API Scopes
Different operations require different scopes:
- Read operations (getPosts, getPost): No authentication required for published posts
- write_posts: Create and update posts
- upload_media: Upload images and attachments
- manage_posts: Delete posts and manage all content
TypeScript Support
Full TypeScript definitions are included:
import {
BlogSDK,
Post,
CreatePostData,
PostWithDetails,
BlogSDKError,
AnalysisResult,
BlogIdea,
GenerateIdeasResult,
RefineContentResult
} from '@blogger-mon/sdk';
// All types are fully typed and documented
const sdk: BlogSDK = new BlogSDK({
apiKey: 'bmk_key' // baseUrl defaults to https://ysqzeskcvmalzhvjyncp.supabase.co
});
const posts: Post[] = (await sdk.getPosts()).posts;
// Use AI features
const analysis: AnalysisResult = await sdk.analyzeBlog('Title', 'Content');
const ideas: GenerateIdeasResult = await sdk.generateIdeas('AI topics');
const refined: RefineContentResult = await sdk.refineContent('Title', 'Content');License
MIT © BloggerMon
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
