# Create a community

> Create an Ur Next Door community with the API: a unique name, HTML description, visibility and icon. Create it now (201) or schedule it (202).

Source: https://docs.urnextdoor.com/guides/create-community/

A community is a topical group with its own feed and its own address (`{slug}.urnextdoor.com`). Creating one with the API works like the website's create form: you choose a name, and optionally a description, who can see and join it, and an icon.

**Endpoint:** `POST /api/v1/communities` · **Scope:** `content` · **Quota:** `community`

## Fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | The community name. It must be unique. |
| `description` | string | No | What the community is about, as HTML. |
| `visibility` | string | No | Who can see and join it. One of: `public`, `ask_to_join`, `private`. |
| `icon_url` | string | No | One of the paths returned by GET /community-icons. |
| `scheduled_at` | string (date-time) | No | Publish later instead of now. ISO 8601 with an offset or Z, at least 5 minutes and at most 180 days ahead. Stored in UTC. |

## Visibility

| Value | Meaning |
| --- | --- |
| `public` | Anyone can join. Content is public and indexed by search engines. |
| `ask_to_join` | Discoverable, but content is for members only. People ask to join. |
| `private` | Invite only, and hidden from non-members. |

Non-public communities are not indexed by search engines. You can change visibility later in the community's settings on the website.

## Pick an icon

`icon_url` must be one of the built-in icons. Get the list from `GET /api/v1/community-icons` (scope `read`) and send one of the paths exactly as returned:

**cURL**

```bash
curl "https://urnextdoor.com/api/v1/community-icons" \
  -H "Authorization: Bearer $UND_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/community-icons", {
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
  },
});
console.log(res.status, await res.json());
```

**Python**

```python
import os

import requests

api_key = os.environ["UND_API_KEY"]

response = requests.get(
    "https://urnextdoor.com/api/v1/community-icons",
    headers={
        "Authorization": f"Bearer {api_key}",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

```php
<?php
$apiKey = getenv('UND_API_KEY');

$ch = curl_init('https://urnextdoor.com/api/v1/community-icons');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
    ],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

echo $status, PHP_EOL, $body, PHP_EOL;
```

Sample response: `200 OK`

```json
{
  "ok": true,
  "items": [
    "/avatars/community/running.png",
    "/avatars/community/books.png"
  ],
  "request_id": "9f8e7d6c5b4a3921"
}
```

## Create a community now

A successful create answers `201 Created` with the new community's `id`, `slug`, `url` and `web_url`:

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/communities" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Morning Runners Pune",
  "description": "<p>Early runs, routes and race plans around Pune.</p>",
  "visibility": "public",
  "icon_url": "/avatars/community/running.png"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/communities", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    name: "Morning Runners Pune",
    description: "<p>Early runs, routes and race plans around Pune.</p>",
    visibility: "public",
    icon_url: "/avatars/community/running.png",
  }),
});
console.log(res.status, await res.json());
```

**Python**

```python
import os
import uuid

import requests

api_key = os.environ["UND_API_KEY"]

response = requests.post(
    "https://urnextdoor.com/api/v1/communities",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Morning Runners Pune",
        "description": "<p>Early runs, routes and race plans around Pune.</p>",
        "visibility": "public",
        "icon_url": "/avatars/community/running.png",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

```php
<?php
$apiKey = getenv('UND_API_KEY');

$payload = [
    'name' => 'Morning Runners Pune',
    'description' => '<p>Early runs, routes and race plans around Pune.</p>',
    'visibility' => 'public',
    'icon_url' => '/avatars/community/running.png',
];

$ch = curl_init('https://urnextdoor.com/api/v1/communities');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
        'Idempotency-Key: ' . bin2hex(random_bytes(16)),
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

echo $status, PHP_EOL, $body, PHP_EOL;
```

Sample response: `201 Created`

```json
{
  "ok": true,
  "id": 5,
  "slug": "morning-runners-pune",
  "url": "/communities/morning-runners-pune",
  "web_url": "https://urnextdoor.com/communities/morning-runners-pune",
  "item": {
    "id": 5,
    "type": "community",
    "slug": "morning-runners-pune",
    "name": "Morning Runners Pune"
  },
  "request_id": "9f8e7d6c5b4a3921"
}
```

The name must be unique. If a community with that name already exists, the request answers `409 conflict`.

## Schedule a community

With `scheduled_at`, the community is **not created yet**. Ur Next Door keeps your request and creates the community at the time you chose. The response is `202 Accepted`, and its `id` is a **scheduled-creation id**, not a community id:

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/communities" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Morning Runners Pune",
  "description": "<p>Early runs, routes and race plans around Pune.</p>",
  "visibility": "ask_to_join",
  "scheduled_at": "2026-10-20T09:30:00Z"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/communities", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    name: "Morning Runners Pune",
    description: "<p>Early runs, routes and race plans around Pune.</p>",
    visibility: "ask_to_join",
    scheduled_at: "2026-10-20T09:30:00Z",
  }),
});
console.log(res.status, await res.json());
```

**Python**

```python
import os
import uuid

import requests

api_key = os.environ["UND_API_KEY"]

response = requests.post(
    "https://urnextdoor.com/api/v1/communities",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Morning Runners Pune",
        "description": "<p>Early runs, routes and race plans around Pune.</p>",
        "visibility": "ask_to_join",
        "scheduled_at": "2026-10-20T09:30:00Z",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

```php
<?php
$apiKey = getenv('UND_API_KEY');

$payload = [
    'name' => 'Morning Runners Pune',
    'description' => '<p>Early runs, routes and race plans around Pune.</p>',
    'visibility' => 'ask_to_join',
    'scheduled_at' => '2026-10-20T09:30:00Z',
];

$ch = curl_init('https://urnextdoor.com/api/v1/communities');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
        'Idempotency-Key: ' . bin2hex(random_bytes(16)),
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

echo $status, PHP_EOL, $body, PHP_EOL;
```

Sample response: `202 Accepted`

```json
{
  "ok": true,
  "status": "scheduled",
  "type": "community",
  "id": 5,
  "name": "Morning Runners Pune",
  "scheduled_at": "2026-10-20T09:30:00Z",
  "request_id": "9f8e7d6c5b4a3921"
}
```

What to know about scheduled communities:

- Use the scheduled-creation id with the scheduling endpoints and the type `community`: `GET /api/v1/scheduled` lists it, and you can reschedule it, publish (create) it now, or cancel it. See [Manage scheduled content](https://docs.urnextdoor.com/guides/manage-scheduled.md).
- The name is checked when you schedule and again when the time comes. If someone else takes the name in between, the creation fails and you are notified.
- Until it is created there is no community page, so `url` and `edit_url` are `null` in the scheduled list.
- It counts against today's `community` quota when you schedule it.

## After it is created

You can post into the new community with its `id` or `slug` (see [Create a post](https://docs.urnextdoor.com/guides/create-post.md)), and manage its settings, members and editors on the website as usual.

## Common errors

| Status and code | Cause | Fix |
| --- | --- | --- |
| `409 conflict` | A community with that name exists | Choose another name |
| `422 validation_failed` | Missing name, an unknown `visibility`, or an `icon_url` that is not a built-in icon | Fix the field named in `errors` |
| `429 quota_exceeded` | Today's community quota is used up (it is small: 2 a day on Free) | Wait until 00:00 UTC |

## Next steps

- [Create a post](https://docs.urnextdoor.com/guides/create-post.md) in your new community.
- [Manage scheduled content](https://docs.urnextdoor.com/guides/manage-scheduled.md), including scheduled communities.
- [Rate limits and daily quotas](https://docs.urnextdoor.com/limits.md).
