API reference

A concise, REST-ful HTTP API. Requests use JSON. Authenticate with a bearer token in the Authorization header.

Example request
curl https://api.nestly.ro/v1/listings \
  -H "Authorization: Bearer YOUR_TOKEN"

Authentication

POST/v1/auth/session

Exchange OAuth code for a session token.

Body
{
  "provider": "google",
  "code": "..."
}
Response
{
  "token": "jwt...",
  "user": { "id": "u-1", "role": "tenant" }
}
POST/v1/auth/logout

Invalidate the current session.

Response
{ "ok": true }

Listings

GET/v1/listings

List rooms with filters.

Response
{
  "data": [{ "id": "l-1", "title": "Studio", "price": 480 }],
  "page": 1, "total": 42
}
POST/v1/listings

Create a listing (owner only).

Body
{
  "title": "...", "price": 500,
  "sector": "Sector 1", "photos": ["..."]
}
Response
{ "id": "l-abc", "status": "pending" }
GET/v1/listings/{id}

Fetch a single listing.

Response
{ "id": "l-1", "title": "...", "owner": {...} }
PATCH/v1/listings/{id}

Update fields.

Body
{ "price": 520 }
Response
{ "ok": true }
DELETE/v1/listings/{id}

Delete a listing.

Response
{ "ok": true }

Messaging

GET/v1/threads

List conversations for the user.

Response
[{ "userId": "u-2", "unread": 1, "last": "..." }]
POST/v1/messages

Send a message.

Body
{ "toId": "u-2", "listingId": "l-1", "text": "Hi" }
Response
{ "id": "m-abc" }
POST/v1/threads/{userId}/read

Mark thread as read.

Response
{ "ok": true }

Favorites

GET/v1/favorites

List saved listings.

Response
["l-1","l-5"]
POST/v1/favorites/{listingId}

Toggle favorite.

Response
{ "saved": true }

Reports & moderation

POST/v1/reports

Report a listing or user.

Body
{ "targetType": "listing", "targetId": "l-4", "reason": "..." }
Response
{ "id": "r-1" }
GET/v1/admin/moderation

Pending listings queue (admin).

Response
[{ "id": "l-4", "status": "pending" }]
PATCH/v1/admin/listings/{id}

Approve or reject (admin).

Body
{ "status": "active" }
Response
{ "ok": true }

Errors

400Bad request — invalid payload
401Missing or invalid token
403Forbidden — role does not permit action
404Resource not found
429Rate limited
500Internal error