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.

View as Markdown

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.

WhatEndpoint
Your chatsGET /api/v1/chats (filter=archived for archived ones)
One chat, with members and pinsGET /api/v1/chats/{key}
Its messagesGET /api/v1/chats/{key}/messages (before= for older, after= for newer)
SearchGET /api/v1/chats/search?q=, or GET /api/v1/chats/{key}/search?q= in one chat
Unread countGET /api/v1/chats/unread-count
Starred messagesGET /api/v1/chats/starred

Send

cURL
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
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
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
$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
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
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
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
$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

Last updated