# Create a community

Create a community under your brand from your own systems, with its type, access settings, and first members.

A community is the top-level space your members join; groups and their videos live inside it. This endpoint creates one the same way **Manage** > **Communities** > **Create** does in Brand Control Center. Use it to create communities from an onboarding flow, a campaign tool, or a migration script. [Create communities and groups](https://begenuin.com/developers/get-started/any-business/create-communities-and-groups) explains how the two fit together.

The account behind your access token becomes the community's leader, and your brand's owner account is added as a moderator a moment later. See [Generate an access token](https://begenuin.com/developers/developer-resources/api/generate-access-token-using-authentication-api) for the token.

## Endpoint

`POST /api/thirdparty/community/create`

| Environment | Base URL |
| --- | --- |
| Production | https://api.begenuin.com |
| QA | https://api.qa.begenuin.com |

Send the token as a bearer token in the `Authorization` header, and the fields as a JSON body with the `Content-Type: application/json` header.

## Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| handle | string | Required | The community's URL handle, 3 to 24 characters. Genuin stores it in lowercase, and it has to be unique across all of Genuin. |
| name | string | Required | The display name. Leading and trailing spaces are trimmed, and at least one character has to remain. |
| type | integer | Required | 1 for a public community, 2 for a private one. Members join a private community by invitation or by an approved join request. |
| actions | array | Required | Who can create groups in the community. See Actions. |
| description | string | Optional | Up to 400 characters. Hashtags in the text are kept as written. |
| tags | string | Required with description | Comma-separated discovery tags, such as trailrunning,races. Required when you send a description, otherwise optional. |
| dp | string | Optional | File name of the profile image. Upload it first; see Upload an image. |
| banner | string | Optional | File name of the banner image, uploaded the same way. |
| users | array | Optional | First members, each {"user_id": "<uuid>"} or {"phone_number": "<digits>"}. They're added after the response is sent. |
| community_id | string | Optional | A UUID to use as the community's id, when your system assigns ids. |
| brand_id | integer | Optional | Defaults to the brand your token belongs to. Another brand's id works only when your account is a user of that brand. |
| is_ai_generated | boolean | Optional | Marks the community as AI-generated. Default false. |
| is_ai_generated_dp, is_ai_generated_banner | boolean | Optional | true when the image came from Genuin's generation flow, so it's copied from the generation bucket. Default false. |
| language | string | Optional | Language code, such as en. |
| location | object | Optional | {"latitude": <-90 to 90>, "longitude": <-180 to 180>}. |

Fields that aren't listed are dropped without an error. In particular, `categories` isn't a parameter of this endpoint.

### Actions

`actions` sets who can create groups in the community. Send exactly one entry: the `action_id` for the community type, with one of its two options.

| Community type | action_id | access_type_id | Who can create groups |
| --- | --- | --- | --- |
| 1 (public) | 1 | 1 | All community members |
| 1 (public) | 1 | 2 | Admins only |
| 2 (private) | 2 | 3 | All community members |
| 2 (private) | 2 | 4 | Admins only |

A missing action, a second action, or an `access_type_id` that doesn't belong to the action returns `412` with code `5166`. Admins are the community's leader and moderators.

### Upload an image

`dp` and `banner` name files that already exist in Genuin's media storage. To upload one, request a signed URL with the same bearer token, then send the bytes to it:

```bash title="cURL"
curl -X POST https://api.begenuin.com/api/v3/users/video/upload/create_upload_url \
  -H "Authorization: Bearer {{GN_ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{ "contentType": "image/png", "path": "uploads/profile_images/community/{{DP_FILE}}" }'
```

```bash title="cURL"
curl -X PUT "{{UPLOAD_URL}}" -H "Content-Type: image/png" --data-binary @dp.png
```

Pass the file name, such as `trail-runners-dp.png`, as `dp`. Banners go under `uploads/community/banner/`. The signed URL accepts one PUT and expires after a short time, so request it right before the upload.

## Returns

Returns `200 OK` with the new community's id, share URL, image URLs, colors, and the leader's member object. The community is live as soon as the response arrives: its share URL opens and the leader can post.

Three things finish asynchronously and can lag the response by a few seconds: the first members from `users`, the moderator role for your brand owner, and search indexing.

## Request

```bash title="cURL"
curl -X POST https://api.begenuin.com/api/thirdparty/community/create \
  -H "Authorization: Bearer {{GN_ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{
    "handle": "trail-runners",
    "name": "Trail Runners",
    "description": "Weekly routes, gear talk, and race recaps #trailrunning",
    "tags": "trailrunning,races",
    "type": 1,
    "actions": [{ "action_id": 1, "access_type_id": 1 }],
    "users": [{ "user_id": "{{USER_ID}}" }]
  }'
```

## Response

```json title="Response"
{
  "code": 200,
  "message": "XXXX-[Community has been created successfully.]",
  "data": {
    "community_id": "0a2be302-04af-4642-a436-1612554e48a6",
    "share_url": "https://community.example.com/community/trail-runners",
    "dp": null,
    "banner": null,
    "color_code": "#A4E6DA",
    "text_color_code": "#49CDB5",
    "leader": {
      "member_id": "0bf977ed-4887-4056-a8f4-1f0de71101f1",
      "name": "Example Brand",
      "bio": null,
      "nickname": "examplebrand",
      "phone": null,
      "is_brand_system_user": true,
      "is_avatar": false,
      "brand": { "brand_id": 1429, "brand_slug": "example-brand", "brand_user_logo": null },
      "profile_image": "https://media.begenuin.com/uploads/profile_images/1706610191569_Vector.png",
      "profile_image_s": "https://media.begenuin.com/uploads/profile_images/s/1706610191569_Vector.png",
      "profile_image_m": "https://media.begenuin.com/uploads/profile_images/m/1706610191569_Vector.png",
      "profile_image_l": "https://media.begenuin.com/uploads/profile_images/l/1706610191569_Vector.png"
    }
  }
}
```

`share_url` combines your brand's community domain with the community's slug, which Genuin derives from the name and handle. `color_code` is picked from Genuin's palette and backs the community card until a profile image is set. Keep `community_id`: every later call, such as adding members, adding moderators, or creating a group, takes it.

## Errors

Every error response carries an HTTP status, a string `code`, a `message`, and a `data` object. Match on `code`.

| HTTP status | code | Cause | Fix |
| --- | --- | --- | --- |
| 400 Bad Request | none | A field failed validation. data.message names the failing fields, such as handle, type; there's no top-level code or message. | Check the types, lengths, and required fields in the Parameters table. |
| 401 Unauthorized | 5159 | You sent a brand_id your account isn't a user of. | Omit brand_id, or use the brand your token belongs to. |
| 404 Not Found | 5235 | brand_id doesn't match an active brand. | Check the id. |
| 409 Conflict | 5216 | The handle is taken. Message: XXXX-[community handle already exists.]. | Pick another handle. |
| 409 Conflict | 5217 | The dp file name is already used by another community. | Upload the image under a new file name. |
| 412 Precondition Failed | 5166 | actions doesn't match the community type. | Send one entry from the Actions table. |
| 400 Bad Request | 1099 | The server couldn't process the request. | Retry once. If it persists, contact the Genuin team with the request timestamp. |

## Limitations

- **One leader**: The token's account is the leader, and the API can't transfer leadership. To let a person run the community, add them with [Add moderators to a community](https://begenuin.com/developers/developer-resources/api/assign-moderators-to-community-using-api).
- **Handle is fixed**: There's no API to change a handle after creation.
- **Many-to-one brand**: Communities belong to one brand. A community created with another brand's `brand_id` appears in that brand's Brand Control Center.
- **Rate limit**: There's no rate limit on this endpoint.

## See also

- [Add members to a community](https://begenuin.com/developers/developer-resources/api/add-members-to-a-community-programmatically-api)
- [Add moderators to a community](https://begenuin.com/developers/developer-resources/api/assign-moderators-to-community-using-api)
- [Create a group in a community](https://begenuin.com/developers/developer-resources/api/create-a-group-programmatically-within-community-using-create-group-api)
- [Generate an access token](https://begenuin.com/developers/developer-resources/api/generate-access-token-using-authentication-api)
- [Handle API errors](https://begenuin.com/developers/developer-resources/api/handle-api-errors)
