PHP SDK
Publish articles, manage series, and run AI tools with the MisarBlog PHP SDK, plus post-embed helpers.
The PHP 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).
Installation
composer require misarblog/sdkAPI Client
MisarBlog\Client 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). Every method returns the decoded response as an array. Retryable statuses (429, 500, 502, 503, 504) are retried with exponential back-off.
use MisarBlog\Client;
$blog = new Client('mbk_YOUR_KEY');
// Override the base URL if needed
$staging = new Client('mbk_YOUR_KEY', 'https://api.misar.io/blog/v1');Articles
// List your articles
$result = $blog->articles->list(['status' => 'published', 'limit' => 20]);
foreach ($result['articles'] as $a) {
echo $a['title'], ' ', $a['url'], PHP_EOL;
}
// Get one by slug (or UUID)
$article = $blog->articles->get('my-first-article');
// Publish
$created = $blog->articles->publish([
'title' => 'Getting Started with the MisarBlog API',
'body_markdown' => "## Introduction\n\nThis guide covers…",
'tags' => ['php', 'api'],
'cover_image_url' => 'https://example.com/cover.jpg',
'visibility' => 'public',
]);
// Save a draft, then update / publish it
$draft = $blog->articles->createDraft([
'title' => 'Work in progress', 'body_markdown' => '## Soon…',
]);
$blog->articles->update($draft['slug'], ['publish' => true]);Other resources
$blog->series->list();
$blog->series->create('A Series', 'Optional');
$blog->ai->titles('seo', 'best AI writing tools 2026');
$blog->ai->complete('Tighten this intro: …', 'You are an editor.', 300);
$blog->images->generate('A minimalist cover', '1792x1024');
$blog->search->query(['q' => 'react', 'type' => 'articles', 'sort' => 'newest']);
$blog->recommendations->get($articleId, 5);
$blog->analytics->get(30);
$blog->profile->get(); // GET /me
$blog->plan->get();
$blog->trial->status();
$blog->reactions->get($articleId);
$blog->reactions->add($articleId, 'like'); // "like" | "clap" | "bookmark"
$blog->reactions->remove($articleId, 'like');Resources
| Resource | Methods |
|---|---|
$blog->articles | list · get · publish · update · createDraft |
$blog->series | list · create · addArticle |
$blog->ai | titles · complete |
$blog->images | generate · upload |
$blog->search | query |
$blog->recommendations | get |
$blog->analytics | get |
$blog->profile | get — GET /me |
$blog->plan | get |
$blog->trial | status · start |
$blog->reactions | get · add · remove |
$blog->upsell | funnel — platform-admin only |
Error handling
use MisarBlog\ApiError;
try {
$blog->articles->get('missing-slug');
} catch (ApiError $err) {
echo $err->status, ' ', $err->getMessage(); // + $err->requiredScope / $err->grantedScopes on 403
}MisarBlog\NetworkError (an ApiError with status === 0) is thrown when the request never completes or retries are exhausted.
Embed helpers
The no-key iframe helpers are static:
use MisarBlog\Embed;
use MisarBlog\Auth;
// Profile embed
$url = Embed::url('johndoe');
// Single-post embed with a theme
$postUrl = Embed::url('johndoe', 'my-first-post', 'dark');
// For gated (paywalled) embeds, refresh the session token
$result = Auth::refreshToken('current-session-token');
echo $result['token'], ' ', $result['expiresAt'];MisarBlog\Embed::url(string $username, ?string $slug = null, string $theme = 'auto'): string returns a public embed-viewer URL. MisarBlog\Auth::refreshToken(string $token, string $baseUrl = 'https://misar.blog'): array returns the new token payload, or throws \RuntimeException on a non-200 response.