Longbridge Developers
Get Started

Create Topic

Create a new community topic on Topics. Two content types are supported:

Typetitlebody formatNotes
post (default)OptionalPlain text onlyMarkdown syntax (e.g. **bold**, # heading) is NOT rendered — it appears as literal characters, similar to a tweet.
articleRequiredMarkdownThe server converts Markdown to HTML for display. Supports headers, tables, bold, code blocks, etc.

Only users who have opened a Longbridge account and hold assets are allowed to publish community topics and replies via Longbridge Developers API or CLI. Returns 403 otherwise.

Stock symbols mentioned in the body (e.g. 700.HK, TSLA.US) are automatically recognized and linked as related stocks by the platform. Use tickers to associate additional symbols not explicitly mentioned in the body.

⚠️ Do not abuse symbol linking to associate unrelated stocks. Content moderation may restrict publishing or mute the account.

Rate limit: Max 3 topics per user per minute and 10 per 24 hours. Exceeding the limit returns 429.

⚠️ Rate limit thresholds are for reference only and may be adjusted by the platform at any time.

>_ CLI
# publish a topic for Tesla
longbridge topic create --body "Tesla Q1 earnings analysis" --tickers TSLA.US
# publish a topic for Apple
longbridge topic create --body "Apple WWDC preview" --tickers AAPL.US

Request

HTTP MethodPOST
HTTP URL/v1/content/topics

Request Body

NameTypeRequiredDescription
titlestringYES (for article)Topic title. Required when topic_type is article; optional for post.
bodystringYESTopic body. \n- For post: plain text only — Markdown is not rendered.\n- For article: Markdown is supported.
topic_typestringNOContent type: post (plain text, default) or article (Markdown).
tickersstring[]NORelated security symbols, format \{symbol\}.\{market\} (e.g. ["AAPL.US", "700.HK"]). Maximum 10. Note: Symbols mentioned in the body (e.g. 700.HK, TSLA.US) are automatically recognized and linked by the platform. Use tickers to associate additional symbols not explicitly mentioned in the body.
hashtagsstring[]NOHashtag names (e.g. ["earnings", "fed"]). Maximum 1.

Request Example

>_ CLI
# Short post — plain text (default). Markdown is NOT rendered.
longbridge topic create --body "Bullish on 700.HK today"
# Short post with related tickers
longbridge topic create --body "NVDA GTC highlights" --tickers NVDA.US,700.HK
# Article — Markdown body, title is required
longbridge topic create --title "My Analysis" --body "**Bullish** on 700.HK because..." --type article
# Article from a Markdown file
longbridge topic create --title "Q4 Earnings Preview" --body "$(cat analysis.md)" --type article
# JSON output
longbridge topic create --body "Test post" --format json
from longbridge.openapi import ContentContext, Config, OAuthBuilder

oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url))
config = Config.from_oauth(oauth)
ctx = ContentContext(config)

# Short post (plain text)
resp = ctx.create_topic(
    title="",
    body="Bullish on 700.HK today",
    topic_type="post",
    tickers=["700.HK"],
)
print(resp)

# Article (Markdown)
resp = ctx.create_topic(
    title="My Analysis",
    body="**Bullish** on 700.HK because...",
    topic_type="article",
    tickers=["700.HK"],
    license=1,
)
print(resp)
import asyncio
from longbridge.openapi import AsyncContentContext, Config, OAuthBuilder

async def main() -> None:
    oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url))
    config = Config.from_oauth(oauth)
    ctx = AsyncContentContext.create(config)

    resp = await ctx.create_topic(
        title="My Analysis",
        body="**Bullish** on 700.HK because...",
        topic_type="article",
        tickers=["700.HK"],
    )
    print(resp)

if __name__ == "__main__":
    asyncio.run(main())
const { Config, ContentContext, OAuth } = require('longbridge')

async function main() {
  const oauth = await OAuth.build('your-client-id', (_, url) => {
    console.log('Open this URL to authorize: ' + url)
  })
  const config = Config.fromOAuth(oauth)
  const ctx = ContentContext.new(config)

  // Article (Markdown body)
  const resp = await ctx.createTopic({
    title: 'My Analysis',
    body: '**Bullish** on 700.HK because...',
    topicType: 'article',
    tickers: ['700.HK'],
  })
  console.log(resp)
}
main().catch(console.error)
import com.longbridge.*;
import com.longbridge.content.*;

