> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cativa.digital/llms.txt
> Use this file to discover all available pages before exploring further.

# Communities and Spaces

> The Community > Space > Group > Post/Course hierarchy and what partners can create via API.

Cativa organizes content in a four-level hierarchy. Understanding this hierarchy is essential to know **which endpoint to call** and **what can be created via API** versus what's configured by the admin in the dashboard.

## The hierarchy

```
Community (the entire tenant platform)
└── Space (thematic area, e.g. "Trading", "Mentoring")
    └── Group (sub-community inside the space)
        ├── Post (feed publication)
        ├── Comment (comment on a post)
        └── Course (sequence of lessons, optional)
```

Every tenant has **exactly one Community** (the customer's whole site). Inside it, the admin creates multiple **Spaces**, each with its own **Groups**. Groups contain **Posts**, **Comments** and, optionally, **Courses**.

<Note>
  The difference between Space and Group is easy to remember: **Space** is the thematic division shown in the main navigation; **Group** is where conversation happens and where badge-based permissions are applied.
</Note>

## Who creates what

The general rule: **structure is the admin's job, content is the partner's job**.

| Resource  | Via API (partner)               | In admin dashboard                   |
| --------- | ------------------------------- | ------------------------------------ |
| Community | No                              | Yes (created on tenant provisioning) |
| Space     | Typically no — admin scope only | Yes                                  |
| Group     | Typically no — admin scope only | Yes                                  |
| Post      | **Yes**                         | Yes                                  |
| Comment   | **Yes**                         | Yes                                  |
| Course    | Typically no — admin scope only | Yes                                  |

<Warning>
  Endpoints to create Space, Group and Course exist but require **admin scope**. Partner keys with default scope (recommended) cannot reach them. Ask the tenant admin to set up the structure in the dashboard — that's the natural flow.
</Warning>

## Access control: badge gates the group

Each **Group** can require one or more **badges** for a user to enter. This is configured in the admin dashboard, on each group's access screen:

```
Group "VIP Members"  ----requires----> Badge "Premium"
Group "Mentors"      ----requires----> Badge "Mentor"
Group "Open"         ----no badge required----> any user can enter
```

The partner **does not configure** this rule — it lives in the admin. But the partner **triggers** the transition: by assigning a badge to the user, they automatically gain access to every group that accepts that badge.

See [Badges as Permissions](/en/concepts/badges-as-permissions) for the full explanation.

## Read endpoints

Even without being able to **create** structure, you almost always need to **read** Spaces and Groups to show them to the user in your app, or to discover IDs before creating Posts.

### List spaces

```bash theme={null}
curl https://apis.cativalab.digital/tenant/v1/community/spaces \
  -H "Authorization: Bearer cativa_live_..."
```

### List groups (filter by space)

```bash theme={null}
curl "https://apis.cativalab.digital/tenant/v1/community/groups?spaceId=01HQ0..." \
  -H "Authorization: Bearer cativa_live_..."
```

## Creating posts

Posts live inside a Group. You need the `groupId` before calling — fetch it via the listing above or store it at onboarding.

<Note>
  The post author is always the user associated with the authenticated credential — you do not (and cannot) send `authorId` in the body.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://apis.cativalab.digital/tenant/v1/community/posts \
    -H "Authorization: Bearer cativa_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "groupId": "01HQ5ABCDEF1234567890XYZ",
      "content": "Welcome to the group!"
    }'
  ```

  ```js Node theme={null}
  const res = await fetch('https://apis.cativalab.digital/tenant/v1/community/posts', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      groupId: '01HQ5ABCDEF1234567890XYZ',
      content: 'Welcome to the group!'
    })
  });
  const post = await res.json();
  ```
</CodeGroup>

The user tied to the credential must **have access** to the group (at least one matching badge, or membership in the "Open" group). Otherwise the call returns `403 forbidden`.

## Creating comments

```bash theme={null}
curl -X POST https://apis.cativalab.digital/tenant/v1/community/posts/01HQ8.../comments \
  -H "Authorization: Bearer cativa_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Loved this post!"
  }'
```

Same access rule: the user tied to the credential must have permission to see the post.

## Anti-pattern: create one group per customer via API

<Warning>
  Don't model "one group per customer". Groups are **static** entities defined by the tenant admin — they represent discussion communities, not ephemeral containers. To customize access per customer, **use badges**: create a single "VIP Members" group and assign the `Premium` badge to the right customers.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="Badges as Permissions" icon="shield-check" href="/en/concepts/badges-as-permissions">
    How to use badges to grant group access without creating new structure.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/en/concepts/webhooks">
    Receive events when posts are created, users join groups, etc.
  </Card>
</CardGroup>
