Skip to main content

Management session authentication

First-time workspace setup

Property managers scripting against the Core API should complete Getting Started — Recommended Setup Sequence steps 1–3 (General information, Users, Preferences) before wiring POST /auth/login — this is operator JWT auth, not partner Authentication Bearer keys. Finish steps 4–15 and Onboarding a New Property — Step 7 before portfolio-wide automation touches live bookings. When sign-in was restored mid-setup, see Getting Started — Lockout catch-up after password recovery (refresh Bearer JWT before MCP or scripted calls resume). Guide pairing after go-live: Setup sequence after go-live (hub: API Reference — Setup sequence after go-live).

Finding your way in this guide

Start with How it differs from integration auth and Sign-in flow, then Authenticated API calls for curl examples. Contrast Authentication (partner Bearer keys on integration prefixes). For scripted retries after expiry, see Error Handling on 401 refresh failures. External AI clients: Landlord MCP alternative. Habit-specific shortcuts live under Related below.

This page documents operator authentication for the Vivin Core API — the same session the management frontend uses at platform.vivin.app. It is not the partner integration Bearer token used for GET /{platform}-integration/listings and similar routes.

Use this when you build internal automation, one-off scripts, or evaluate HTTP routes before wiring Landlord MCP. For production AI clients, prefer Landlord MCP tools (they enforce the same permissions as the UI).

How it differs from integration auth​

Pair with other Management session sections

Partner integrations use long-lived Bearer keys — Authentication. Never paste integration keys into Core /api Swagger below.

AspectManagement sessionPartner integration
WhoProperty managers, Vivin internal operatorsChannel managers, OTAs, booking engines
CredentialEmail + password or Google ID token → short-lived JWT in response bodyLong-lived API key in Authorization: Bearer
RefreshhttpOnly cookie (POST /auth/refresh) — not readable from JavaScriptKey does not rotate unless Vivin rotates it
ScopeUser role + accountId on every domain routeSingle integration platform + account
Docs surfaceCore API Swagger at /api when enabled (see below)Per-integration Swagger at /{platform}-integration

Sign-in flow​

Pair with other Management session sections

Browser clients rely on httpOnly refresh cookies — command-line scripts need curl -c cookies.txt -b cookies.txt. Session UX: Getting Started — Staying signed in.

POST /auth/login HTTP/1.1
Host: api.vivin.app
Content-Type: application/json

{
"email": "[email protected]",
"password": "your-password"
}

Response (200) — short-lived access token plus user and account context:

{
"token": "<JWT>",
"user": {
"id": "…",
"email": "[email protected]",
"firstName": "…",
"lastName": "…",
"role": "…",
"accountId": "…"
},
"account": {
"id": "…",
"companyName": "…",
"logoUrl": "…"
}
}

The server also sets an httpOnly refresh cookie on the response. Browser clients (the management frontend) send that cookie automatically on POST /auth/refresh. Command-line scripts must preserve cookies between requests (for example curl -c cookies.txt -b cookies.txt).

Google sign-in (POST /auth/google)​

When the hub UI shows Sign in with Google, the browser posts a Google Identity Services ID token instead of email/password. The response shape and refresh cookie match POST /auth/login. Vivin resolves an existing property manager by linked Google subject or by email match — it does not create users. Unknown Google emails are rejected; deactivated users cannot sign in. Operator UX: Getting Started — Sign in with Google.

POST /auth/google HTTP/1.1
Host: api.vivin.app
Content-Type: application/json

{
"idToken": "<Google Identity Services ID token>"
}

Prefer email/password for headless scripts unless you already hold a fresh Google ID token. Browser operators should use the hub button rather than calling this route manually.

Replace api.vivin.app with your API host:

# 1) Sign in — save Set-Cookie refresh token to a jar and read the access JWT
curl -sS -c cookies.txt -X POST 'https://api.vivin.app/auth/login' \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]","password":"your-password"}' \
| tee login.json

export VIVIN_JWT="$(jq -r .token login.json)"

# 2) Call a protected route
curl -sS -b cookies.txt -H "Authorization: Bearer ${VIVIN_JWT}" \
'https://api.vivin.app/bookings?limit=5'

# 3) When the JWT expires, refresh (cookie only — no body)
curl -sS -b cookies.txt -c cookies.txt -X POST 'https://api.vivin.app/auth/refresh' \
| tee refresh.json

