BLURT GUEST GATEWAY · API v1
Guest API integration guide
Integrate guest comments into any BLURT frontend, from account setup through AI moderation, publishing and status tracking.
Polska dokumentacja · Open standalone documentation
1. How it works
Guest Gateway lets visitors comment without owning a BLURT account. Your frontend collects a nickname and comment; your backend sends it to Guest API. Gemini AI performs anti-spam moderation, and a worker publishes approved comments on-chain using a dedicated BLURT guest account's Posting authority.
- Visitor → frontend form
- Backend → authenticated HTTPS Guest API request
- Validation and Gemini moderation, with manual review where needed
- Queue worker → BLURT RPC using the guest account Posting Key
- Frontend → status lookup by comment ID
Each application has its own API key, limits and assigned BLURT guest account. For example, blurt.pl uses @blurtpl-guest; another site can use a completely independent account. The visitor's nickname is shown in the comment, but the on-chain author is the guest account.
2. Getting access and creating an app
- Request access. An administrator invites your BLURT account, grants the manager role, and optionally allows you to add your own guest account.
- Sign in to the blurtplugin.online panel using a BLURT signature (WhaleVault / Blurt Keychain or local Posting Key login if available).
- Create a dedicated BLURT guest account on-chain. In Guest Accounts, register it with its Posting Key (WIF) if permitted. Otherwise an administrator must assign an existing guest account.
- Create an application. Give it a name, select your guest account, configure hourly/daily limits and generate an API key.
- Copy the API key immediately. A secret starting with
ggk_is shown only once; it can be rotated later, not revealed again. - Configure your server and test submission and status retrieval.
3. Credentials and ownership
| Item | Purpose | Storage |
|---|---|---|
| Owner's BLURT name | Panel login and permissions | Public identity |
| Guest BLURT account | On-chain author of guest comments | Dedicated account controlled by its owner |
| Posting Key (WIF) | Signs on-chain comment operations | Secured Guest panel ONLY |
Guest API key ggk_… | Authenticates one application | Your backend only, outside the public webroot |
| Idempotency-Key | Identifies one submission across retries | Persistent backend submission ID |
| visitor_id | Rate-limits an anonymous visitor | Random identifier from your backend, not personal data |
Never submit an Active or Owner Key. A Posting Key can still be abused to publish or incur fees. Use a separate low-balance guest account and keep the ability to rotate its Posting Key.
4. API endpoint and authentication
API base URL:
https://blurtplugin.online/bg-entry.php
Use HTTPS server-to-server calls with Authorization: Bearer ggk_…. Never expose the API key in browser JavaScript. The public API supports POST to submit and GET ?id=… to query status; admin operations are handled only in the authenticated panel.
5. POST — submit a comment
Example request:
POST /bg-entry.php HTTP/1.1
Host: blurtplugin.online
Authorization: Bearer ggk_YOUR_APP_SECRET
Idempotency-Key: frontend:comment-1234567890
Content-Type: application/json
{
"visitor_id": "visitor_8nBL4m9X2qP7v6K1",
"nickname": "Anna",
"body": "Great article!",
"parent_author": "author",
"parent_permlink": "example-post"
}| Field | Validation |
|---|---|
visitor_id | 16–128 characters, letters/digits/_/-; stable anonymous ID, no IP or email |
nickname | 2–50 characters, no angle brackets, controls or line breaks |
body | 2–2500 characters |
parent_author | BLURT author of the post or parent comment |
parent_permlink | Post/comment permlink, up to 255 characters, lowercase letters/digits/dashes |
Idempotency-Key header | 12–120 characters (A-Z a-z 0-9 _ : -); keep unchanged when retrying |
Use Content-Type: application/json. Request body is limited to approximately 16 KB. The guest account is selected by your application key; never send Posting Keys in the request body.
A successful HTTP 202 Accepted response:
{
"ok": true,
"id": "9f3ca91dba802a531c48f77b892ac343",
"status": "moderating",
"account": "your-guest-account"
}202 confirms acceptance, not publication. Reusing the same Idempotency-Key within an application returns the original submission, possibly with duplicate: true. Do not regenerate it after a timeout for the same comment.
6. GET — status and moderation
Check status with the same API key:
GET /bg-entry.php?id=9f3ca91dba802a531c48f77b892ac343 HTTP/1.1
Host: blurtplugin.online
Authorization: Bearer ggk_YOUR_APP_SECRETExample response:
{
"ok": true,
"comment": {
"id": "9f3ca91dba802a531c48f77b892ac343",
"status": "published",
"review_reason": null,
"permlink": "re-9f3ca91dba802a531c48f77b",
"tx_id": "...",
"published_at": "2026-10-30 10:15:00",
"account": "your-guest-account"
}
}| Status | Meaning |
|---|---|
moderating | Awaiting Gemini AI moderation |
review | Awaiting manual review |
rejected | Rejected, not published |
queued | Approved, queued for publishing |
publishing | On-chain submission is being processed |
broadcasted | Broadcast submitted; confirmation pending |
uncertain | Unknown chain outcome; do not resubmit with a new ID |
published | Publication confirmed on-chain |
failed | Publishing failure; investigate |
AI is intended to filter spam and fraud, not opinions. Uncertain cases may be held for manual moderation. A 32-character lowercase hexadecimal comment ID is required for status checks, and each application can read only its own submissions.
7. Limits, HTTP errors and retries
The gateway enforces 3 comments per visitor per 24 hours per application, plus per-app hourly and daily limits set in the panel. Implement your own CAPTCHA, CSRF protection and rate limiting too.
| HTTP | Example reason | Action |
|---|---|---|
400 | INVALID_JSON, INVALID_ID, IDEMPOTENCY_KEY_REQUIRED | Fix request format |
401 | UNAUTHORIZED | Check the Bearer API key and application status |
403 | APP_DISABLED during a request | Contact the app owner |
404 | NOT_FOUND | Check comment ID and app key |
405/415 | Unsupported method / JSON required | Use GET or JSON POST |
413/422 | Payload too large / invalid inputs | Fix submitted data |
429 | RATE_LIMITED | Back off, inform the visitor |
503 | SERVICE_UNAVAILABLE, ACCOUNT_UNAVAILABLE | Retry later using the same Idempotency-Key |
426 | HTTPS_REQUIRED | Use HTTPS |
Error responses are generally {"ok":false,"error":"CODE"}. A reverse proxy may return HTML for 404 errors; always check HTTP status before JSON parsing.
8. Examples — cURL, PHP and browser
cURL (server-side)
curl --fail-with-body -X POST 'https://blurtplugin.online/bg-entry.php' \
-H "Authorization: Bearer $BLURT_GUEST_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: frontend:comment-1234567890' \
--data '{"visitor_id":"visitor_8nBL4m9X2qP7v6K1","nickname":"Anna","body":"Test comment","parent_author":"author","parent_permlink":"example-post"}'Warning: this request creates a real submission. Use your own authorized app and test post.
PHP backend request
<?php
$key = getenv('BLURT_GUEST_API_KEY');
if (!$key) throw new RuntimeException('API key missing');
// Reuse a persisted submission key when retrying the same comment.
$submissionKey = 'frontend:comment-1234567890';
$payload = [
'visitor_id' => 'visitor_8nBL4m9X2qP7v6K1',
'nickname' => 'Anna',
'body' => 'Test comment',
'parent_author' => 'author',
'parent_permlink' => 'example-post',
];
$ch = curl_init('https://blurtplugin.online/bg-entry.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $key,
'Content-Type: application/json',
'Idempotency-Key: ' . $submissionKey,
],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 15,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($body === false) throw new RuntimeException('Connection failed');
curl_close($ch);
$result = json_decode($body, true);
if ($http !== 202 || !is_array($result) || empty($result['ok'])) {
throw new RuntimeException('API response HTTP ' . $http);
}
$id = $result['id']; // store for future GET status checksBrowser calls your own backend only
// Never embed the ggk_ API key in browser code.
const response = await fetch('/api/guest-comment', {
method: 'POST',
credentials: 'same-origin',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({nickname, body, parent_author, parent_permlink})
});
const result = await response.json();
// Your backend sets visitor_id and Idempotency-Key,
// enforces CSRF and rate limits, and exposes a safe status route.Have the backend generate a random, stable visitor ID (such as a session value), persist an idempotency key per submission, and authenticate status GET requests using the server-side app key. Do not expose raw secrets or internal errors to the browser.
9. Security and multiple frontends
- Keep API keys server-side only; never expose them in source, browser calls or logs.
- Enter your Posting Key only into the trusted Guest management panel, never in the comment form or POST API request.
- Prefer an independent guest account with limited funds rather than a personal account.
- If an API secret leaks, rotate it in the panel; the old secret becomes invalid.
- Protect your frontend with HTTPS, CSRF, CAPTCHA, validation and rate limits.
- When publishing is
uncertain, do not submit a fresh duplicate; request investigation. - Managers see only assigned apps/accounts; panel access does not give rights to other users' resources.
Guest Gateway's infrastructure is centralized, but published comments live on the BLURT blockchain and can be read by any compatible frontend.
10. Go-live checklist
- Administrator invited your account with manager access.
- Dedicated guest BLURT account is created with the correct Posting authority and enough BLURT for fees.
- API secret was generated and stored privately on your server.
- Backend POST works and you can poll GET using its returned ID.
- Your UI clearly distinguishes moderation, queued, rejected, and published states.
- Retrying an identical submission with the same Idempotency-Key does not create a second comment.
- Check 401 (invalid secret), 429 (rate limiting), and cross-app isolation.
- Add frontend CSRF, validation, CAPTCHA and rate limiting.
- Confirm that a published comment is visible on-chain under your guest account.