class Main {
    public static void main(String[] args) throws Exception {
        try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get();
             Config config = Config.fromOAuth(oauth);
             ContentContext ctx = ContentContext.create(config)) {
            // Article (Markdown body, title required)
            CreateTopicOptions opts = new CreateTopicOptions("My Analysis", "**Bullish** on 700.HK because...")
                .setTopicType("article")
                .setTickers(new String[]{"700.HK"})
                .setLicense(1);
            OwnedTopic resp = ctx.createTopic(opts).get();
            System.out.println(resp);
        }
    }
}
use std::sync::Arc;
use longbridge::{oauth::OAuthBuilder, content::{ContentContext, CreateTopicOptions}, Config};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open this URL to authorize: {url}")).await?;
    let config = Arc::new(Config::from_oauth(oauth));
    let ctx = ContentContext::new(config);

    // Article (Markdown body, title required)
    let opts = CreateTopicOptions {
        title: "My Analysis".to_string(),
        body: "**Bullish** on 700.HK because...".to_string(),
        topic_type: Some("article".to_string()),
        tickers: Some(vec!["700.HK".to_string()]),
        hashtags: None,
        license: Some(1),
    };
    let resp = ctx.create_topic(opts).await?;
    println!("{:?}", resp);
    Ok(())
}
#include &lt;iostream&gt;
#include <longbridge.hpp>

#ifdef WIN32
#include <windows.h>
#endif

using namespace longbridge;
using namespace longbridge::content;

static void
run(const OAuth& oauth)
{
    Config config = Config::from_oauth(oauth);
    ContentContext ctx = ContentContext::create(config);

    // Article (Markdown body, title required)
    CreateTopicOptions opts;
    opts.title = "My Analysis";
    opts.body = "**Bullish** on 700.HK because...";
    opts.topic_type = "article";
    opts.tickers = {"700.HK"};

    ctx.create_topic(opts, [](auto res) {
        if (!res) { std::cout << "failed: " << *res.status().message() << std::endl; return; }
        std::cout << "created topic: " << res->id << std::endl;
    });
}

int main(int argc, char const* argv[]) {
#ifdef WIN32
    SetConsoleOutputCP(CP_UTF8);
#endif

    const std::string client_id = "your-client-id";
    OAuthBuilder(client_id).build(
    [](const std::string& url) {
        std::cout << "Open this URL to authorize: " << url << std::endl;
    },
    [](auto res) {
        if (!res) {
            std::cout << "authorization failed: " << *res.status().message() << std::endl;
            return;
        }
        run(*res);
    });

    std::cin.get();
    return 0;
}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/longbridge/openapi-go/config"
	"github.com/longbridge/openapi-go/oauth"
	"github.com/longbridge/openapi-go/content"
)

func main() {
	o := oauth.New("your-client-id").
		OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) })
	if err := o.Build(context.Background()); err != nil {
		log.Fatal(err)
	}
	conf, err := config.New(config.WithOAuthClient(o))
	if err != nil {
		log.Fatal(err)
	}
	ctx, err := content.NewFromCfg(conf)
	if err != nil {
		log.Fatal(err)
	}
	// Article (Markdown body, title required)
	opts := content.CreateTopicOptions{
		Title:     "My Analysis",
		Body:      "**Bullish** on 700.HK because...",
		TopicType: "article",
		Tickers:   []string{"700.HK"},
	}
	resp, err := ctx.CreateTopic(context.Background(), opts)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("created topic: %s\n", resp.ID)
}

Response

Response Headers

  • Content-Type: application/json

Response Example

{
  "code": 0,
  "message": "success",
  "data": {
    "item": {
      "id": "39304657",
      "title": "My View on AAPL",
      "topic_type": "article",
      "tickers": ["AAPL.US"],
      "hashtags": ["earnings"],
      "created_at": "1742000000"
    }
  }
}

Response Status

StatusDescriptionSchema
200Successcreate_topic_response
403Forbidden — user has not opened a Longbridge account or has no assetsNone
429Too Many Requests — rate limit exceeded (3/min or 10/24h); retry laterNone
500Internal errorNone

Schemas

create_topic_response

NameTypeRequiredDescription
itemobjecttrueNewly created topic details
∟ idstringtrueTopic ID
∟ titlestringfalseTopic title
∟ descriptionstringfalsePlain-text summary (auto-generated from body)
∟ bodystringfalseFull body text (Markdown for article)
∟ topic_typestringfalseTopic type. One of article, post
∟ tickersstring[]falseAssociated security symbols
∟ hashtagsstring[]falseAssociated hashtag names
∟ imagesobject[]falseImage list
∟∟ urlstringfalseOriginal image URL
∟∟ smstringfalseSmall thumbnail URL
∟∟ lgstringfalseLarge thumbnail URL
∟ likes_countint32falseNumber of likes
∟ comments_countint32falseNumber of replies
∟ views_countint32falseNumber of views
∟ shares_countint32falseNumber of shares
∟ detail_urlstringfalseDirect URL to the topic
∟ authorobjectfalseAuthor information
∟∟ member_idstringfalseAuthor member ID
∟∟ namestringfalseAuthor display name
∟∟ avatarstringfalseAuthor avatar URL
∟ created_atstringtrueUnix timestamp (seconds) when the topic was created
∟ updated_atstringfalseUnix timestamp (seconds) of last update