Overview
The SENTRY API provides programmatic access to a continuously updated database of Star Citizen citizen and organization data, sourced from Roberts Space Industries. This API is hosted at https://sentry.wildknightsquadron.com/api/v1 and requires no authentication.
Base URL: https://sentry.wildknightsquadron.com/api/v1
Machine-readable spec: /api/v1/openapi.json (also /openapi.json). Interactive Swagger UI: /api/v1/docs.
Behind the Scenes
SENTRY crawls the Star Citizen playerbase 24/7 and updates the database. It discovers new citizens through organization member lists and organizations through citizen profile pages. We self-throttle this process so we aren't putting any load on the RobertsSpaceIndustries.com servers that could even come close to being considered problematic. Check out our Statistics Page to see some of our metrics.
When a citizen or organization that is not in our database is requested via the API our crawler immediately attempts to crawl that page and returns the profile if it exists and adds it to our database.
When a citizen or oganization that is in our database but is not a complete profile (we call this a stub) we immediately crawl that page and provide the full profile.
Newly discovered organizations are crawled immediately (via a priority queue) so we are primarily focused on expanding our database of citizens.
Citizens Endpoint
Endpoint: /api/v1/citizens
GET /api/v1/citizens/{handle}
Retrieve full citizen data.
curl https://sentry.wildknightsquadron.com/api/v1/citizens/Yuka
Example Response
{
"profile": {
"handle": "yuka",
"display_name": "Yuka",
"bio": "Testing Short Bio",
"avatar_url": "/media/5lpzy4cu6dbi8r/heap_infobox/Yuka_new.png",
"citizen_record": "#295799",
"title": "Lt. Colonel",
"enlisted": "Nov 10, 2013",
"fluency": "English",
"location": "United States , Texas",
"website": "https://ExperienceStarCitizen.com",
"probation": false,
"probation_end": null,
"last_fetched": "2025-02-22 18:58:42.522556",
"is_stub": false
},
"memberships": [
{"organization_sid": "WILDKNIGHT", "member_rank": "Commander", "is_main": true, "rank_number": 5, "visibility": "visible"},
{"organization_sid": "[REDACTED]", "member_rank": null, "is_main": false, "rank_number": 0, "visibility": "redacted"}
],
"changes": [
{
"change": 1,
"timestamp": "2025-02-22 18:58:42.524289",
"fields": {
"website": {"old": "https://WildKnightSquadron.com", "new": "https://ExperienceStarCitizen.com"},
"title": {"old": "Citizen", "new": "Citizen"}
}
}
],
"metadata": {
"first_added": "2025-02-22 16:00:37.688924",
"last_fetched": "2025-02-22 18:58:42.522556",
"is_stub": false
}
}
Hidden and redacted org memberships are included. They use placeholder SIDs [HIDDEN] and [REDACTED] (with :N suffixes when a citizen has more than one). Those are not the real orgs HIDDEN and REDACTED. Each membership has a visibility field: visible, hidden, or redacted. If a public membership later becomes redacted, history records a leave of the public SID and a join of a redacted placeholder; SENTRY does not assert they are the same org.
Sub-Resources
/api/v1/citizens/{handle}/{subResource} (e.g., memberships)
/api/v1/citizens/{handle}/{subResource}/{field} (e.g., profile/website)
Search Endpoint
Endpoint: GET /api/v1/search
Fuzzy-search citizens (handle / display name) and organizations (SID / name). Exact matches may queue a live scrape; finalized is false until that finishes. Response shape is unchanged for legacy clients that pass only query.
Query parameters:
query(required). Global search needs 2+ characters. Org-scoped search allows 1+.type=citizen|organization— omit to search both.org=<SID>— citizen hits limited to that org’s memberships. No scrape queue. Match is substring on handle, display name, rank, visibility.org_status=active|left|all— withorg=only (defaultactive).page,per_page(max 200) — org-scoped paging. Response includespage,pages,total.
curl "https://sentry.wildknightsquadron.com/api/v1/search?query=yuka" curl "https://sentry.wildknightsquadron.com/api/v1/search?query=yuka&type=citizen" curl "https://sentry.wildknightsquadron.com/api/v1/search?query=knight&org=TEST&org_status=active&page=1&per_page=20"
Organizations Endpoint
Endpoint: /api/v1/orgs
GET /api/v1/orgs/{sid}
Retrieve full organization data.
curl https://sentry.wildknightsquadron.com/api/v1/orgs/WILDKNIGHT
Example Response
{
"profile": {
"sid": "WILDKNIGHT",
"name": "Wild Knight Squadron",
"description": null,
"member_count": 15,
"last_fetched": "2025-02-22 16:00:37.688924",
"is_stub": false
},
"memberships": [
{"citizen_handle": "yuka", "member_rank": "Commander", "is_main": true, "visibility": "visible"},
{"citizen_handle": "[redacted]", "member_rank": null, "is_main": false, "visibility": "redacted"}
],
"changes": [
{
"change": 1,
"timestamp": "2025-02-22 08:14:46.496846",
"fields": {
"member_count": {"old": null, "new": "15"}
}
}
],
"metadata": {
"first_added": "2025-02-22 08:14:46.496846",
"last_fetched": "2025-02-22 16:00:37.688924",
"is_stub": false
}
}
GET /api/v1/orgs/{sid}/membership_history
Computed join/leave history for an organization. Join is the first time SENTRY observed the citizen in this org. Leave is the last observation after a citizen scrape no longer lists the org. Org roster pages are paged and do not record leaves by themselves.
Query params: page, per_page (max 200), status=all|active|left.
curl "https://sentry.wildknightsquadron.com/api/v1/orgs/WILDKNIGHT/membership_history?status=left"
Example Response
{
"organization_sid": "WILDKNIGHT",
"events": [
{
"citizen_handle": "kleineliebe",
"display_name": "KleineLiebe",
"join_detected": "2025-10-13T17:53:01.873614",
"leave_detected": "2026-07-30T20:05:27.363473",
"status": "left",
"is_main": null,
"current_rank": null,
"visibility": "visible"
}
],
"page": 1,
"pages": 1,
"total": 14,
"active": 31,
"left": 14,
"status": "left"
}
Sub-Resources
/api/v1/orgs/{sid}/{subResource} (e.g., memberships, membership_history)
/api/v1/orgs/{sid}/{subResource}/{field} (e.g., profile/member_count)