Run a community with a server list, forum and guides
Serve a server list, a forum, guides and your Discord chat on your storefront, and moderate what your customers post.
Your storefront can host a community for your customers and their players: a list of your customers' servers, a forum, a library of guides, and the public channels of your Discord server. Visitors read all of it without signing in. Customers post with their own token, and your team moderates what they post in the staff console.
Every route on this page is under https://api.coritan.com/api/v1/orgs/{org_slug}. With the API says which credential each group of routes takes.
Before you begin
Section titled Before you begin- To show your Discord chat, connect a Discord bot to your organization as Connect a Discord server describes. That needs the
owneroradminrole. - To let customers post, sign them in as Sign customers in to your storefront describes.
- To moderate, a member needs Tier 1 support or a higher role. Moderate the community lists the lowest role for each task.
Turn the community on
Section titled Turn the community onCoritan turns the server list, the forum and the guides on for your organization, and sets their options, such as the forum's boards, the tags a server can carry and the length limits. You turn the chat on yourself.
- Ask support to turn on the parts you want. Until a part is on, its routes answer
404. - To show your Discord chat, go to Organizations, open your organization, choose Integrations, then Discord. Under Community chat, tick Mirror public channels on the storefront, then choose Save Discord settings. Connect the bot covers the Invite link and Hidden channels fields.
- Read
GET /storefront/branding, and check that each part you asked for hasenabled: truein its block.
Build the community pages
Section titled Build the community pagesGET /storefront/branding carries a block for each part, with what your pages need to show it. Read the switches and limits from it rather than writing them into your site, because Coritan can change them. Show your brand covers the rest of the answer.
| Block | What it holds |
|---|---|
public_server_list |
enabled, the path_prefix your site serves the community under, the categories and editions a server is listed under, the tags a customer can choose and max_tags. |
community_forum |
enabled and the forum's paths, such as forum_base and profile_base. Switches for what members can do: allow_customer_threads, allow_customer_replies, nested_replies, voting_enabled, downvotes_enabled, reactions_enabled, solutions_enabled, wall_enabled, member_directory_enabled and profile_images_enabled. Limits: max_body_chars, max_bio_chars, max_tags, max_reply_depth and bump_cooldown_hours. Lists: reactions, thread_kinds, report_categories, roles and role_labels. |
community_knowledgebase |
enabled and guides_base, the categories and difficulties a guide can take, the switches comments_enabled, allow_customer_contrib, helpful_votes_enabled and allow_cover_images, and the limits max_body_chars, max_summary_chars and max_tags. |
community_chat |
enabled, and the invite_url of your Discord server. |
GET /storefront/community/overview returns a community home page in one call: stats, servers, guides, forum, members and chat, with the counts and names a hub shows. It carries no images, so the page can paint at once. Add include=pages to get the first page of each tab as well, 24 items each, with their images.
GET /storefront/community/stats returns the counters on their own, for a live figure: total_accounts, total_servers, total_servers_created and total_players.
List your customers' servers
Section titled List your customers' serversThe server list shows the servers your customers choose to list, each with a page of its own. The customer who owns the service creates its listing with their token.
Read the listing with
GET /portal/services/{service_id}/community-listing, whereservice_idis the service'sidfromGET /portal/services.feature_enabledsays whether the list is on. The answer holds theeditions,tagsandmax_tagsto offer, the server'sjoin_addressandplayers_online, and thelisting, which isnulluntil the first save.Save the listing:
Shellcurl -X PUT "https://api.coritan.com/api/v1/orgs/acme/portal/services/41/community-listing" \ -H "Authorization: Bearer $CUSTOMER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"display_name": "Survival SMP", "slug": "survival-smp", "tagline": "Vanilla survival with land claims", "tags": ["survival"], "published": true}'The first save creates the listing from every field. Later saves change only the fields you send.
Show the customer their listing at
listing.public_path, such as/community/servers/survival-smpon your site.
| Field | What it takes |
|---|---|
display_name |
Up to 120 characters. A new listing takes the service's hostname when you leave it out. |
slug |
The listing's address: 2–80 lowercase letters, digits and hyphens, unique in your organization. We make one from display_name when you leave it out. |
tagline, description |
Up to 200 and 8,000 characters. |
category |
One of the editions. Left out, it follows from the tags. |
tags |
Tags from your list, up to max_tags. |
website_url, discord_url |
http or https addresses, up to 500 characters. |
icon_data_uri, banner_data_uri, gallery |
PNG images as data URIs: an icon of up to 120,000 characters, a banner of up to 400,000, and up to 4 gallery images of up to 400,000 each. |
seo_title, seo_description |
The listing page's title and description for search engines. We keep the first 160 and 320 characters. |
show_player_count |
false hides how many players are online. It defaults to true. |
published |
true puts the listing on the public list. |
A listing can be published once it has at least one tag. When the answer's require_gameproxy is true, the server also needs a working join address. The listing shows the server's join address, or its custom domain when the owner linked one with include_in_list set, as Link a custom domain describes.
A server's own panel has a shorter switch for the same listing, which List the server in your directory covers. External servers can be listed too, and show the players they reported at their last status check.
When your staff hold or hide a listing, moderation in the answer is held or hidden, and the listing stays off the public list whatever published says.
Show the server list
Section titled Show the server listGET /storefront/community/servers lists the published listings for anyone:
curl "https://api.coritan.com/api/v1/orgs/acme/storefront/community/servers?tag=survival&sort=players"
Filter with q, category and tag, sort with sort (players, rating or newest), and page with page and page_size (1–100, 24 by default). GET /storefront/community/servers/{listing_slug} returns one listing. Each carries its join_address, players_online (null when the owner hides it), online, featured, average_rating and total_ratings.
A signed-in customer rates a listing with POST /storefront/community/servers/{listing_slug}/rate and a rating from 1 to 5. A second rating replaces the first. Send the customer's token with GET /storefront/community/servers/{listing_slug}, and the answer includes their own rating as user_rating.
Run the forum
Section titled Run the forumThe forum has boards of threads, and each thread is a discussion, question, announcement or showcase. Coritan sets up your boards when it turns the forum on. With none set, the forum has six: Announcements, where only forum administrators post, Help & Support, Guides & Tutorials, Server Showcase, Suggestions, and Off Topic, which search engines do not index. Votes, reactions, accepted answers, nested replies, the member directory and profile walls each have a switch in the community_forum block.
Read the forum
Section titled Read the forumThese routes need no token, and the lists take page and page_size:
| Route | What it returns |
|---|---|
GET /storefront/community/forum |
The boards, with the counts a forum's front page shows. |
GET /storefront/community/forum/boards/{category_slug} |
A board's threads. sort is hot (the default), new, top, active or unanswered, and q, tag and kind narrow the list. |
GET /storefront/community/forum/threads |
Threads from every public board. filter is latest or unanswered. |
GET /storefront/community/forum/threads/{category_slug}/{thread_slug} |
A thread and its replies. sort is best (the default), new, old or top. |
GET /storefront/community/forum/search |
Threads and replies whose title or text matches q, 2–120 characters. scope is all, threads or posts. |
GET /storefront/community/forum/tags |
The tags in use, busiest first. .../tags/{tag} lists the threads with one tag. |
GET /storefront/community/members |
The member directory, when it is on. sort is posts, threads, solutions, reactions, newest or active. |
GET /storefront/community/members/{handle} |
A member's profile. .../activity lists their threads, replies or accepted answers by kind, and .../wall their wall. |
Post in the forum
Section titled Post in the forumPosting takes the customer's token, and the routes are under /portal/community/forum/. Bodies are Markdown, up to max_body_chars, and a member mentions another with @ and their handle. POST /storefront/community/forum/preview renders a draft as your site will show it, with the members it mentions in mentions.
| Route | What it does |
|---|---|
POST /threads |
Starts a thread from category_slug, title (3–200 characters), body_markdown, kind and tags. |
POST /threads/{thread_id}/posts |
Replies with body_markdown. With nested replies on, parent_post_id answers one reply. |
PUT /threads/{thread_id}, PUT /posts/{post_id} |
Edits the member's own thread or reply, with an optional edit_reason. |
DELETE /threads/{thread_id}, DELETE /posts/{post_id} |
Deletes the member's own thread or reply. Forum staff can delete anyone's, and only a forum administrator can delete a locked thread. |
POST /posts/{post_id}/vote |
Votes with value from -1 to 1. |
POST /posts/{post_id}/react |
Reacts with a reaction_type from reactions. |
POST /threads/{thread_id}/solution?post_id=... |
Accepts a reply as the answer. The thread's author and forum staff can, and DELETE clears it. |
POST /threads/{thread_id}/bump |
Moves the author's thread back to the top, once every bump_cooldown_hours. |
POST /threads/{thread_id}/subscription |
Follows a thread, or stops following it. GET /subscriptions lists followed threads with their unread posts. |
POST /reports |
Reports a thread, a post or a member, named by thread_id, post_id or handle in the query. The body takes a category from report_categories and a reason of up to 500 characters. |
GET /portal/community/forum/me returns the member's handle and forum role, their unread followed threads and, for forum staff, the number of open reports.
PUT /portal/community/profile changes the member's profile: display_name (2–64 characters), biography (up to max_bio_chars), location (up to 64), website_url and signature (up to 300 each), avatar_data_uri and banner_data_uri when profile images are on, wall_enabled and index_opt_out. A wall is where members post on each other's profiles. POST /portal/community/members/{handle}/wall takes up to 2,000 characters, and POST /portal/community/wall/{wall_post_id}/comments comments on a wall post. A member can write 20 wall posts and 60 wall comments an hour.
Publish guides
Section titled Publish guidesGuides are articles written in Markdown, each with a page under guides_base. Customers write them when allow_customer_contrib is on, and a moderator approves each one before it goes live.
Read guides
Section titled Read guidesGET /storefront/community/guideslists published guides. Filter withq,category,taganddifficulty, sort withsort(views, the default,newest,featuredorhelpful), and page withpageandpage_size.GET /storefront/community/guides/{slug}returns one guide incontent, with itshelpfulvotes,relatedguides andview_count. Views by the author and by moderators do not count.GET /storefront/community/guides/{slug}/commentslists a guide's comments. A signed-in customer comments withPOSTandbody_markdown, up to 4,000 characters. When your guides hold comments for approval, a new comment'sstatusispendinguntil a moderator approves it.POST /storefront/community/guides/{slug}/helpfulwithhelpfulset totrueorfalserecords the customer's vote, one per customer.POST .../guides/{slug}/reportreports the guide, or one comment withcomment_id, with areasonof up to 500 characters.
Write a guide
Section titled Write a guide- Create the guide as the customer with
POST /portal/community/guides/articles. It needstitle, up to 200 characters, andbody_markdown, up tomax_body_chars.slug,summary,category,difficulty,tags,game_slug,cover_data_uri,seo_titleandseo_descriptionare optional. The guide is saved as adraft, andsubmitset totruesends it for review at once. - When the draft is ready, send it for review with
PUT /portal/community/guides/articles/{article_id}. An edit is submitted unless it carriessubmit: false. Itsproposal_statusbecomespending, and we notify your guide moderators. - A moderator approves or rejects it. Approval publishes the guide at its
public_path. A rejection comes back inrejection_reason, and the customer can edit the guide and submit it again.
Changing a published guide works the same way: the live version stays up until a moderator approves the proposed one. GET .../articles/{article_id}/diff returns the live and proposed versions with the diff between them, and POST .../articles/{article_id}/proposal/withdraw takes a proposal back.
GET /portal/community/guides/articles lists the customer's guides with their status (draft, published or archived) and proposal_status (none, pending or rejected). GET /portal/community/guides/notifications returns their 50 latest notifications.
POST /storefront/community/guides/preview renders Markdown as a guide will show it, with its table of contents in toc. A link keeps its address only when it is http or https or starts with / or #, and an image only when it is an http or https address or a PNG data URI.
Caution
DELETE /portal/community/guides/articles/{article_id} deletes the customer's guide in any state, with every revision, comment, vote and report. It cannot be undone.
Show your Discord chat
Section titled Show your Discord chatThe chat mirrors your Discord server's public channels on your site. Anyone can read them, and a signed-in customer's messages appear in Discord under their username.
- A channel appears when Discord lets
@everyoneread it and send messages in it, unless it is in Hidden channels. Ticket channels never appear. We check the channels regularly and each time you save the Discord settings, and Sync community channels checks them now. GET /storefront/community/chat/channelslists the channels bychannel_id,nameandtopic, with theinvite_url, the longest message inmax_length, and the limit inrate_limit_secondsandrate_limit_hint.GET /storefront/community/chat/messagesreturns the latest messages of the channel inchannel_id:limitof them (1–100, 50 by default), or older ones withbefore_id. To poll, sendafter_idset to thelatest_idof the last answer, and you get only what is new.POST /storefront/community/chat/sendsendsbody, up to 500 characters, tochannel_id. A customer can send one message every 8 seconds from the web. Send aclient_nonceof your own, up to 64 characters, so that a retry returns the first message instead of sending a second.GET /storefront/community/chat/statusreturns the customer'shandle, and the seconds before they can send again incooldown_secondsandmuted_seconds.
Messages from your site reach Discord through a webhook, under the customer's username. When the bot lacks Discord's Manage Webhooks permission, it posts them itself, with the username in front. We keep up to 500 messages per channel, none older than 30 days.
Customer names in the community
Section titled Customer names in the communityPosts, messages and profiles show each customer's username, which the community calls their handle. Register a customer gives its rules, and PATCH /auth/me with chat_handle changes it. While a signed-in customer types a new one, GET /storefront/community/handle-available?handle=... answers available, with the reason when it is not. In the forum, a member can also set a display_name, which cannot be another member's handle.
Moderate the community
Section titled Moderate the communityYour team moderates on the staff console's community page at /staff/community, which works through the staff routes under /staff/community/. GET /staff/community/summary counts what is waiting. The lowest role for each task:
| Task | Lowest role |
|---|---|
| Read forum reports and server listings | Tier 1 support |
| Dismiss a report, quarantine what it points at, or mute its author for up to 7 days | Tier 1 support |
| Hold a listing for review | Tier 1 support |
| Restore or remove reported content | Tier 2 support |
| Hide, show, release or delete a listing | Tier 2 support |
| Pin, lock or hide a thread | Tier 3 support |
| Find members, change their forum role and suspend them | Tier 3 support |
| Review guides, guide comments and guide reports | Tier 3 support |
| Feature a listing, or mute for longer than 7 days | Tier 3 support |
| Add or remove guide moderators | Admin |
Billing, Admin and Owner can do everything Tier 3 support can. Every action goes on the audit log with a name that starts with community., such as community.content_removed or community.listing_held.
Work through forum reports
Section titled Work through forum reportsGET /staff/community/forum/reports lists the open reports, and status set to quarantined, resolved or all shows the others. Each report names the member behind the content and whether they are muted. Every open report on the same content moves with the one you act on.
POST /staff/community/forum/reports/{report_id}/resolvedismisses the report, with an optionalresolution, and leaves the content as it is.POST .../quarantinehides the content, with an optionalnote, until Tier 2 support decides..../restoreputs it back, and.../removedeletes it.POST .../removealso works on content that is still up. The content leaves every list and search engines, and we keep it for the record.POST .../mutewithhoursand an optionalreasonstops the author posting in the forum and the chat. A longer mute already running stays as it is. To lift a mute, or set one in minutes, use/chat-muteas Change the account describes.
Forum members and roles
Section titled Forum members and rolesEvery member holds a forum role. Customers hold member, premium, supreme or ultimate, and the staff roles above them are support, supervisor, architect and administrator, from the lowest. role_labels in the branding block holds the name your site shows for each.
GET /staff/community/forum/membersfinds members:qmatches a handle or an email address, andonlyisall,stafforsuspended.assignablelists the roles you can give.POST /staff/community/forum/members/{handle}/rolewithrolechanges a member's role.POST /staff/community/forum/members/{handle}/suspendwithsuspendand areasonof up to 300 characters suspends a member.suspendset tofalselifts it and gives back their earlier role.
In the forum, your staff act as a supervisor: they can give the roles below it, and act on members who hold them. Owners and admins can give any role.
A customer with a staff role moderates from your site with their own token, under /portal/community/forum/moderation/. They read the reports and resolve one with action set to none, remove or suspend. With threads/{thread_id}/flags they pin, lock or move a thread, or mark it as a duplicate of another. They can change the roles of members below their own. Other members get 403 Forum staff only.
Moderate listings
Section titled Moderate listingsGET /staff/community/listings lists every listing with its owner. only is all, published, hidden, held or featured, and q searches.
POST /staff/community/listings/{listing_id}/holdwith areasonof 3–300 characters takes a listing off the list until Tier 2 support decides.PATCH /staff/community/listings/{listing_id}withhiddenand an optionalreasonhides or shows a listing, whatever its owner chose, and ends a hold.featuredputs a listing at the top of the list.POST .../releaseputs a held listing back as its owner left it.
Caution
DELETE /staff/community/listings/{listing_id} deletes the listing and its ratings, and cannot be undone. The owner can list the server again from the start, so hide a listing that should stay off the list.
Review guides
Section titled Review guidesTier 3 support reviews guides from GET /staff/community/guides/queue, and approves or rejects guides, comments and guide reports under /staff/community/guides/. Rejecting a guide needs a reason of 3–500 characters, which the author reads.
Guide moderators are customers you trust to do the same from your site. An admin adds one with POST /staff/community/guides/moderators and the customer's customer_id, and removes one with DELETE .../moderators/{customer_id}. A moderator works through GET /portal/community/guides/moderation with their own token, and approves or rejects under /portal/community/guides/moderation/. Other customers get 403 Moderator access required.
The moderation filter
Section titled The moderation filterForum posts, guide comments and chat messages go through a moderation filter. Text with a slur is refused with 422. In chat messages and guide comments, other words the filter lists are replaced with asterisks. A customer the chat refuses more than three times in an hour is muted there for an hour. Usernames are held to the same filter. Ask support to add words your community should not see.
Keep the forum in search engines
Section titled Keep the forum in search enginesWhen Coritan serves your storefront's site, its sitemap and llms.txt list the forum's best threads. We score each thread and member page, and the score puts it in one of three tiers:
| Tier | What it means |
|---|---|
excluded |
Kept out of search engines. |
index |
In the sitemap, highest scores first. |
llms |
Also in llms.txt, with the accepted answer. It needs a higher score, and an accepted answer or a reply from forum staff. |
A thread scores for how much it says, its replies and the people taking part, its votes, reactions and views, whether it was answered, and how recently it was active. Threads on a board that search engines do not index stay excluded, and a member can keep their own profile out with index_opt_out. We score a thread again each time it changes, such as a reply, a vote, an accepted answer or a moderator's action.
An owner or admin reads the totals, the reasons threads are left out and the scoring policy with GET /admin/community/forum/seo. POST /admin/community/forum/seo/preview with thread_id or handle explains one verdict, and POST /admin/community/forum/seo/rescore scores every thread and profile again.
Result
Section titled ResultGET /storefront/branding shows enabled: true for each part you turned on, and its public routes answer anyone. Customers list their servers, post, write guides and chat from your site, and what they report reaches your team on the staff console's community page.
Troubleshooting
Section titled Troubleshooting404 Community forum is not enabled,Community guides are not enabledorCommunity server list is not enabled- That part is off for your organization. Ask support to turn it on.
The community forum is not enabled for this brandorCommunity guides are not enabled for this brand- A staff route for a part that is off. Ask support to turn it on.
404 Community chat is not enabled- Tick Mirror public channels on the storefront in your Discord settings, and check that Integration enabled is ticked.
- The chat shows no channels
- A channel shows only when Discord lets
@everyoneread it and send messages in it, and it is not in Hidden channels. After you change a channel's permissions in Discord, choose Sync community channels. No Discord server configured- Syncing the channels needs your server's ID. Enter the Server (guild) ID and save.
403 Support access required,403 Tier 2 support access requiredor403 Admin access required- The member's role is below what the task needs. Moderate the community lists the lowest role for each.
Your tier mutes for up to 7 days; ask Tier 3 for longer- Tier 1 and Tier 2 support mute for up to 168 hours. Ask a member with Tier 3 support or a higher role.
Featuring a listing is for Tier 3- Ask a member with Tier 3 support or a higher role to feature it.
This report's content is quarantined; restore it or remove it instead- A quarantined report closes when Tier 2 support restores or removes the content.
Publishing requires at least one tag- Add a tag from your list to
tags. Publishing requires an active join address for this server- Your list takes only servers that players can join. Publish once the server's join address is active.
That community URL slug is already taken- Another listing in your organization uses that
slug. Choose another. 429 You are posting too quickly. Try again a little later.- The member passed an hourly limit for threads, replies, wall posts or wall comments.
429 You are muted in the community for another …- Your staff muted the member.
Retry-Aftergives the seconds left. 403 Your forum access is suspended.- Your staff suspended the member from the forum. When they gave a reason, the message is the reason instead.
422 That message breaks the community rules. Keep it civil and try again.- The moderation filter refused the text. In the chat, more than three refusals in an hour mute the customer for an hour.
429 You cannot post in community chat right now. Try again in …- The customer is muted in the chat.
muted_secondsinGET /storefront/community/chat/statuscounts down. 429withYou can send one message every 8 seconds from the web. …- The customer sent a message less than 8 seconds ago. Wait for
Retry-After, or forcooldown_secondsfromchat/statusto reach0. Invite links to other servers are not allowed here.- Chat messages cannot carry a Discord invite link.
Keep it under 500 characters. …- Chat messages take up to 500 characters. Read
max_lengthfromchat/channelsand hold your composer to it. 403 Customer contributions are disabled- Your guides do not take guides from customers. Ask support to turn contributions on.
A proposal is already pending validation- The guide has an edit waiting for a moderator. Withdraw it with
POST .../proposal/withdraw, or wait for the decision. 403 Moderator access requiredor403 Forum staff only- The customer is not a guide moderator, or holds no staff role in the forum.
Related
Section titled Related- Build a storefront on the Organization API
- Show your catalogue with the Storefront API
- Let customers run their servers
- Connect a Discord server
- The staff console
- Organization roles and permissions
- Read the organization audit log
With the API
Section titled With the APIEach group of routes takes its own credential, sent as Authorization: Bearer:
| Routes | Credential |
|---|---|
/storefront/community/... |
None to read. Rating a server, commenting on a guide, voting on it or reporting it, sending a chat message, chat/status and handle-available take the customer's token, $CUSTOMER_TOKEN. |
/portal/community/... and /portal/services/{service_id}/community-listing |
The customer's token. |
/staff/community/... |
A member's console session or Coritan access token, $STAFF_TOKEN, as The staff console explains. |
/admin/community/... |
An owner's or admin's Coritan access token, $CORITAN_TOKEN. |
Start a thread as a customer:
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/portal/community/forum/threads" \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"category_slug": "help", "title": "Players cannot join after the 1.21 update", "body_markdown": "Since the update, players are disconnected as they join. What should I change?", "kind": "question"}'
Quarantine what a report points at, as a member with Tier 1 support or a higher role:
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/staff/community/forum/reports/318/quarantine" \
-H "Authorization: Bearer $STAFF_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note": "Advertises another host"}'
The answer names what was hidden, such as {"ok": true, "quarantined": "post", "id": 9051}.
Explain why a thread is in search engines or left out, as an owner or admin:
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/admin/community/forum/seo/preview?thread_id=2207" \
-H "Authorization: Bearer $CORITAN_TOKEN"
An owner or admin can also manage guide moderators and approve or reject guides under /admin/community/guides/. The staff routes record each decision in the audit log, and the admin routes do not.
The API reference lists every route with its parameters and answers:
| Routes | Reference |
|---|---|
/storefront/community/... |
Storefront |
/portal/community/... |
Customer portal community |
/portal/services/{service_id}/community-listing |
Customer portal services |
/staff/community/... |
Staff community, with the forum member routes under Staff forum members |
/admin/community/forum/... |
Community forum |
/admin/community/guides/... |
Community guides |