# Message endpoints

> Read and send messages, star, pin, mute or archive chats, and run group chats. New chats only with your connections.

Source: https://docs.urnextdoor.com/reference/messages/

All paths are relative to `https://urnextdoor.com/api/v1`. See [API reference](https://docs.urnextdoor.com/reference.md) for the envelope and headers every endpoint shares.

| Endpoint | What it does | Scope | Daily quota |
| --- | --- | --- | --- |
| [`GET /chats`](https://docs.urnextdoor.com/reference/messages/#listChats) | List your chats | `messages` | not counted |
| [`GET /chats/search`](https://docs.urnextdoor.com/reference/messages/#searchChats) | Search your chats | `messages` | not counted |
| [`GET /chats/unread-count`](https://docs.urnextdoor.com/reference/messages/#countUnreadChats) | Count unread messages | `messages` | not counted |
| [`GET /chats/contacts`](https://docs.urnextdoor.com/reference/messages/#listChatContacts) | List who you can message | `messages` | not counted |
| [`GET /chats/starred`](https://docs.urnextdoor.com/reference/messages/#listStarredMessages) | List starred messages | `messages` | not counted |
| [`GET /chats/{key}/messages`](https://docs.urnextdoor.com/reference/messages/#listMessages) | Read a chat's messages | `messages` | not counted |
| [`POST /chats/{key}/messages`](https://docs.urnextdoor.com/reference/messages/#sendMessage) | Send a message | `messages` | `message` |
| [`GET /chats/{key}/search`](https://docs.urnextdoor.com/reference/messages/#searchChat) | Search one chat | `messages` | not counted |
| [`GET /chats/{key}`](https://docs.urnextdoor.com/reference/messages/#getChat) | Read a chat | `messages` | not counted |
| [`POST /chats/{key}/messages/{messageId}/forward`](https://docs.urnextdoor.com/reference/messages/#forwardMessage) | Forward a message | `messages` | `message` |
| [`POST /chats/{key}/messages/{messageId}/react`](https://docs.urnextdoor.com/reference/messages/#reactToMessage) | React to a message | `messages` | `react` |
| [`PUT /chats/messages/{id}/starred`](https://docs.urnextdoor.com/reference/messages/#setMessageStarred) | Star or unstar a message | `messages` | not counted |
| [`POST /chats/{key}/read`](https://docs.urnextdoor.com/reference/messages/#markChatRead) | Mark a chat read | `messages` | not counted |
| [`POST /chats/{key}/pins`](https://docs.urnextdoor.com/reference/messages/#pinMessage) | Pin a message | `messages` | not counted |
| [`PUT /chats/{key}/state`](https://docs.urnextdoor.com/reference/messages/#setChatState) | Archive, pin or mute a chat | `messages` | not counted |
| [`POST /chats/groups`](https://docs.urnextdoor.com/reference/messages/#createGroup) | Start a group chat | `messages` | `message` |
| [`POST /chats/groups/{slug}/members`](https://docs.urnextdoor.com/reference/messages/#addGroupMember) | Add a member to a group | `messages` | `message` |
| [`POST /chats/groups/{slug}/role`](https://docs.urnextdoor.com/reference/messages/#setGroupRole) | Set a group member's role | `messages` | not counted |
| [`POST /chats/groups/{slug}/rename`](https://docs.urnextdoor.com/reference/messages/#renameGroup) | Rename a group | `messages` | not counted |
| [`POST /chats/groups/{slug}/icon`](https://docs.urnextdoor.com/reference/messages/#setGroupIcon) | Set a group's icon | `messages` | not counted |
| [`POST /chats/groups/{slug}/leave`](https://docs.urnextdoor.com/reference/messages/#leaveGroup) | Leave a group | `messages` | not counted |

## List your chats {#listChats}

`GET https://urnextdoor.com/api/v1/chats`

Your chats, newest first. filter=archived for archived ones.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `listChats`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `filter` | query | No | archived for archived chats. |

### Example

**cURL**

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

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats", {
  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/chats",
    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/chats');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {items, unread, archived_count}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Search your chats {#searchChats}

`GET https://urnextdoor.com/api/v1/chats/search`

Search chats, contacts and messages.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `searchChats`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `q` | query | No | What to search for. |
| `type` | query | No | Only one kind of message. |
| `from` | query | No | From this date (YYYY-MM-DD). |
| `to` | query | No | Up to this date. |

### Example

**cURL**

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

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/search", {
  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/chats/search",
    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/chats/search');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {chats, contacts, messages}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Count unread messages {#countUnreadChats}

`GET https://urnextdoor.com/api/v1/chats/unread-count`

How many messages are unread.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `countUnreadChats`

### Example

**cURL**

```bash
curl "https://urnextdoor.com/api/v1/chats/unread-count" \
  -H "Authorization: Bearer $UND_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/unread-count", {
  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/chats/unread-count",
    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/chats/unread-count');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {unread}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## List who you can message {#listChatContacts}

`GET https://urnextdoor.com/api/v1/chats/contacts`

Your connections, the members you can start a chat with through a key.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `listChatContacts`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `q` | query | No | Part of a name. |

### Example

**cURL**

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

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/contacts", {
  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/chats/contacts",
    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/chats/contacts');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {connections}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## List starred messages {#listStarredMessages}

`GET https://urnextdoor.com/api/v1/chats/starred`

Messages you starred.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `listStarredMessages`

### Example

**cURL**

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

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/starred", {
  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/chats/starred",
    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/chats/starred');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {messages}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Read a chat's messages {#listMessages}

`GET https://urnextdoor.com/api/v1/chats/{key}/messages`

Messages in a chat: after= for newer, before= for older.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `listMessages`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The chat key: a group slug, or "yourname-theirname" for a direct chat. |
| `after` | query | No | Only messages after this id. |
| `before` | query | No | Only messages before this id. |

### Example

**cURL**

```bash
curl "https://urnextdoor.com/api/v1/chats/aarav-asha/messages" \
  -H "Authorization: Bearer $UND_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/messages", {
  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/chats/aarav-asha/messages",
    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/chats/aarav-asha/messages');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {messages, last_id, has_more}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Send a message {#sendMessage}

`POST https://urnextdoor.com/api/v1/chats/{key}/messages`

Send a message in a chat. A new direct chat needs an accepted connection; an existing chat continues.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** counts as `message` (see [limits](https://docs.urnextdoor.com/limits.md))
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `sendMessage`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The chat key: a group slug, or "yourname-theirname" for a direct chat. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/aarav-asha/messages" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "body": "See you at 6!"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    body: "See you at 6!",
  }),
});
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/chats/aarav-asha/messages",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "body": "See you at 6!",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'body' => 'See you at 6!',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/aarav-asha/messages');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `201 Created` | The message. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Search one chat {#searchChat}

`GET https://urnextdoor.com/api/v1/chats/{key}/search`

Search the messages of one chat.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `searchChat`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The conversation key from GET /chats. |
| `q` | query | No | What to search for. |

### Example

**cURL**

```bash
curl "https://urnextdoor.com/api/v1/chats/aarav-asha/search" \
  -H "Authorization: Bearer $UND_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/search", {
  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/chats/aarav-asha/search",
    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/chats/aarav-asha/search');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {messages, query}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Read a chat {#getChat}

`GET https://urnextdoor.com/api/v1/chats/{key}`

A chat with its members, latest messages and pins.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `getChat`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The chat key: a group slug, or "yourname-theirname" for a direct chat. |

### Example

**cURL**

```bash
curl "https://urnextdoor.com/api/v1/chats/aarav-asha" \
  -H "Authorization: Bearer $UND_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha", {
  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/chats/aarav-asha",
    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/chats/aarav-asha');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {chat, members, messages, pins}. |   |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Forward a message {#forwardMessage}

`POST https://urnextdoor.com/api/v1/chats/{key}/messages/{messageId}/forward`

Forward a message to another chat (to is its key).

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** counts as `message` (see [limits](https://docs.urnextdoor.com/limits.md))
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `forwardMessage`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The conversation key from GET /chats. |
| `messageId` | path | Yes | The message id from GET /chats/{key}/messages. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/aarav-asha/messages/512/forward" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "to": "rooftopgrowers"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/messages/512/forward", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    to: "rooftopgrowers",
  }),
});
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/chats/aarav-asha/messages/512/forward",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "to": "rooftopgrowers",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'to' => 'rooftopgrowers',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/aarav-asha/messages/512/forward');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `201 Created` | {forwarded, to, message}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## React to a message {#reactToMessage}

`POST https://urnextdoor.com/api/v1/chats/{key}/messages/{messageId}/react`

Add an emoji reaction. The same emoji again removes it; another replaces it.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** counts as `react` (see [limits](https://docs.urnextdoor.com/limits.md))
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `reactToMessage`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The conversation key from GET /chats. |
| `messageId` | path | Yes | The message id from GET /chats/{key}/messages. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/aarav-asha/messages/512/react" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "emoji": "👍"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/messages/512/react", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    emoji: "👍",
  }),
});
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/chats/aarav-asha/messages/512/react",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "emoji": "👍",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'emoji' => '👍',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/aarav-asha/messages/512/react');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {reactions}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Star or unstar a message {#setMessageStarred}

`PUT https://urnextdoor.com/api/v1/chats/messages/{id}/starred`

Set whether a message is starred.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `setMessageStarred`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `id` | path | Yes | The message id. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X PUT "https://urnextdoor.com/api/v1/chats/messages/41/starred" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "starred": true
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/messages/41/starred", {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    starred: true,
  }),
});
console.log(res.status, await res.json());
```

**Python**

```python
import os

import requests

api_key = os.environ["UND_API_KEY"]

response = requests.put(
    "https://urnextdoor.com/api/v1/chats/messages/41/starred",
    headers={
        "Authorization": f"Bearer {api_key}",
    },
    json={
        "starred": True,
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'starred' => true,
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/messages/41/starred');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

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

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {starred, changed}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Mark a chat read {#markChatRead}

`POST https://urnextdoor.com/api/v1/chats/{key}/read`

Mark messages read up to an id.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `markChatRead`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The conversation key from GET /chats. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/aarav-asha/read" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "upto_id": 512
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/read", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    upto_id: 512,
  }),
});
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/chats/aarav-asha/read",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "upto_id": 512,
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'upto_id' => 512,
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/aarav-asha/read');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {read_upto}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Pin a message {#pinMessage}

`POST https://urnextdoor.com/api/v1/chats/{key}/pins`

Pin a message in a chat (up to 5; group admins only in groups).

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `pinMessage`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The conversation key from GET /chats. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/aarav-asha/pins" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "message_id": 512
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/pins", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    message_id: 512,
  }),
});
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/chats/aarav-asha/pins",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "message_id": 512,
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'message_id' => 512,
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/aarav-asha/pins');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {pinned}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Archive, pin or mute a chat {#setChatState}

`PUT https://urnextdoor.com/api/v1/chats/{key}/state`

Set any of archived, pinned and muted. mute_seconds sets how long a mute lasts (default 8 hours).

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **operationId:** `setChatState`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `key` | path | Yes | The conversation key from GET /chats. |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X PUT "https://urnextdoor.com/api/v1/chats/aarav-asha/state" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "muted": true,
  "mute_seconds": 3600
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/aarav-asha/state", {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    muted: true,
    mute_seconds: 3600,
  }),
});
console.log(res.status, await res.json());
```

**Python**

```python
import os

import requests

api_key = os.environ["UND_API_KEY"]

response = requests.put(
    "https://urnextdoor.com/api/v1/chats/aarav-asha/state",
    headers={
        "Authorization": f"Bearer {api_key}",
    },
    json={
        "muted": True,
        "mute_seconds": 3600,
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'muted' => true,
    'mute_seconds' => 3600,
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/aarav-asha/state');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

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

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {archived?, pinned?, muted?, changed}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Start a group chat {#createGroup}

`POST https://urnextdoor.com/api/v1/chats/groups`

Start a group with your connections.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** counts as `message` (see [limits](https://docs.urnextdoor.com/limits.md))
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `createGroup`

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/groups" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Roof club",
  "member_ids": [
    7,
    9
  ]
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/groups", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    name: "Roof club",
    member_ids: [7, 9],
  }),
});
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/chats/groups",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Roof club",
        "member_ids": [7, 9],
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'name' => 'Roof club',
    'member_ids' => [7, 9],
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/groups');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `201 Created` | {slug, key}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Add a member to a group {#addGroupMember}

`POST https://urnextdoor.com/api/v1/chats/groups/{slug}/members`

Add one of your connections to a group you run.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** counts as `message` (see [limits](https://docs.urnextdoor.com/limits.md))
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `addGroupMember`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `slug` | path | Yes | The slug from the item's URL (an id also works where noted). |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/members" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "username": "ravi"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/members", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    username: "ravi",
  }),
});
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/chats/groups/rooftop-growers/members",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "username": "ravi",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'username' => 'ravi',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/members');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {ok}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Set a group member's role {#setGroupRole}

`POST https://urnextdoor.com/api/v1/chats/groups/{slug}/role`

Make a member an admin or a member of a group you run.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `setGroupRole`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `slug` | path | Yes | The slug from the item's URL (an id also works where noted). |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/role" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "username": "ravi",
  "role": "admin"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/role", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    username: "ravi",
    role: "admin",
  }),
});
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/chats/groups/rooftop-growers/role",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "username": "ravi",
        "role": "admin",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'username' => 'ravi',
    'role' => 'admin',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/role');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {role}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Rename a group {#renameGroup}

