Skip to content

Location

The location module stores addresses (individual or organization) in the addresses table. Most address columns are stored encrypted (@EncryptedColumn) and come out as plaintext in the response. The controller is registered at /addresses; all endpoints require Bearer JWT plus an ACL permission.

PropertyValue
Base URL{HOST}/v1
AuthBearer JWT (header Authorization) or access_token cookie
Content-Typeapplication/json
Error envelope{ "message": string | string[], "statusCode": number, "error": string }
ValidationGlobal ValidationPipe · whitelist: true, forbidNonWhitelisted: true
Related modulesusers, organizations, onboarding
Document versionv1 · 2026-05-20
AudienceInternal FE devs (mobile + web)

Four endpoints: register a new address (for the logged-in user), get address detail by ID, list all addresses (Moria-only), and update an address. An ACL permission is used for each operation: create-address, read-address, update-address. Only the list endpoint is additionally restricted via @Roles(UserType.MORIA).

MethodPathAuthSummary
POST/v1/addressesbearerRegister a new address for the logged-in user
GET/v1/addresses/:address_idbearerDetail of one address (UUID)
GET/v1/addressesbearerList all addresses — Moria admins only
PATCH/v1/addresses/:address_idbearerUpdate an address (all fields optional)

Register a new address. The server reads user from the token (@AuthUser()) to determine the address owner.

bearer create-address
FieldTypeRequiredNotes
provincestringExample DKI JAKARTA
citystring
countrystring
districtstringoptionalKecamatan
subdistrictstringoptionalKelurahan
streetstringoptional
villagestringoptional
rtstringoptionalRT, example 01
rwstringoptionalRW, example 02
postal_codestringoptional
unit_numberstringoptionalUnit number
building_numberstringoptionalBuilding number
labelstringoptionalCustom label (e.g. Home, Office)
address_typeenum AddressTypeoptionalindividual | organization; default individual
{
"province": "DKI JAKARTA",
"city": "Jakarta Utara",
"country": "Indonesia",
"district": "Pademangan",
"subdistrict": "Pademangan Barat",
"street": "Jl. Sudirman",
"postal_code": "14410",
"rt": "01",
"rw": "02",
"label": "Home",
"address_type": "individual"
}
{
"status": "success",
"statusCode": 201,
"message": "address registered successfully",
"data": {
"address": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "660e8400-e29b-41d4-a716-446655440111",
"organization_id": null,
"province": "DKI JAKARTA",
"city": "Jakarta Utara",
"country": "Indonesia",
"district": "Pademangan",
"subdistrict": "Pademangan Barat",
"street": "Jl. Sudirman",
"village": null,
"rt": "01",
"rw": "02",
"postal_code": "14410",
"unit_number": null,
"building_number": null,
"label": "Home",
"address_type": "individual",
"created_by": "660e8400-e29b-41d4-a716-446655440111",
"updated_by": "660e8400-e29b-41d4-a716-446655440111",
"deleted_by": null,
"created_at": "2026-05-20T08:30:00.000Z",
"updated_at": "2026-05-20T08:30:00.000Z"
}
}
}
StatusWhen it occurs
400 Bad RequestValidation failure (required field missing, unknown enum, non-whitelisted field)
401 UnauthorizedBearer/cookie is invalid
403 ForbiddenMissing the create-address permission

GET /v1/addresses/:address_id bearer

Section titled “GET /v1/addresses/:address_id ”

Retrieve the detail of one address by ID. address_id is validated via ParseUUIDPipe.

bearer read-address
ParamTypeNotes
address_idUUIDMust be UUID v4
{
"status": "success",
"statusCode": 200,
"message": "address fetched successfully",
"data": {
"address": { "...": "shape matches AddressDto from POST" }
}
}
StatusWhen it occurs
400 Bad Requestaddress_id is not a UUID
401 UnauthorizedBearer/cookie is invalid
403 ForbiddenMissing the read-address permission
404 Not FoundAddress not found

List all addresses with pagination. Admin endpoint — restricted to the MORIA role.

bearer MORIA read-address
ParamTypeDefaultNotes
pagenumber1Numeric string (auto-cast); 0 is rejected
limitnumber10Numeric string; 0 is rejected
order'asc' | 'desc'descOrder
othersOther fields in QueryParamsDto (e.g. user_id, organization_id) are not processed by this endpoint — ignored without error
{
"status": "success",
"statusCode": 200,
"message": "addresses are fetched successfully",
"data": {
"limit": 10,
"count": 124,
"currentPage": 1,
"totalPages": 13,
"addresses": [
{ "...": "AddressDto" }
]
}
}
StatusWhen it occurs
401 UnauthorizedBearer/cookie is invalid
403 ForbiddenRole is not MORIA, or missing the read-address permission

PATCH /v1/addresses/:address_id bearer

Section titled “PATCH /v1/addresses/:address_id ”

Update an address. The DTO is PartialType(CreateAddressDto) — all fields optional. The server performs the update and returns the latest record.

bearer update-address
ParamTypeNotes
address_idUUIDMust be UUID v4

Same fields as CreateAddressDto, but all optional (send only what changed).

{
"label": "Office",
"address_type": "organization"
}
{
"status": "success",
"statusCode": 200,
"message": "address updated successfully",
"data": {
"address": { "...": "full AddressDto after update" }
}
}
StatusWhen it occurs
400 Bad Requestaddress_id is not a UUID, or body contains non-whitelisted field
401 UnauthorizedBearer/cookie is invalid
403 ForbiddenMissing the update-address permission
404 Not FoundAddress not found

  • individual — personal user address
  • organization — organization entity address
  • create-address
  • read-address
  • update-address
{
"message": "address_id must be a UUID",
"statusCode": 400,
"error": "Bad Request"
}
  • 400 body/query/param validation
  • 401 missing / expired token
  • 403 role/permission mismatch
  • 404 address not found