Salesforce APItrailhead.salesforce.com ↗
Search public Salesforce Trailblazer Community questions, read answers, browse topics, and enrich companies with real member profiles via 5 structured endpoints.
What is the Salesforce API?
The Salesforce Trailblazer Community API exposes 5 endpoints for reading public questions, answers, topic lists, and member profiles from trailhead.salesforce.com. Use search_questions to pull questions with author details including real name, company, job title, and location. Use enrich_company to map community members and posts to a specific company or industry. Use find_practitioners to identify unique people posting about specific Salesforce topics.
curl -X GET 'https://api.parse.bot/scraper/28f7279c-bc0c-4efc-8326-c9172b892fc5/search_questions?sort=recent_activity&query=flow&topic_id=0TO4S000000c4vdWAA&answer_status=all' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace trailhead-salesforce-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Salesforce Trailblazer Community — browse topics, search questions, enrich a company, find practitioners."""
from parse_apis.trailhead_salesforce_com_api import (
Trailhead, FeedSort, AnswerStatus, InputNotFound,
)
client = Trailhead()
# Browse featured topic categories and pick the first topic from each.
for cat in client.topic_categories.list(limit=3):
print(cat.category)
for topic in cat.topics[:3]:
print(f" {topic.name} ({topic.id})")
# Search unanswered questions, newest first — cap at 5 total items.
for q in client.question_summaries.search(
sort=FeedSort.CREATED_DATE,
answer_status=AnswerStatus.UNANSWERED,
limit=5,
):
print(q.title, f"by {q.author.name} at {q.author.company}")
# Drill from a search hit into the full question with all answers.
hit = client.question_summaries.search(query="flow error", limit=1).first()
if hit is not None:
detail = hit.details()
print(detail.title, f"— {detail.answer_count} answers")
for ans in detail.answers[:3]:
print(f" {ans.author.name}: {ans.body[:100]}")
# Point-lookup by an id discovered from the search above.
if hit is not None:
try:
question = client.questions.get(id=hit.id)
print(question.title, question.posted_in.name)
except InputNotFound:
print("Question was deleted")
# Enrich a company to find community members and related posts.
report = client.enrichments.enrich(company="Cognizant", max_posts=10)
print(f"{report.company}: {report.people_count} people, {report.posts_count} posts")
for person in report.people[:3]:
print(f" {person.name} — {person.job_title} at {person.company}")
for post in report.posts[:3]:
print(f" {post.title}: {post.author.name}")
# Find practitioners who discuss specific tools, filtered to US-based admins.
practitioners = client.practitioners.find(
terms="copado,gearset", country="United States", roles="Administrator",
)
print(f"{practitioners.people_count} practitioners across {practitioners.posts_count} posts")
for p in practitioners.people[:5]:
print(f" {p.name} ({p.role}) — {p.post_count} posts, matched: {', '.join(p.terms_matched)}")
print("exercised: topic_categories.list / question_summaries.search / details / questions.get / enrichments.enrich / practitioners.find")
Returns one page of public questions from the Trailblazer Community feed, newest first. Each row is one question with its title, plain-text body, hashtags, the topic or group it was posted in, answer count, best-answer id, and the author's public profile (real name, company, job title, role, state/country, ambassador flag). Filters: free-text search over question text, answer status, sort order, and an optional topic restriction given either as topic_id (from list_topics) or as topic_name (a topic display name or URL slug: it is resolved against the featured list_topics catalog first - case-insensitive exact name, otherwise a unique partial match, with an error listing candidates when a partial match is ambiguous - and any name not in that catalog, e.g. 'Copado', is passed to the site, which resolves every community topic by name or slug; an unknown topic returns a not-found error). topic_id and topic_name are mutually exclusive. One upstream call per page, plus one extra call when topic_name is used. Pagination is cursor based: pass next_cursor from a previous response as cursor to fetch the following page; omit cursor for the first page. limit is clamped to 50. Author fields other than name/company are null when the poster has not filled in their profile. A topic-restricted feed also includes questions posted in other topics that tag the requested topic. An empty questions array with has_more=false is a valid result for a narrow search.
| Param | Type | Description |
|---|---|---|
| sort | string | Ordering of results (the feed's Sort dropdown). |
| limit | integer | Number of questions per page; values above 50 are clamped to 50. |
| query | string | Free-text search over question titles and bodies (e.g. 'flow error'). Omitted = no text filter. |
| cursor | string | Opaque continuation token from a previous response's next_cursor. Omit for the first page. |
| topic_id | string | Restrict to questions posted in one community topic; use an id from list_topics.categories[*].topics[*].id. Omitted = all topics and groups. An unknown id returns a not-found error. Cannot be combined with topic_name. |
| topic_name | string | Restrict to one community topic by its display name or URL slug instead of its id (e.g. 'Copado' or 'Sales Cloud'): matched case-insensitively against list_topics names first (a partial name is accepted when it matches exactly one featured topic), otherwise resolved by the site, which knows every community topic. Cannot be combined with topic_id. |
| answer_status | string | Restrict to questions by answer state (the feed's Answer Status dropdown). |
{
"type": "object",
"fields": {
"count": "number of questions in this page",
"has_more": "true when another page exists",
"questions": "array of question objects: id, type, url, title, body (plain text), hashtags (array of topic names), created_at/last_modified_at (ISO 8601 UTC), likes, answer_count, best_answer_id (null when none accepted), posted_in {id, type TOPIC|GROUP, name, url}, author {id, name, profile_url, company, job_title, role, location_state, location_country, is_forum_ambassador}",
"next_cursor": "cursor for the next page, null when has_more is false"
},
"sample": {
"data": {
"count": 1,
"has_more": true,
"questions": [
{
"id": "0D5KX00000jAT7R0AW",
"url": "https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000jAT7R0AW",
"body": "I facilitate a community group in the Trailblazer Community. Is there an option to move it Salesforce hosted Slack community?",
"type": "QUESTION",
"likes": 0,
"title": "Moving a trailblazer group to slack?",
"author": {
"id": "0053A00000CBP8OQAX",
"name": "Roy Moore",
"role": "Architect",
"company": "Compassion International",
"job_title": "Salesforce Guy",
"profile_url": "https://trailblazers.salesforce.com/profileView?u=0053A00000CBP8OQAX",
"location_state": "Colorado",
"location_country": "United States",
"is_forum_ambassador": false
},
"hashtags": [
"Slack Community",
"Slack"
],
"posted_in": {
"id": "0TO30000000Dt7IGAS",
"url": "https://trailhead.salesforce.com/trailblazer-community/topics/slackcommunity",
"name": "Slack Community",
"type": "TOPIC"
},
"created_at": "2026-09-11T17:20:03.000Z",
"answer_count": 0,
"best_answer_id": null,
"last_modified_at": "2026-09-11T17:20:03.000Z"
}
],
"next_cursor": "MjAyNi0wOS0xMVQxNzoyMDowM1osMEQ1S1gwMDAwMGpBVDdSMEFXLCw0LA"
},
"status": "success"
}
}About the Salesforce API
What the API covers
Five endpoints cover the public Trailblazer Community feed. search_questions returns paginated questions with each post's title, plain-text body, hashtags, topic group, answer count, best-answer id, and the author's public profile (name, company, job title, role, location state and country). Results can be filtered by free-text query, topic_id or topic_name, answer_status, and sort order. Pages are capped at 50 questions; the next_cursor field drives pagination.
Retrieving full threads and topics
get_question takes a single question_id and returns the full question plus all answers in posting order. Each answer includes its author's profile, body text, like count, and an is_best_answer flag. Answers are fetched up to 250 per call; answers_truncated signals when more exist on the site. list_topics returns the community's featured topic filters grouped by category (Featured Product Topics, Featured Other Topics, Featured Solution Topics), each with an id you can pass directly to search_questions as topic_id.
Company and practitioner enrichment
enrich_company accepts a company name, an industry term, or both. It returns a posts array of matching community posts and a people array of member profiles whose public company field contains the supplied term. The people_detail_truncated flag indicates when more than 25 matched members were found and the remainder lack enriched profile fields. find_practitioners takes comma-separated terms and searches each separately, then deduplicates results to one row per unique author. Optional filters — country, roles, require_company, exclude_companies, created_after, created_before — allow precise audience segmentation without post-processing.
The Salesforce API is a managed, monitored endpoint for trailhead.salesforce.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when trailhead.salesforce.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official trailhead.salesforce.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Monitor new Salesforce product questions by topic to identify recurring customer pain points.
- Build a prospect list of Salesforce administrators and developers by company using enrich_company.
- Find practitioners using specific DevOps tools (Copado, Gearset) by running find_practitioners with those terms.
- Track community sentiment around a Salesforce release by searching questions with a version keyword and filtering by date.
- Identify unanswered questions in a specific topic to surface support gaps using the answer_status filter.
- Enrich a company account in a CRM with real community members and their posted questions using enrich_company.
- Segment community members by role and country for regional go-to-market research using find_practitioners filters.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.