Member counts
You don't need to set anything up. When you submit a community, RootPit opens its Root invite page and reads the community name and member count Root shows there. We re-check every live listing at least once a day (and whenever a listing is viewed after 12 hours), and owners can press Refresh members in the dashboard. Invites that fail three checks in a row are hidden until the owner fixes the link.
Live sync with a Root Bridge (optional)
A Bridge pushes updates the moment they happen, proves you manage the community, and is how you claim a listing someone else added. Each community listing can have a private webhook URL:
POST https://rootpit.com/api/public/root-webhook?token=<secret>
Paste it into a Bridge in your Root community (Create channel → App channel → Bridge) and enable Community Name, Community Icon, and Member Count. Get the URL from Dashboard → Live sync. Each delivery updates your member count, name, and icon.
What we read
| Field | Payload location | Effect |
|---|---|---|
| Root community ID | communityId | Binds the listing to one Root community on first delivery |
| Member count | data.community.memberCount or data["Member Count"] | Updates the member count and the "verified" timestamp |
| Name | data.community.name or data["Community Name"] | Renames the listing (2 to 80 characters, no links or mass mentions) |
| Icon | data.community.iconUrl or data["Community Icon"] | Replaces the icon (https only) |
The token can also be sent as Authorization: Bearer <secret> instead of the query string.
Security model
Root doesn't sign Bridge payloads, so the URL is the credential. Treat it like a password.
- We store only a SHA-256 hash of your token. We can't show it to you again. If you lose it, rotate it from your dashboard. Rotating immediately disables the old URL.
- After the first delivery, the listing is bound to that Root community ID. Deliveries from any other community are rejected with
409, so a leaked URL can't be pointed at a different community. - Deliveries are rate limited (30 per hour per listing, 60 per minute per IP) and bodies are capped at 64 KB.
- If Root sends
webhook-id/webhook-timestampheaders, we reject timestamps more than 5 minutes off and ignore duplicate delivery IDs. - Every delivery is logged for 30 days. See Dashboard → Live sync for status codes and outcomes.
- If your Bridge renames an approved listing, you get a notification so unexpected changes are visible.
Responses
| Status | Meaning | Retry? |
|---|---|---|
200 | Processed (response lists updated fields) | n/a |
400 | Body isn't JSON, stale timestamp | No |
401 / 404 | Missing, malformed, or unknown token | No, rotate the URL |
409 | Wrong Root community, or community already listed | No |
413 | Payload too large | No |
429 | Rate limited (Retry-After header) | Yes, later |
5xx | Our problem | Yes, with backoff |
Ownership claims
Imported or disputed listings can be claimed. Claim this listing gives you a one-time Bridge URL. If the delivery comes from the Root community the listing is already bound to, ownership transfers automatically; otherwise a moderator confirms the claim.
Bot REST API
Used by the RootPit Root bot. All endpoints require the X-RootPit-Key header and return JSON. Errors return { "error": string }.
| Method | Path | Body / query | Notes |
|---|---|---|---|
POST | /api/public/v1/bump | { listing_id, type } | Same 2-hour cooldown as the site; 429 while cooling down |
POST | /api/public/v1/review | { listing_id, type, root_user_id, root_username, rating (1 to 5), body? } | One review per Root user per listing (updates on repeat) |
GET | /api/public/v1/listing-status | ?listing_id=&type= | Votes, bumps, rating, badges, status |
POST | /api/public/v1/bot-installed | { listing_id, type, installed } | Marks whether the RootPit bot is installed |
type is "community" or "bot"; listing_id is the listing's UUID.
Health
GET /api/health returns 200 {"ok":true} when the site can reach its database and 503 otherwise, so it works with uptime monitors.