export VIVIN_JWT="$(jq -r .token refresh.json)"

# 4) End the session server-side
curl -sS -b cookies.txt -c cookies.txt -X POST 'https://api.vivin.app/auth/logout'

The refresh cookie name and attributes are managed by Core API — treat cookies.txt as a secret alongside the JWT.

Authenticated API calls​

Pair with other Management session sections

Refresh with POST /auth/refresh when JWT expires — 401 patterns in Error Handling. Permission matrix: Users and roles.

Send the access token on every protected route:

GET /bookings HTTP/1.1
Host: api.vivin.app
Authorization: Bearer <JWT>

When the JWT expires, call POST /auth/refresh with the refresh cookie (no body, no access token required). A successful refresh returns a new token in the body and rotates the refresh cookie.

POST /auth/logout revokes the current refresh token and clears the cookie. Safe to call even when the access token is already expired.

Operator-visible behaviour (silent refresh, session-expired message, sidebar Logout) is described in Getting Started — Staying signed in.

sequenceDiagram
participant Client as Script or browser
participant API as Core API
Client->>API: POST /auth/login (email + password)
API-->>Client: 200 body.token (JWT) + Set-Cookie refresh
Client->>API: GET /bookings Authorization Bearer JWT
alt JWT expired
Client->>API: POST /auth/refresh (refresh cookie)
API-->>Client: 200 new token + rotated cookie
Client->>API: Retry protected route with new JWT
end
Client->>API: POST /auth/logout (refresh cookie)
API-->>Client: Refresh revoked; cookie cleared

Permissions and multi-tenancy​

Pair with other Management session sections

Every route filters by signed-in accountId — same tenancy model as partner reads after Property & Unit Mapping. Do not reuse management JWTs on integration prefixes.

Every management route is scoped to the signed-in user's accountId. Module tabs and write actions additionally require role permissions (for example finance.approve_payments, bookings.create) — the same matrix documented under Users and roles.

401 / 403 responses follow the patterns in Error handling. Integration partners should not reuse management JWTs on integration route prefixes, and vice versa.

Core API Swagger (/api)​

Pair with other Management session sections

Enable locally with ENABLE_CORE_API_SWAGGER=true — integration Swagger stays separate per Try requests in Swagger. Paste JWT from POST /auth/login, not partner Bearer keys.

The internal Core API catalogue (all management and domain routes) is exposed at /api on the API host when ENABLE_CORE_API_SWAGGER=true (or 1) on that environment. It may be disabled on production hosts.

Integration Swagger pages (/uniplaces-integration, /ical-integration, etc.) stay enabled separately — see Try requests in Swagger.

To explore management routes locally:

  1. Start Core API with Core Swagger enabled for your environment.
  2. Open the Core Swagger UI on your API host (path /api).
  3. Click Authorize, choose the Bearer scheme, and paste the JWT from POST /auth/login (with or without the Bearer prefix, per the form hint).
  4. Expand a tag (for example bookings) and use Try it out on a GET you have permission to call.

The Bearer control uses the same JWT as programmatic management calls — not your integration API key. Integration Swagger pages (/{platform}-integration) remain separate; see Try requests in Swagger.

Production and staging hosts

On shared API hosts (for example api.vivin.app), /api may return 404 when ENABLE_CORE_API_SWAGGER is not set. Integration Swagger URLs stay available for partners. Operators evaluating management routes on those hosts should use the management UI, Landlord MCP, or a local Core API instance with Swagger enabled.

Landlord MCP alternative​

Pair with other Management session sections

Prefer Landlord MCP for external AI clients — same permissions as the UI without raw HTTP. Booking-scoped automation: Tenant MCP.

Landlord MCP wraps the same Core API behind MCP tools with session-based auth (Mcp-Session-Id). Prefer MCP when external AI clients need structured, permission-aware tool calls instead of raw HTTP.

Authentication paths for Landlord MCP:

PathWhen to use
API keysIDE assistants (Cursor, Claude Desktop), custom scripts — paste Bearer token from AI / MCP
MCP OAuthHosted connectors (Claude.ai, ChatGPT) — PKCE authorization code on the Core API host
POST /auth/login (this page)One-off scripts and Swagger exploration — refresh via httpOnly cookie
POST /auth/google (this page)Hub Sign in with Google — same JWT + refresh cookie; requires an existing invited user
POST /auth/refresh / POST /auth/logoutSilent renewal and explicit end of session (browser or scripts with cookie jar)

