Read and send messages
Read your chats, send messages to your connections, star, pin, mute or archive chats, and run group chats with the Ur Next Door API.
Messages are the most personal thing a key can touch, so the messages scope is never ticked by default, and a key may start a chat only with one of your connections (403 dm_not_allowed otherwise). A chat you already have, started on the website or in the app, continues as usual.
Scope: messages ยท Quota: message for sending, forwarding and groups; reading and chat settings are not counted
Chats and their keys
Every chat has a key: a group's slug, or yourname-theirname for a direct chat (both usernames, joined by a hyphen). GET /api/v1/chats lists your chats with their keys; GET /api/v1/chats/contacts lists the connections you can start a chat with.
| What | Endpoint |
|---|---|
| Your chats | GET /api/v1/chats (filter=archived for archived ones) |
| One chat, with members and pins | GET /api/v1/chats/{key} |
| Its messages | GET /api/v1/chats/{key}/messages (before= for older, after= for newer) |
| Search | GET /api/v1/chats/search?q=, or GET /api/v1/chats/{key}/search?q= in one chat |
| Unread count | GET /api/v1/chats/unread-count |
| Starred messages | GET /api/v1/chats/starred |
Send
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!"
}'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());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
$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;Also: POST /api/v1/chats/{key}/messages/{messageId}/forward with {"to": "<chat key>"}, and POST /api/v1/chats/{key}/messages/{messageId}/react with an emoji (the same emoji again removes it).
Chat settings
PUT /api/v1/chats/{key}/state sets any of archived, pinned and muted (with mute_seconds). Each is set, never flipped: a repeat changes nothing.
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
}'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());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
$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;PUT /api/v1/chats/messages/{id}/starred stars a message; POST /api/v1/chats/{key}/read marks a chat read; POST /api/v1/chats/{key}/pins pins a message.
Groups
POST /api/v1/chats/groups starts a group with your connections (member_ids). In a group you run, add a connection (POST .../members), set a role (.../role, with role admin or member always sent), rename it, set its icon, or leave it. Adding someone already in the group answers 409, never a silent role change.
Next steps
- Follow, connect and block: connections decide who a key can message.
- Keep your API key safe.
- API reference: Messages.
Last updated