POST
/
api
/
v1
/
onboarding
/
step-2-current-home
Onboarding step 2 — current home
curl --request POST \
  --url https://api.example.com/api/v1/onboarding/step-2-current-home
import requests

url = "https://api.example.com/api/v1/onboarding/step-2-current-home"

response = requests.post(url)

print(response.text)
const options = {method: 'POST'};

fetch('https://api.example.com/api/v1/onboarding/step-2-current-home', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/onboarding/step-2-current-home",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/api/v1/onboarding/step-2-current-home"

req, _ := http.NewRequest("POST", url, nil)

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/onboarding/step-2-current-home")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/api/v1/onboarding/step-2-current-home")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body

Overview

Submits the property details that describe the user’s current home. The server creates a current_homes document in status: DRAFT (1:1 with the user — a unique partial index on userId enforces “one listing per user”) and advances currentStep from 2 to 3. The listing stays DRAFT through the rest of onboarding. Photos are attached in step 3, the description in step 3 description, and the listing only becomes eligible for LIVE once onboarding completes AND tenancy is APPROVED — see POST /current-home/me/publish. rentMonthlyMinor is derived server-side from rent (weekly → amountMinor * 52 / 12 rounded to nearest pence; monthly → identity) and is used by the matching engine. Preconditions:
  • Onboarding is IN_PROGRESS and currentStep is 2 or later (step 1 completed).
Re-submission is an upsert: while onboarding is in progress, posting step 2 again (e.g. the user navigated Back from a later step and edited their details) updates the existing DRAFT listing in place. currentStep only advances 2 → 3 on the first submission — a re-submission never moves or regresses it.

Authentication

Bearer <accessToken> required. Scope: user.

Path parameters

None.

Query parameters

None.

Request body

FieldTypeRequiredAllowed values / ConstraintsExample
propertyTypeenumyesDETACHED, SEMI_DETACHED, TERRACED, FLAT, MAISONETTE, BUNGALOWFLAT
bedroomsintegeryes0..10 inclusive2
bathroomsintegeryes0..10 inclusive1
addressstringyes1..500 chars. Free-text postal address (usually the reverse-geocoded address of the map pin).27 Camden High Street, London
addressDetailsstringno0..200 chars. Free-text detail the user typed on top of the pin address (house/flat number, street, entrance notes). Display-only. Defaults to "".Flat 4
postcodestringyes5..10 chars; must be a valid UK postcode. Normalized to uppercase server-side.NW1 7JE
lngnumberyes-180..180. Decimal degrees, WGS-84.-0.1426
latnumberyes-90..90. Decimal degrees, WGS-84.51.5390
rentobjectyesSee Rent object
featuresstring[]noSubset of: GARDEN, PARKING, BALCONY, LIFT, GROUND_FLOOR, PETS_ALLOWED, WHEELCHAIR_ACCESS. Defaults to [].["GARDEN", "LIFT"]

Rent object

FieldTypeRequiredNotes / ConstraintsExample
amountMinorintegeryesPositive integer pence (1 = £0.01).120000
frequencyenumyesWEEKLY, MONTHLYMONTHLY

Example payload

{
  "propertyType": "FLAT",                              // enum: "DETACHED" | "SEMI_DETACHED" | "TERRACED" | "FLAT" | "MAISONETTE" | "BUNGALOW"
  "bedrooms": 2,                                       // integer 0..10
  "bathrooms": 1,                                      // integer 0..10
  "address": "27 Camden High Street, London",
  "addressDetails": "Flat 4",                          // optional free text (house/flat no, street)
  "postcode": "NW1 7JE",
  "lng": -0.1426,
  "lat": 51.5390,
  "rent": {
    "amountMinor": 120000,                             // integer pence; 120000 = £1,200.00
    "frequency": "MONTHLY"                             // enum: "WEEKLY" | "MONTHLY"
  },
  "features": [
    "GARDEN",                                          // enum (multi): "GARDEN" | "PARKING" | "BALCONY" | "LIFT" | "GROUND_FLOOR" | "PETS_ALLOWED" | "WHEELCHAIR_ACCESS"
    "LIFT"
  ]
}

Response — 200 OK

Returns the refreshed onboarding state (same shape as GET /onboarding/state).
FieldTypeAllowed valuesExample
onboardingStatusenumIN_PROGRESS, COMPLETEIN_PROGRESS
currentStepinteger | nulladvances to 33
tenancyStatusenumunchangedPENDING

Example response

{
  "onboardingStatus": "IN_PROGRESS",
  "currentStep": 3,
  "tenancyStatus": "PENDING"
}

Error responses

StatusCodeMeaning
400VALIDATION_FAILEDBody fails Zod validation (bad enum, postcode not a valid UK format, lng/lat out of range, etc.).
401UNAUTHENTICATEDMissing, malformed, or expired access token.
409STATE_CONFLICTStep 1 not completed yet (currentStep < 2), or onboarding is already complete (use PATCH /current-home/me instead).

Example error — 409

{
  "type": "https://api.swappr.co.uk/errors/state-conflict",
  "title": "State conflict",
  "status": 409,
  "code": "STATE_CONFLICT",
  "detail": "Complete step 1 first (current step is 1)",
  "instance": "/api/v1/onboarding/step-2-current-home",
  "requestId": "01HZQ7K3M4N5P6Q7R8S9T0V1W2"
}

Side effects

  • First submission: inserts a row into the current_homes collection with status: DRAFT, the supplied details, photos: [], description: "", and rentMonthlyMinor derived from rent; sets users.currentStep = 3.
  • Re-submission (onboarding in progress): updates the existing DRAFT row’s step-2 fields in place; photos, description, status, and currentStep are untouched.

See also

curl

curl -X POST https://api.swappr.co.uk/api/v1/onboarding/step-2-current-home \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "propertyType": "FLAT",
    "bedrooms": 2,
    "bathrooms": 1,
    "address": "27 Camden High Street, London",
    "addressDetails": "Flat 4",
    "postcode": "NW1 7JE",
    "lng": -0.1426,
    "lat": 51.5390,
    "rent": { "amountMinor": 120000, "frequency": "MONTHLY" },
    "features": ["GARDEN", "LIFT"]
  }'