Connector OAuth issues the same management JWT shape as login; see MCP OAuth — Token response.

Management session section cross-reference​

Use the endpoints and fields above. Related integrator pages are linked inline where useful.

Pair with other Management session guide sections

Related below links operator JWT and refresh cookies to setup, companion API guides, operator workflows, and escalation paths.

Setup sequence after go-live​

Pair with other Management session guide sections

Complete Account Settings — Recommended setup order before partner traffic.

Documentation map & escalation​

Companion API guides​

Pair with other Management session guide sections

Companion guides share Bearer authorization or error shapes with this page — start from API Reference hub.

  • Authentication (integration) — Partner Bearer keys for marketplace and booking-engine feeds
  • AI usage — Account-scoped LLM token ledger (GET /ai-usage, GET /ai-usage/summary) on the same management JWT
  • Error handling — Standard HTTP error shapes and 401 refresh failures
  • Creating Bookings — Partner write surface (distinct from operator JWT on management routes)
  • Webhooks & Notifications — Outbound events when automation listens instead of polling management GETs
  • Property & Unit Mapping — Partner externalId scope contrast with operator accountId JWT routes

Upstream & downstream workflows​

Operator UI & settings​

Deeper concept reads​

  • Landlord MCP — Recommended external automation surface for operators
  • Tenant MCP — Booking-scoped alternative when automation targets one reservation
  • Automation & AI — Channel map for in-product AI, chatbot, and external MCP clients
  • Payment Allocation — Operator payment matching behind many management routes
  • Integrations & Distribution — Marketplace partner APIs use integration Bearer keys, not management JWTs from this guide
  • Services Marketplace — Portal service charges management JWT scripts may reconcile on Transactions after tenant Request Service
  • Tenant Portal — Operator JWT workflows that copy portal links from booking Contract Info after management session sign-in
  • FAQ — Tenant contract signing blocked — No PDF yet, mandatory Your Details gates, category locks, or Lease purpose; portal signing vs paper upload on Contract Info
  • Booking Lifecycle — Computed Upcoming → Ongoing → Ended / Canceled status model, list filters, and Timeline

Deeper workflow reads​

See Upstream & downstream workflows above for the same guides.

Operator habit hubs​

Day-to-day operator habits (lockout catch-up, pending receipts, payment triage, handoffs, and related playbooks) live on the Common Workflows habit hub.

Deep-link anchors for habit hubs

Lockout catch-up after password recovery​

Pending manual receipt approval​

Reject/revert mistaken receipts​

Portfolio segmentation by tenant category​

Notification row-click navigation​

Payment alert to receivables triage​

Confirmation alert triage​

Finance debt receivables triage​

Handling a Late Payment collections​

Finance Income status drill-down​

Cash flow forecast drill-down​

Key glossary terms​

Module documentation hubs​

Pair with other Management session guide sections

for screen-by-screen operator follow-up.

  • AI Chat module — In-management assistant using the same operator JWT session as management HTTP routes (hub)
  • Bookings module — Operator UI routes that share the same JWT session as management scripts (hub)
  • Finance module — Ledger tabs that require Approve payments permission on top of a valid session (hub)
  • Inbox module — WhatsApp routes that require the same operator session as management scripts (hub)
  • Dashboard module — Same-day KPI snapshot using management JWT routes (hub)
  • Operations module — Ticket and cash-flow routes behind the same JWT session as management scripts (hub)
  • Notifications module — Alert routes automation may poll after management JWT sign-in (hub); Payment overdue alerts when scripted queries surface unpaid schedules
  • Audit module — Portfolio-wide Manual Blocks and Discounts contract-value review (hub)
  • Analytics module — Month-range portfolio KPI charts with rankings and heatmaps (hub)
  • Listings module — Property wizard, Channels tab, and unit management (hub)
  • Properties workspace — Legacy /properties URL redirects into Listings (hub)
  • Booking engine details — Rich marketplace payload editor via the Full integration pill (hub)
  • Tenants module — Tenant directory and profile sidebars (hub)
  • Sales module — Portfolio availability and channel manager connections (hub)
  • Utilities module — Bills Included ceiling model and tenant overage charges (hub)
  • Account Settings — Workspace-wide financial policies, templates, integrations, and operational defaults (hub)