@wpgaurav/fluent-community
125+ reusable AI agent skills for Claude Code, ChatGPT, Cursor, and other AI tools — WordPress, design, SEO, marketing, frontend
| name | fluent-community |
| description | Use when pushing content, docs, posts, changelogs, or other updates to Fluent Community spaces through the Fluent Community REST API. |
Fluent Community REST API
Push content (docs, posts, changelogs) to Fluent Community spaces on your-site.com.
Authentication
Basic Auth using credentials from ~/.env:
GA_WORDPRESS_URL = https://your-site.com
GA_USERNAME = your-username
GA_APPLICATION_PASSWORD = your-app-password
With curl: -u '$GA_USERNAME:$GA_APPLICATION_PASSWORD'
With Python urllib:
import base64
AUTH = base64.b64encode(b'your-username:your-app-password').decode()
req.add_header('Authorization', f'Basic {AUTH}')
Base URL
https://your-site.com/wp-json/fluent-community/v2
Endpoints
List Spaces
GET /spaces?per_page=50
Returns { "spaces": [ { "id", "title", "slug", "parent_id", "privacy", "status", "settings", ... } ] }
Get Space by Slug
GET /spaces/{slug}/by-slug
Returns { "space": { ... }, "permissions": { "can_create_post": true, ... } }
Join a Space
POST /spaces/{slug}/join
The authenticated user must be a member of a space to post in it.
Create a Feed/Post
POST /feeds
Parameters (form-encoded, use --data-urlencode):
title(string) - Post titlemessage(string, required) - Post content (markdown, HTML, or plain text)space(string, required) - Space slug (NOT space_id)content_type(string) -text,markdown, orhtml. Default:textprivacy(string) -publicorprivate. Default:publicstatus(string) -publishedordraft. Default:publishedfeatured_image(string) - Featured image URLscheduled_at(datetime) - Schedule publication time
CRITICAL: Use space (slug) not space_id (numeric). Using space_id returns "Please select a valid space to post in."
curl example:
curl -s -X POST 'https://your-site.com/wp-json/fluent-community/v2/feeds' \
-u 'your-username:your-app-password' \
--data-urlencode 'title=My Post Title' \
--data-urlencode 'message=Post content in markdown' \
--data-urlencode 'content_type=markdown' \
--data-urlencode 'space=core-forms-docs'
Python example (recommended for bulk operations):
import json, urllib.request, urllib.parse, base64
AUTH = base64.b64encode(b'your-username:your-app-password').decode()
API = 'https://your-site.com/wp-json/fluent-community/v2/feeds'
data = urllib.parse.urlencode({
'title': 'Post Title',
'message': content,
'space': 'space-slug-here',
}).encode()
req = urllib.request.Request(API, data=data, method='POST')
req.add_header('Authorization', f'Basic {AUTH}')
resp = urllib.request.urlopen(req)
result = json.loads(resp.read())
feed_id = result['feed']['id']
For large content files:
curl -s -X POST "$API" \
-u "$AUTH" \
--data-urlencode "title=Large Doc" \
--data-urlencode "space=space-slug" \
--data-urlencode "message@/tmp/content.txt"
Response:
{
"feed": {
"id": 85,
"title": "My Post",
"slug": "my-post",
"message": "...",
"content_type": "markdown",
"space_id": "17",
"status": "published",
"permalink": "https://your-site.com/circle/space/core-forms-docs/post/my-post"
},
"message": "Your post has been published"
}
Update a Feed/Post
POST /feeds/{feed_id}
PATCH /feeds/{feed_id}
Delete a Feed/Post
DELETE /feeds/{feed_id}
Returns { "message": "Feed has been deleted successfully" }
Create a Space
POST /spaces
Uses space[field] syntax:
curl -s -X POST "$API/spaces" \
-u "$AUTH" \
--data-urlencode 'space[title]=My Space' \
--data-urlencode 'space[slug]=my-space' \
--data-urlencode 'space[description]=Description here' \
--data-urlencode 'space[privacy]=public'
Update a Space
PUT /spaces/{slug}/by-slug
PUT /spaces/{id}/by-id
Note: Space settings (restricted_post_only, default_post_sort_by, show_sidebar) may need to be updated via the Fluent Community admin panel rather than the API.
Known Spaces
- Core Forms (ID 8, slug:
core-forms) - Discussion space - Core Forms Docs (ID 17, slug:
core-forms-docs) - Documentation - Functionalities (ID 9, slug:
functionalities) - Discussion - Functionalities Docs (ID 18, slug:
functionalities-docs) - Documentation - GT Link Manager (ID 12, slug:
gt-link-manager) - Discussion - GT Link Manager Docs (ID 21, slug:
gt-link-manager-docs) - Documentation - GT ACF Blocks Plugin (ID 10, slug:
gt-acf-blocks-plugin) - Discussion - GT ACF Blocks Plugin Docs (ID 19, slug:
gt-acf-blocks-plugin-docs) - Documentation - GT Page Blocks Builder (ID 13, slug:
gt-page-blocks-builder) - Discussion - GT Page Blocks Builder Docs (ID 22, slug:
gt-page-blocks-builder-docs) - Documentation - GT Extensions for FluentCart (ID 11, slug:
gt-extensions-for-fluentcart) - Discussion - GT Extensions for FluentCart Docs (ID 20, slug:
gt-extensions-for-fluentcart-docs) - Documentation - Dynamic Month & Year into Posts (ID 14, slug:
dynamic-month-year-into-posts) - Discussion - Dynamic Month & Year into Posts Docs (ID 23, slug:
dynamic-month-year-into-posts-docs) - Documentation - Books (ID 15, slug:
books) - Book discussions
Bulk Push Pattern
When pushing multiple markdown docs to a space:
import json, urllib.request, urllib.parse, base64, os, glob, time, re
AUTH = base64.b64encode(b'your-username:your-app-password').decode()
API = 'https://your-site.com/wp-json/fluent-community/v2/feeds'
SPACE = 'target-space-slug'
DOCS_DIR = '/path/to/docs'
# Convert markdown tables to lists (Fluent Community doesn't render tables)
table_pattern = re.compile(r'^\|[^\n]+\|\n\|[\s:|-]+\|\n(?:\|[^\n]+\|\n?)+', re.MULTILINE)
def md_table_to_list(match):
block = match.group(0).strip()
tlines = [l.strip() for l in block.split('\n') if l.strip()]
headers = [h.strip() for h in tlines[0].strip('|').split('|')]
rows = []
for line in tlines[2:]:
cells = [c.strip() for c in line.strip('|').split('|')]
rows.append(cells)
result = []
for row in rows:
items = []
for i, cell in enumerate(row):
if i < len(headers) and headers[i]:
items.append(f"**{headers[i]}:** {cell}")
else:
items.append(cell)
result.append("- " + " | ".join(items))
return '\n'.join(result)
files = sorted(glob.glob(os.path.join(DOCS_DIR, '*.md')))
for filepath in files:
with open(filepath, 'r') as f:
content = f.read()
lines = content.split('\n')
title = lines[0][2:].strip() if lines[0].startswith('# ') else os.path.basename(filepath)
content = '\n'.join(lines[1:]).strip()
content = table_pattern.sub(md_table_to_list, content)
data = urllib.parse.urlencode({
'title': title,
'message': content,
'space': SPACE,
}).encode()
req = urllib.request.Request(API, data=data, method='POST')
req.add_header('Authorization', f'Basic {AUTH}')
resp = urllib.request.urlopen(req)
result = json.loads(resp.read())
print(f"OK | Feed #{result['feed']['id']} | {title}")
time.sleep(0.5)
Gotchas
- Use
space(slug), NOTspace_id- The numeric ID will silently fail with "Please select a valid space to post in." - Fluent Community doesn't render markdown tables - Convert tables to lists before pushing.
- Use
--data-urlencodefor content with special characters, markdown, or HTML. - User must be a member of the space to post (join via
POST /spaces/{slug}/join). - Rate limit - Add
time.sleep(0.5)between requests when pushing in bulk. - Content types:
textwraps in<p>tags,markdownrenders markdown,htmlpasses through raw HTML. - Space settings like sort order and restricted posting are best updated via the Fluent Community admin panel, not the API.
Post-Push Space Settings
After pushing docs, configure these in the Fluent Community admin panel:
- Restricted Post Only: Yes (prevents non-admin posts)
- Show Sidebar: Yes (shows post navigation)
- Disable Post Sort By: Yes (locks sort order)
- Default Post Sort By: Oldest (shows docs in chronological/chapter order)
Loading...
Select a file to preview
Analyzing security...
Checking scan reports and verification data.
Bill of Materials
Everything this skill can do — files, network, commands, and more.