Community context
Almost everything in Babele is scoped to a community, so most endpoints take a communityId — as a route segment, a query parameter, or a field in the request body. This guide covers where to find your community ID, where the parameter goes, when it is required and when it is optional, and what the API does when you leave it out.
Finding your community ID
Most endpoints require the community ID as an URL parameter, query parameter or in the request body. To find your community ID, login to the Babele platform and check the URL of the page in the browser URL location box. The community ID is the numeric part of the URL that immediately follows /community. In https://app.babele.co/community/1234, the community ID would be 1234. A page whose URL has no /community/{id} segment carries no community context at all.
The API can also tell you:
GET /api/User/GetMyCommunitiesreturns every community the authenticated account belongs to, each with itsidandname. This is the usual way for an integration to discover the IDs it is allowed to use.GET /api/Project/GetOverview?id={id}returns acommunitiesarray naming every community a project is publicly visible in, each with itsidandname. Use it when you know the project but not the community.
What changed: one project, many communities
Babele used to model the project–community relationship as 1:1. A project lived in exactly one community, so a projectId was enough to identify everything about it, and most endpoints never had to ask which community you meant.
That relationship is now N:M, expressed through a link called CommunityProject — one per (community, project) pair. Two consequences drive everything else on this page:
- A project can belong to several communities at once. The same project can be enrolled in one program in community
999and in a different program in community1000, with its own canvas, its own mentors, its own KPI values and its own discussions in each. Asking for "the project" without saying which community is now ambiguous, which is why so many endpoints ask you to name one. - A project can also exist standalone, with no community at all — visitable with no community context. A project can be standalone and belong to communities at the same time. This is why some reads accept no
communityIdrather than demanding one.
What is per-community and what is per-project
Per-community, stored against the CommunityProject link: the business-model canvas — its sections, paragraphs and paragraph comments — program enrolments, the community's project form and the project's answers to it, community-project KPI definitions and KPI values, discussions raised in that community, and the link's own privacy level. None of it is visible from another community.
Per-project, shared across every community the project belongs to: the project's own descriptive fields — name, description, media, location, social links — its sustainable development goals, and its Core Team. The Core Team is a single global list, visible from any community context the project belongs to. Follower, mentor and custom circles may be scoped either to the project or to one community-project link.
Authorization follows the same split. A community administrator's powers stop at their own community's boundary, even for a project that also belongs to a community they do not administer. Programs are strictly per-community: a program attached to one community is never visible from another.
communityId in a request always means "the community whose view of this
project I want". The API resolves the (project, community) pair to a
CommunityProject for you — you never send a CommunityProject ID except
where a field is literally named communityProjectId, as on
POST /api/Survey/survey-response and POST /api/KpiDefinition/Save.
Joining and leaving a community
Two endpoints manage the links directly. They replace the old 1:1 "move into community" behaviour.
POST /api/Project/AddToCommunity
curl -X POST "https://api.babele.co/api/Project/AddToCommunity?projectId=1714&targetCommunityId=1000"
Note the parameter is called targetCommunityId, not communityId. Adding a project that already has an active link returns 409 Conflict (ProjectAlreadyInCommunityException); adding one whose link exists but has been disabled re-enables that link instead of creating a second one. The caller must be an administrator of the target community who also administers one of the communities the project already belongs to — a project that belongs to no community yet can be added by any administrator of the target community.
POST /api/Project/RemoveFromCommunity
curl -X POST "https://api.babele.co/api/Project/RemoveFromCommunity?projectId=1714&communityId=1000"
This one marks the link disabled. It does not delete the project, which goes on existing standalone and in whatever other communities it belongs to. The caller must administer the community being removed from.
Where communityId goes
There are four patterns. Which one an endpoint uses is fixed — check the endpoint's own reference page before you guess. The examples below are trimmed to show placement only; every one of these endpoints also needs the Authorization: Bearer <token> header described under Authentication and Authorization.
A route segment
The community ID is part of the path. It cannot be omitted: leave it out and the route simply does not match, so you get a 404 rather than an API error.
DELETE /api/Methodology/{communityId}/{id}
curl -X DELETE "https://api.babele.co/api/Methodology/999/73"
Other examples: POST /api/Project/{communityId}/bulk/Tag, GET /api/Community/{id}/ApplicationDefinitions.
A query parameter
The most common pattern on GET endpoints. It sits alongside the resource ID.
GET /api/Project/GetOverview
curl -X GET "https://api.babele.co/api/Project/GetOverview?id=1714&communityId=999"
Other examples: GET /api/Project/GetByMethodology, GET /api/KpiReport/GetKpiChartReportsForOverview, GET /api/SurveyForm/GetAll.
A request-DTO field
On writes, the community ID travels in the JSON body next to the rest of the resource. On several endpoints it is not only read but stored, so changing it on an update moves the resource to another community.
POST /api/Survey/survey-definition
curl -X POST "https://api.babele.co/api/Survey/survey-definition" \
-H "Content-Type: application/json" \
-d '{"communityId":999,"formId":1258,"name":"Quarterly impact survey"}'
Other examples: POST /api/ApplicationDefinition, PUT /api/ApplicationDefinition/{id}, PUT /api/Survey/survey-definitions/{surveyId}.
A filter field inside a POST body
List and search endpoints are POST because their filter is a JSON object. communityId is one field of that filter, and it is what scopes the whole query — it is never a wildcard.
POST /api/Project/GetByCommunity
curl -X POST "https://api.babele.co/api/Project/GetByCommunity" \
-H "Content-Type: application/json" \
-d '{"communityId":999,"skip":0,"take":50,"orderBy":0}'
Other examples: POST /api/Community/GetUserList, POST /api/Project/GetUserList, POST /api/Project/GetResourceList.
Required or optional, and why
The N:M change pushed communityId in two directions at once, and the rule of thumb follows from what each endpoint is for:
If the endpoint reads a project and could sensibly answer without a community,
communityIdis optional. Everything else — every write, and every read whose answer only exists inside a community — requires it.
Reads that loosened to optional, so that standalone projects stay reachable. These accept a missing communityId and behave differently, not badly, when you leave the parameter out:
GET /api/Project/GetOverviewGET /api/Project/GetOverviewSummaryGET /api/Project/GetEditInfoOverviewGET /api/KpiDefinition/GetByProjectGET /api/KpiValue/GetPendingPOST /api/Project/GetResourceList— thecommunityIdinside the filter body is nullable
POST /api/Project/Create belongs here too: its body communityId is nullable, and omitting it creates a standalone project rather than failing.
Writes and community-scoped reads that tightened to required. Scope has to be explicit, because the server can no longer infer which community you meant from the project alone:
GET /api/Project/Disable,Follow,Unfollow,ApplyToTeam,IsProjectTeamMember, andDELETE /api/Project/DeletePOST /api/Project/AddToCommunity— astargetCommunityId— andPOST /api/Project/RemoveFromCommunityGET /api/Project/GetByMethodologyGET /api/KpiDefinition/GetByMethodologyGET /api/KpiReport/GetByProject,GetKpiChartReportsForOverviewGET /api/ProjectTracking/Details,SearchOverviewGET /api/Survey/project-survey-definitions,project-survey-responses,user-survey-responsesPOST /api/Community/GetUserList,POST /api/Project/GetUserList— in the filter body
Team membership is the case that surprises people. The Core Team is project-scoped now, yet every team endpoint still requires communityId: it is the authorization and audit context, and it selects the community-project link that memberships and permissions are read through. It is required even though the team list it returns is global.
What happens when you omit it
Omitting an optional communityId
You get the standalone view of the project: the project as it exists in its own right, with every community-scoped field emptied. On GET /api/Project/GetOverview that means the caller must hold a membership of the project itself, and:
pendingParagraphsandopenDiscussionscome back[]form,answersandkpiDefinitionscome backnulldiscussionCount,resourceCountandnetworkCountare0isCommunityAdminandcanEditCirclesarefalseuserInvitationPolicyis4(None)communityIdsis[]andmainCommunityIdisnullcommunitiesis still populated, listing every community the project is publicly visible in
Supply communityId on the same call and you get the project as it exists inside that one community, with its discussions, its pending paragraphs, that community's project form and answers, the applicable KPI definitions and the community-scoped permission flags. See "Get a project overview" on the Projects page for the full field-by-field breakdown.
Omitting a required communityId
A missing communityId is never treated as "all communities". The API treats the absent value as 0, and 0 is not a valid community, so the request goes wrong in one of three ways depending on the endpoint:
500with an error discriminator. The body names the exception in anerrorfield —CommunityNotFoundExceptionorCannotAccessToCommunityException.POST /api/Project/GetByCommunityandPOST /api/Community/GetUserListfail this way.403 Forbidden. Endpoints that check a community permission before querying reject community0as a permission failure.GET /api/ProjectTracking/SearchOverviewandGET /api/KpiReport/GetKpiChartReportsForOverviewbehave this way.200with silently wrong data. This is the dangerous one. Endpoints that resolve the (project, community) pair find nothing for community0and return an empty or partial result with no error at all.GET /api/Project/GetByMethodologyreturns[].POST /api/Project/GetUserListreturns a body, but with a partial team, acountthat is too low,isMemberandisAdminfalseand empty pending arrays.
The first case is the only one that gives you a usable signal. It looks like this:
Response
{
"error": "CommunityNotFoundException",
"errorCode": null,
"message": "An error has occurred."
}
An unexpectedly empty list, or a permission flag that is false when you
expect true, is almost always a missing or wrong communityId rather than a
data problem. Send it explicitly on every endpoint that takes it, and never
rely on a default.
communityId at a glance
| Endpoint | Where it goes | Required? | If you omit it |
|---|---|---|---|
POST /api/Project/GetByCommunity | Filter body | Required | 500 CommunityNotFoundException |
GET /api/Project/GetOverview | Query | Optional | The standalone project view |
GET /api/ProjectTracking/SearchOverview | Query | Required | 403 Forbidden |
GET /api/KpiReport/GetKpiChartReportsForOverview | Query | Required | 403 Forbidden |
POST /api/Community/GetUserList | Filter body | Required | 500 CommunityNotFoundException |
POST /api/Project/GetUserList | Filter body | Required | 200 with a partial team and false permission flags |
GET /api/SurveyForm/GetAll | Query | Required | 200 with an empty list |
POST /api/Survey/survey-definition | Request body | Required | The survey is filed under community 0 |
PUT /api/Survey/survey-definitions/{surveyId} | Request body | Required | Rejected |
POST /api/Survey/survey-response | Body, as communityProjectId | Optional | The response is not linked to any community project |
GET /api/Survey/survey-definition/{id} | Absent | — | Scope comes from the survey definition itself |
GET /api/Project/GetByMethodology | Query | Required | 200 with an empty array |
GET /api/KpiDefinition/GetByMethodology | Query | Required | Nothing, unless projectId is also sent — then 403 Forbidden |
POST /api/KpiDefinition/Save | Body, as communityProjectId | Optional | The definition is program-scoped or project-scoped instead |
DELETE /api/Methodology/{communityId}/{id} | Route segment | Required | Cannot be omitted — the route does not match |
GET /api/Community/{id}/ApplicationDefinitions | Route segment | Required | Cannot be omitted — the route does not match |
POST /api/ApplicationDefinition | Request body | Required | Treated as community 0, and the community lookup fails |
GET /api/ApplicationDefinition/{id} | Absent | — | Derived from the application definition |
POST /api/apikey, GET /api/apikey | Absent | — | API keys belong to a user, not a community |