`POST https://urnextdoor.com/api/v1/chats/groups/{slug}/rename`

Rename a group you run.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `renameGroup`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `slug` | path | Yes | The slug from the item's URL (an id also works where noted). |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/rename" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Rooftop club"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/rename", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    name: "Rooftop club",
  }),
});
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/chats/groups/rooftop-growers/rename",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Rooftop club",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'name' => 'Rooftop club',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/rename');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {name}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Set a group's icon {#setGroupIcon}

`POST https://urnextdoor.com/api/v1/chats/groups/{slug}/icon`

Set a group's icon to one of your images; an empty url removes it.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `setGroupIcon`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `slug` | path | Yes | The slug from the item's URL (an id also works where noted). |

### Request body

Send `Content-Type: application/json`.

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/icon" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "url": "/storage/aarav/chat/icon.webp"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/icon", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    url: "/storage/aarav/chat/icon.webp",
  }),
});
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/chats/groups/rooftop-growers/icon",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "url": "/storage/aarav/chat/icon.webp",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$payload = [
    'url' => '/storage/aarav/chat/icon.webp',
];

$ch = curl_init('https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/icon');
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;
```

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {icon_url}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |

## Leave a group {#leaveGroup}

`POST https://urnextdoor.com/api/v1/chats/groups/{slug}/leave`

