Skip to main content

Move-outs API

A move-out is the record Greenlight opens when a resident vacates a unit. You open one through this API when a resident moves out, and Greenlight tracks refund/consent/statement steps against it as they ship.

This is an early release. Today the API covers opening a move-out and reading it back; consent, statement submission, and payout are not live yet and are not documented here until they are. See move_out.initiated for the corresponding webhook.

See Authentication & Environments for base URLs and request signing.

Open a move-out​

POST /partners/{owner_slug}/move_outs
Content-Type: application/json

Unlike the prospect and property endpoints, the body is not wrapped in a named key — send the move-out's own fields at the top level:

{
"external_id": "your-move-out-123",
"move_out_date": "2026-09-30",
"property": {
"external_id": "your-property-1",
"address_line_one": "123 Main St",
"address_city": "Chicago",
"address_state": "IL",
"address_zip": "60601"
},
"unit": {
"external_id": "your-unit-1",
"name": "4B"
},
"residents": [
{
"role": "primary",
"name": "Jordan Rivera",
"email": "renter@example.com",
"external_id": "your-resident-1"
}
]
}

external_id is the idempotency key, unique per property owner. Re-POSTing the same external_id returns the existing move-out unchanged — it does not update it and does not create a duplicate. refund_amount_cents is omitted here deliberately: send it only once the refund amount is final, since its presence is what tells Greenlight the statement is done.

Both a create and a re-post return 200-shaped bodies with a status_code field: 201 when the move-out was created, 200 when an existing one was returned. Read status_code rather than the HTTP status if you need to tell them apart — the HTTP status matches it in both cases.

Fetch a move-out​

GET /partners/{owner_slug}/move_outs/{id}

Returns the same move-out object. Webhooks are the primary channel for status changes; use this to reconcile if you are not subscribed, or to poll after creation.

{id} is the numeric move_out_id from the create response — see the note on IDs below.

Request fields​

FieldNotes
external_idYour identifier for the move-out. Required, unique per property owner.
move_out_dateYYYY-MM-DD. Required.
propertyObject with address_line_one, address_city, address_state, address_zip (all required) and an optional external_id. Stored as sent — see the note below.
unitOptional object with external_id and name.
residentsRequired, at least one. Each entry needs role (primary or co_resident) and name; email and external_id are optional.
refund_amount_centsOptional. Integer cents. Send only when the refund amount is final.
deposit_amount_centsOptional. Integer cents. The deposit originally collected, before any deductions.
lease_startOptional. YYYY-MM-DD.
lease_endOptional. YYYY-MM-DD.

The property address is stored exactly as sent, not derived from any Greenlight property record. Most departing residents predate any integration Greenlight has with your system, so a move-out stands on its own — nothing here requires the property, unit, or residents to already exist in Greenlight.

Response​

{
"status_code": 201,
"move_out": {
"move_out_id": 1042,
"external_id": "your-move-out-123",
"status": "initiated",
"move_out_date": "2026-09-30",
"refund_amount_cents": null,
"property": {
"external_id": "your-property-1",
"address_line_one": "123 Main St",
"address_city": "Chicago",
"address_state": "IL",
"address_zip": "60601"
},
"unit": {
"external_id": "your-unit-1",
"name": "4B"
},
"residents": [
{
"role": "primary",
"name": "Jordan Rivera",
"email": "renter@example.com",
"external_id": "your-resident-1"
}
]
}
}

Response fields​

FieldDescription
move_out_idGreenlight's numeric ID for the move-out
statusinitiated today. More values arrive as later milestones (consent, statement, payout) ship.
refund_amount_centsnull until the statement is final

Note on IDs: unlike prospects (tpp_…) and policies (policy_…), a move-out's ID is a plain integer, not a prefixed string. The same move_out_id appears in the create/fetch response and in the move_out.initiated webhook payload.

Errors​

{
"status_code": 422,
"error": "Move-out invalid.",
"move_out": {
"external_id": "can't be blank",
"residents": "must include at least one resident"
}
}
StatusMeaning
401Request signature missing, malformed, or older than five minutes
403Caller not granted access to this property owner
404Unknown owner_slug, or the move-out does not exist — including one that exists under a different owner
422Validation failure — see the move_out object for field-level detail

Next steps​