Working with Shiva listings
This page documents the Shiva listing API. Creating or updating a listing uses the same cookie session as the web app. Published listings can be read without login.
Base URL (production app):
https://app.tnuchamu.org/api
Meal-train / food coordinator details and donation URL fields live on the listing
itself (via PATCH /api/shiva-listings/:id).
Authentication
T'Nuchamu uses session cookies (Passport / express-session). Log in
once, then send the session cookie on later requests with
credentials: "include" (browsers) or by forwarding the
Set-Cookie / Cookie header (other clients).
Start a session. The username field accepts email or username.
Login request body
{
"username": "you@example.com",
"password": "your-password"
}
| Field | Type | Required | Notes |
|---|---|---|---|
username |
string | Yes | Email (recommended) or username |
password |
string | Yes | Account password |
Login response
{
"user": {
"id": 123,
"username": "you@example.com",
"email": "you@example.com",
"firstName": "Ada",
"lastName": "Cohen"
}
}
The response also sets a session cookie. Reuse that cookie for authenticated listing calls. Email must be verified before login succeeds.
Return the current session user, or 401 if not logged in.
End the session and clear the cookie.
Browser OAuth flow (redirect). Prefer password login for API clients.
Example: login then create a listing
curl -c cookies.txt -X POST https://app.tnuchamu.org/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"you@example.com","password":"your-password"}'
curl -b cookies.txt -X POST https://app.tnuchamu.org/api/shiva-listings \
-H "Content-Type: application/json" \
-d @listing.json
Create a Shiva listing
POST /api/shiva-listings accepts a JSON body validated by
insertShivaListingSchema. When a session is present, the server sets
userId from the authenticated user. New listings are usually created as
draft; publish with a later PATCH.
Create a listing. Returns 201 with the created listing object.
Required fields
| Field | Type | Notes |
|---|---|---|
ownerFullName |
string | Listing owner full name |
ownerEmail |
string | Owner email |
ownerPhone |
string | Primary phone |
niftarFirstName |
string | Niftar first name |
niftarLastName |
string | Niftar last name |
niftarGender |
string | e.g. male / female |
niftarDateOfPassing |
string (date) | YYYY-MM-DD |
Common optional fields
| Field | Type | Notes |
|---|---|---|
status |
string | draft (default), published, archived |
ownerSmsPhone, ownerWhatsappPhone |
string | If different from primary |
ownerPreferredContactMethods |
string[] | e.g. ["email","phone","sms","whatsapp"] |
pocSameAsOwner |
boolean | Point of contact same as owner |
pocFullName, pocEmail, pocPhone |
string | Point of contact (if different) |
niftarPrefix, niftarMiddleName, niftarMaidenName |
string | Additional niftar name fields |
niftarJewishName, niftarBio |
string | Jewish name / biography |
niftarFirstYahrzeit |
string | First yahrzeit text/date |
niftarProfilePicture, niftarVideoUrl |
string | Media URLs |
niftarGallery |
array | Gallery items (JSON) |
isMesMitsvah |
boolean | Meis mitzvah listing |
acceptingDonations, donationUrl |
boolean / string | Memorial donation settings |
foodCoordinator* |
mixed | Meal train / food coordinator fields |
shloshimDate, mishnayosLink |
string | L'ilui Nishmas fields |
whatsappGroupInviteLink |
string | Optional WhatsApp group invite |
hideFamilyName |
boolean | Privacy setting |
*Complete flags |
boolean | Tab completion tracking (e.g. informationComplete) |
Example request body
{
"status": "draft",
"ownerFullName": "Sarah Cohen",
"ownerEmail": "sarah@example.com",
"ownerPhone": "+14155550100",
"ownerSmsUsesPrimary": true,
"ownerWhatsappUsesPrimary": true,
"ownerPreferredContactMethods": ["email", "sms"],
"pocSameAsOwner": true,
"niftarPrefix": "Mr.",
"niftarFirstName": "David",
"niftarMiddleName": "",
"niftarLastName": "Cohen",
"niftarGender": "male",
"niftarJewishName": "David ben Moshe",
"niftarDateOfPassing": "2026-07-28",
"niftarBio": "",
"isMesMitsvah": false,
"acceptingDonations": false,
"foodCoordinatorFirstName": "",
"foodCoordinatorLastName": "",
"foodCoordinatorMealTrainLink": "",
"informationComplete": true,
"levayaComplete": false,
"kevurahComplete": false,
"aveilimComplete": false,
"shivaHouseComplete": false,
"minyanComplete": false,
"mealsAndFoodsComplete": false,
"affiliationsComplete": false,
"liluiNishmasComplete": false
}
Houses, aveilim, visiting times, levaya, and kevurah are created with the related
endpoints below after you have the listing id from this response.
Shiva listings
Core CRUD and nested reads for a listing — including houses, aveilim, visiting times, levaya/kevurah, and comfort messages.
List or search public Shiva listings.
Create a new listing (often as a draft). See Create a Shiva listing for the full request body.
Get a listing by numeric id or slug.
Full nested listing payload (houses, minyanim, and related data).
Validate the ready-to-publish checklist.
Update listing fields (including meals and donation URL).
Delete a listing.
Aveilim on the listing.
Shiva houses for the listing.
Levaya events for the listing.
Kevurah details for the listing.
Listing change history.
Read public comfort messages (nichum).
Post a comfort message (authenticated).
Upload or share a listing photo.
Search niftar names (dedupe helper when creating a listing).