Comments, moderation, and social feeds through one REST API and SDKs for 10+ languages. Fetch, post, and moderate from your backend, then stream new activity to every reader in realtime over WebSockets.
FastComments is more than comments. Build discussions, moderation, and social feeds on the same API and SDK suite.
Threaded comments and live chat. Fetch, post, vote, pin, reply, and search, with SSO and realtime updates built in.
A dedicated moderation surface with 40+ endpoints. Approve, flag, block, ban, lock, and audit, backed by automatic spam filtering.
Build activity and social feeds with posts, media, reactions, and follows, then push new posts to every client live.
cURL and typed SDKs for Node, Python, PHP, Ruby, Go, Java, Rust, Swift, and C++. Over 200 endpoints cover comments, votes, pages, SSO users, feed posts, moderation, and notifications, all behind a single API key.
npm install fastcomments-sdkimport { createFastCommentsSDK } from 'fastcomments-sdk/server';
const sdk = createFastCommentsSDK({
apiKey: 'your-api-key', // server-side only
basePath: 'https://fastcomments.com' // optional (default)
});
// Fetch comments for a page
const { comments } = await sdk.publicApi.getCommentsPublic({
tenantId: 'your-tenant-id',
urlId: 'page-url-id'
});
// Post a comment
await sdk.publicApi.createCommentPublic({
tenantId: 'your-tenant-id',
broadcastId: crypto.randomUUID(),
createComment: {
urlId: 'page-url-id',
url: 'https://example.com/post',
comment: 'Hello from the API!',
commenterName: 'Alice'
}
});
# Fetch comments for a page curl -s 'https://fastcomments.com/api/v1/comments?tenantId=your-tenant-id&urlId=page-url-id' \ -H 'x-api-key: YOUR_API_KEY'
pip install fastcommentsimport client
from client.api.public_api import GetCommentsPublicOptions
configuration = client.Configuration(host="https://fastcomments.com")
with client.ApiClient(configuration) as api_client:
api = client.PublicApi(api_client)
response = api.get_comments_public(
"your-tenant-id",
"page-url-id",
GetCommentsPublicOptions(page=0, limit=30),
)
for comment in response.comments:
print(comment.commenter_name, comment.comment)
composer require fastcomments/fastcomments-php<?php
require_once(__DIR__ . '/vendor/autoload.php');
$api = new FastComments\Client\Api\PublicApi(new GuzzleHttp\Client());
$result = $api->getCommentsPublic('your-tenant-id', 'page-url-id', [
'page' => 0,
'limit' => 30,
]);
foreach ($result->getComments() as $comment) {
echo $comment->getCommenterName() . ': ' . $comment->getComment() . PHP_EOL;
}
gem install fastcommentsrequire 'fastcomments-client'
api = FastCommentsClient::PublicApi.new
result = api.get_comments_public('your-tenant-id', 'page-url-id', { page: 0, limit: 30 })
result.comments.each do |comment|
puts "#{comment.commenter_name}: #{comment.comment}"
end
go get github.com/fastcomments/fastcomments-gopackage main
import (
"context"
"fmt"
openapiclient "github.com/fastcomments/fastcomments-go/client"
)
func main() {
client := openapiclient.NewAPIClient(openapiclient.NewConfiguration())
resp, _, err := client.PublicAPI.
GetCommentsPublic(context.Background(), "your-tenant-id").
UrlId("page-url-id").Page(0).Limit(30).Execute()
if err != nil {
panic(err)
}
for _, c := range resp.Comments {
fmt.Printf("%s: %s\n", c.GetCommenterName(), c.GetComment())
}
}
import com.fastcomments.invoker.ApiClient;
import com.fastcomments.invoker.Configuration;
import com.fastcomments.api.PublicApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://fastcomments.com");
PublicApi api = new PublicApi(client);
var result = api.getCommentsPublic("your-tenant-id", "page-url-id")
.page(0)
.limit(30)
.execute();
System.out.println(result.getComments());
use fastcomments_sdk::client::apis::configuration::Configuration;
use fastcomments_sdk::client::apis::public_api::{get_comments_public, GetCommentsPublicParams};
let config = Configuration::new();
let params = GetCommentsPublicParams {
tenant_id: "your-tenant-id".to_string(),
url_id: "page-url-id".to_string(),
page: Some(0),
limit: Some(30),
..Default::default()
};
let result = get_comments_public(&config, params).await.unwrap();
for comment in result.comments {
println!("{:?}: {:?}", comment.commenter_name, comment.comment);
}
import FastCommentsSwift
var options = PublicAPI.GetCommentsPublicOptions()
options.page = 0
options.limit = 30
let result = try await PublicAPI.getCommentsPublic(
tenantId: "your-tenant-id",
urlId: "page-url-id",
options: options
)
print(result.comments ?? [])
#include "FastCommentsClient/api/PublicApi.h"
#include "FastCommentsClient/ApiClient.h"
#include "FastCommentsClient/ApiConfiguration.h"
using namespace org::openapitools::client::api;
auto config = std::make_shared<ApiConfiguration>();
config->setBaseUrl(utility::conversions::to_string_t("https://fastcomments.com"));
PublicApi publicApi(std::make_shared<ApiClient>(config));
auto resp = publicApi.getCommentsPublic(
utility::conversions::to_string_t("your-tenant-id"),
utility::conversions::to_string_t("page-url-id")
).get();
Open one connection and receive every new comment, edit, vote, and presence update the moment it happens. No events are missed: on reconnect the event log is re-fetched to replay anything sent while the client was offline. Native WebSocket subscribers ship for Node, React Native, Java, Swift, and C++. Every other language stays realtime by polling the event log.
npm install fastcomments-sdkimport { subscribeToChanges, LiveEventType } from 'fastcomments-sdk/browser';
const config = { tenantId: 'your-tenant-id', urlId: 'page-url-id' };
const subscription = subscribeToChanges(
config,
'your-tenant-id', // tenantIdWS
'page-url-id', // urlIdWS
'user-session-id', // userIdWS (from the getComments response)
(event) => {
if (event.type === LiveEventType.new_comment) {
console.log('New comment:', event.comment?.comment);
}
return true; // event handled
},
(isConnected) => console.log(isConnected ? 'connected' : 'disconnected')
);
// later: subscription.close();
npm install fastcomments-react-native-sdkimport React, { useState } from 'react';
import { FastCommentsLiveCommenting } from 'fastcomments-react-native-sdk';
import { FastCommentsCommentWidgetConfig } from 'fastcomments-typescript';
export default function Comments() {
// <FastCommentsLiveCommenting> subscribes to the live feed automatically.
const [config] = useState<FastCommentsCommentWidgetConfig>({
tenantId: 'your-tenant-id',
urlId: 'page-url-id',
showLiveRightAway: true,
countAll: true,
});
return <FastCommentsLiveCommenting config={config} />;
}
import com.fastcomments.pubsub.LiveEventSubscriber;
import com.fastcomments.pubsub.SubscribeToChangesResult;
import com.fastcomments.core.CommentWidgetConfig;
import com.fastcomments.model.LiveEventType;
CommentWidgetConfig config = new CommentWidgetConfig();
config.tenant = "your-tenant-id";
config.urlId = "page-url-id";
LiveEventSubscriber subscriber = new LiveEventSubscriber();
SubscribeToChangesResult result = subscriber.subscribeToChanges(
config,
"your-tenant-id", // tenantIdWS
"page-url-id", // urlId
"page-url-id", // urlIdWS
"my-presence-id", // userIdWS
null, // canSeeCommentsCallback (optional)
(event) -> {
if (event.getType() == LiveEventType.NEW_COMMENT) {
System.out.println("New comment: " + event.getComment().getId());
}
}
);
// later: result.close();
import FastCommentsSwift
let config = LiveEventConfig(
tenantId: "your-tenant-id",
urlId: "page-url-id",
urlIdWS: "page-url-id", // URL-safe id for the WS server
userIdWS: "my-presence-id"
)
let subscriber = LiveEventSubscriber()
let result = subscriber.subscribeToChanges(config: config) { event in
if event.type == .newComment, let comment = event.comment {
print("New comment: \(comment.id ?? "")")
}
}
// later: result?.close()
#include <fastcomments/live/live_stream.hpp>
#include <iostream>
using namespace fastcomments::live;
LiveStreamConfig cfg;
cfg.wsBaseUrl = "wss://fastcomments.com"; // no trailing slash
LiveStream stream(cfg);
stream.onEvent([](const LiveEvent& ev) {
if (ev.type == EventType::NewComment) {
std::cout << "New comment at " << ev.timestamp << std::endl;
}
});
stream.subscribe("your-tenant-id", "page-url-id", "my-presence-id").wait();
// later: stream.close().wait();
pip install fastcommentsimport time
import client
configuration = client.Configuration(host="https://fastcomments.com")
with client.ApiClient(configuration) as api_client:
api = client.PublicApi(api_client)
start_time = int(time.time() * 1000) # ms epoch
while True:
result = api.get_event_log(
"your-tenant-id", "page-url-id", "my-user-id", start_time
)
for event in result.events:
print("event:", event.data)
start_time = int(event.created_at.timestamp() * 1000) + 1
time.sleep(2)
# startTime = epoch millis to replay from; advance it past the last event you saw curl -s 'https://fastcomments.com/api/v1/event-log/your-tenant-id?urlId=page-url-id&userIdWS=my-user-id&startTime=1720560000000' \ -H 'x-api-key: YOUR_API_KEY'
Skip building and maintaining your own comment UI. Our dedicated, maintained SDKs for React Native, Android, and iOS ship native UI components for threaded comments, live chat, and feeds. Drop in a view, pass a config, and you are done.
npm: fastcomments-react-native-sdk
Native components, no webview. Drop in FastCommentsLiveCommenting, FastCommentsLiveChat, or FastCommentsFeed and pass a config.
See the live democom.fastcomments:sdk
Native Android UI components. Add FastCommentsView to your layout for threaded comments, voting, notifications, and feeds. Android 8.0+.
View on GitHubSwift Package: FastCommentsUI
A native SwiftUI library for threaded comments, social feeds, and live chat. iOS 16+ and macOS 14+.
View on GitHubOne API key, one base URL. Everything the dashboard does, your code can do too.
Typed clients for Node, Python, PHP, Ruby, Go, Java, Rust, Swift, C++, and more, so you build in your stack instead of ours.
New comments reach every reader the moment they post, with no refresh and no polling. If a reader reconnects, missed events are replayed from the log.
Single sign-on, comment moderation, and spam filtering are built in, so the hard parts are handled before you write a line.
We run the storage and the realtime infrastructure across a global network. You call the API and ship.
One API and SDK suite behind comment threads, chat, and live activity across web, mobile, and server apps.
Stream messages to everyone in the room in realtime, with presence counts and typing activity.
Add nested, votable comment sections to articles, products, and posts with a few API calls.
Post to a feed and push new items and reactions to connected clients as they arrive.
Collect questions, answers, votes, and poll results, then rank and display them live.
Start a free trial and grab your tenant ID and API key from the dashboard.
Add the SDK for your language, or call the REST API directly with cURL and your x-api-key header.
Load comments, post from your backend, and subscribe to changes to stream updates to every reader.
FastComments runs across multiple regions on our own infrastructure. Writes replicate between regions, nodes fail over automatically, and readers are served from the location nearest them.
Writes are accepted in more than one region and replicated between them, so there is no single point of failure.
Comments and media are served from our own global CDN and DNS, delivered from the location nearest your users. No third-party CDN.
Redundant nodes fail over on their own, so traffic keeps flowing through an outage. Backed by 99.99% uptime.
Run in the US or the EU. The EU region at eu.fastcomments.com keeps data in-region for compliance.
Thousands of satisfied customers trust us for our exceptional service, reliability, and innovative solutions. Join our growing community and experience the difference today!
Get Started
No. The widget is optional. You can build your entire commenting experience on the REST API and SDKs and render everything yourself.
Node, Python, PHP, Ruby, Go, Java, Rust, Swift, C++, and Nim, plus a React Native SDK for mobile. Any language can also call the REST API directly.
Clients open a WebSocket and receive new comments, edits, votes, and presence updates as events, so there is no refresh and no polling. No events are missed: if a client disconnects, it re-fetches the event log on reconnect to replay anything sent while it was offline.
No. FastComments hosts the realtime infrastructure. Your client subscribes with the SDK, and we deliver the events.
They poll the event log endpoint, which returns every change since a timestamp. The Node, React Native, Java, Swift, and C++ SDKs include a native WebSocket subscriber instead.
For comments specifically, FastComments pre-calculates pagination on every write for optimal load times, so even very large threads paginate fast.
Yes. Start a free trial with full access to the API and SDKs, no credit card required. After the trial, paid plans scale with your traffic.
The full REST API and SDK reference lives at docs.fastcomments.com, where every endpoint, parameter, and response is documented.
Yes. FastComments serves an EU region at eu.fastcomments.com, and the SDKs support routing to it.
Start a free trial, grab your API key, and add live discussions to your app today.