Leave a group chat.

- **Auth:** your API key (Bearer or X-API-Key)
- **Scope:** `messages`
- **Daily quota:** not counted
- **Idempotency-Key:** supported (see [Idempotency](https://docs.urnextdoor.com/idempotency.md))
- **operationId:** `leaveGroup`

### Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `slug` | path | Yes | The slug from the item's URL (an id also works where noted). |

### Example

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/leave" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/leave", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
  },
});
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/chats/groups/rooftop-growers/leave",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

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

$ch = curl_init('https://urnextdoor.com/api/v1/chats/groups/rooftop-growers/leave');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Idempotency-Key: ' . bin2hex(random_bytes(16)),
    ],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

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

### Responses

| Status | Meaning | Codes |
| --- | --- | --- |
| `200 OK` | {ok}. |   |
| `400 Bad Request` | The body is not a JSON object, or the Idempotency-Key header is malformed. | `invalid_json`, `invalid_idempotency_key` |
| `401 Unauthorized` | No key, or the key is unknown, malformed, revoked or expired, or the member is not active. | `missing_api_key`, `invalid_api_key` |
| `403 Forbidden` | The key lacks the scope, or the member may not do this. | `insufficient_scope`, `forbidden` |
| `404 Not Found` | Unknown route or item, or the item is not yours. | `not_found` |
| `409 Conflict` | Conflicts with the current state, or the same Idempotency-Key is still being processed. | `conflict`, `idempotency_in_progress` |
| `413 Payload Too Large` | The body is over the limit, or the image is over 8 MB. | `payload_too_large` |
| `415 Unsupported Media Type` | Wrong Content-Type, or a file type that is not allowed. | `unsupported_media_type` |
| `421 Misdirected Request` | Called on a community subdomain. Use https://urnextdoor.com. | `wrong_host` |
| `422 Unprocessable Content` | Field errors, or an Idempotency-Key reused with a different body. | `validation_failed`, `idempotency_key_reused` |
| `429 Too Many Requests` | Over 60 requests a minute from this member (or too many failed key checks from one address), or today's quota for this action is used up. | `rate_limited`, `quota_exceeded` |
| `500 Internal Server Error` | Our fault. Safe to retry with the same Idempotency-Key. | `server_error` |
| `503 Service Unavailable` | The API is switched off. | `api_disabled` |
