MisarMisar Docs
MisarMailMisarBlogMisarReachMisarPostMisarDevMisarCoderMisarSEOMisar PlatformMisar SSO
SDKs

Dart SDK

Publish articles, manage series, and run AI tools with the MisarBlog Dart SDK, plus post-embed helpers.

The Dart SDK ships a full client for the developer API (https://api.misar.io/blog/v1) plus the iframe embed helpers, in the misarblog_sdk package (v1.0.0). For Flutter apps, the misarblog_flutter package adds secure key storage and an embed widget on top of this client.

Installation

Add to pubspec.yaml, then run dart pub get:

dependencies:
  misarblog_sdk: ^1.0.0

API Client

MisarBlogClient authenticates with an mbk_ key (or an OAuth 2.1 access token) and defaults to https://api.misar.io/blog/v1 (the gateway strips /api). Resource methods return typed model objects. Retryable statuses (429, 500, 502, 503, 504) are retried with exponential back-off. Call close() when you are done.

import 'package:misarblog_sdk/misarblog.dart';

final blog = MisarBlogClient(apiKey: 'mbk_YOUR_KEY');

// Override the base URL if needed
final staging = MisarBlogClient(
  apiKey: 'mbk_YOUR_KEY',
  baseUrl: 'https://api.misar.io/blog/v1',
);

Articles

// List your articles
final result = await blog.articles.list(status: 'published', limit: 20);
for (final a in result.articles) {
  print('${a.title} ${a.url}');
}

// Get one by slug (or UUID)
final article = await blog.articles.get('my-first-article');

// Publish
final created = await blog.articles.publish(
  title: 'Getting Started with the MisarBlog API',
  bodyMarkdown: '## Introduction\n\nThis guide covers…',
  tags: ['dart', 'api'],
  coverImageUrl: 'https://example.com/cover.jpg',
  visibility: 'public',
);

// Save a draft, then update / publish it
final draft = await blog.articles.createDraft(title: 'Work in progress', bodyMarkdown: '## Soon…');
await blog.articles.update(draft.slug, publish: true);

Other resources

await blog.series.list();
await blog.series.create(title: 'A Series', description: 'Optional');

await blog.ai.titles(action: 'seo', prompt: 'best AI writing tools 2026');
await blog.ai.complete(prompt: 'Tighten this intro: …', system: 'You are an editor.', maxTokens: 300);

await blog.images.generate(prompt: 'A minimalist cover', size: '1792x1024');

await blog.articles.search(q: 'react', type: 'articles', sort: 'newest');
await blog.articles.recommendations(articleId: articleId, limit: 5);

await blog.analytics.get(days: 30);
await blog.account.profile();      // GET /me
await blog.account.plan();
await blog.account.trialStatus();

await blog.reactions.get(articleId);
await blog.reactions.add(articleId: articleId, type: 'like');     // "like" | "clap" | "bookmark"
await blog.reactions.remove(articleId: articleId, type: 'like');

blog.close();

Resources

ResourceMethods
blog.articleslist · get · publish · update · createDraft · search · recommendations
blog.serieslist · create · addArticle
blog.aititles · complete
blog.imagesgenerate · upload
blog.analyticsget
blog.accountprofile (GET /me) · plan · trialStatus · startTrial · upsellFunnel
blog.reactionsget · add · remove

Error handling

try {
  await blog.articles.get('missing-slug');
} on MisarBlogError catch (err) {
  print('${err.status} ${err.message}');   // err.body carries the parsed response
}

MisarBlogNetworkError is thrown when the request never completes or retries are exhausted.

Embed helpers

The no-key iframe helpers are top-level functions:

import 'package:misarblog_sdk/misarblog.dart';

// Profile embed
final url = embedUrl('johndoe');

// Single-post embed with a theme
final postUrl = embedUrl('johndoe', slug: 'my-first-post', theme: 'dark');

// For gated (paywalled) embeds, refresh the session token
final result = await refreshToken('current-session-token');
print('${result.token} ${result.expiresAt}');

embedUrl(String username, {String? slug, String theme = "auto"}) -> String returns a public embed-viewer URL. Future<TokenResult> refreshToken(String token, {String baseUrl = "https://misar.blog"}) returns a TokenResult(token, expiresAt), or throws on a non-200 response.

For an in-app embed widget, see the Flutter SDK.