Addresses
5 API calls in this section.
Create Address
/addressesCreates a new address in the system, returns an existing saved address for duplicate user coordinates, or returns normalized address JSON when save_to_address_book=false.
Key rules
Required address fields are
country,latitude, andlongitude.address_line1is optional whenfull_addressis provided; the backend copiesfull_addressintoaddress_line1.address_typeis optional and defaults touserwhen omitted.city,state,postal_code,address_line2, title, contact info, and other descriptive fields are optional; empty optional strings are accepted.save_to_address_book=falsereturns normalized JSON (no DB insert and no saved-coordinate lookup).save_to_address_book=true(default) uses exact active coordinates scoped only byuser_id. The identity isuser_id + latitude + longitude;tenant_id, system scope, andaddress_typedo not change the match. Coordinates are compared at the database's 8-decimal precision. Inactive addresses do not block reuse.New coordinates create a row and return HTTP
201withaction=address_created.Existing coordinates skip insertion and return HTTP
200withsuccess, a localizedAddress already saved as {existing saved title}message, and the complete existingaddressobject. The newly submitted title does not replace the existing title or appear in this message. The duplicate response intentionally has noactionfield.is_primaryis the frontend default-address toggle. For a customer with existing active addresses,falsekeeps the new address non-primary andtruemakes it primary, unsetting the prior primary address. The backend makes the first active address primary even when this field isfalse.
Frontend integration contract
Send
country,latitude, andlongitudefor create and save/normalize requests.Send
address_line1when available. If omitted, sendfull_addressand it will be used asaddress_line1.Send the user's label in
title, for example{"en":"home"}, when creating an address at new coordinates. If the coordinates already exist, the response message uses the title from the returned existingaddressobject.Send
city,postal_code,state, and other optional address fields only when available;""is allowed for optional strings.Send
is_primary: trueonly when the user explicitly selects "Use this address as default".HTTP
201withaction=address_createdmeans a new row was created; select the returnedaddress.idand continue normally.HTTP
200withsuccess=truemeans those coordinates were already saved. Showmessage, close the address modal, select the returnedaddress.id, and continue the original flow. Do not expect anactionfield or a new address row.400means the address was not saved; usedetails[].fieldto highlight the exact invalid field.
Required Fields
country,latitude,longitudeaddress_line1orfull_address(if missing,full_addressis copied toaddress_line1)
Owner Constraint
user_iddefaults to the authenticated user when omitted.tenant_idcan be provided directly or through the query/context when needed.
Query parameters
| Parameter | Type | Description |
|---|---|---|
language | string | Language of the response Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
address_type | string | — |
user_id | string | — |
title | object | — |
title.en | string | — |
full_address | string | — |
address_line1 | string | — |
address_line2 | string | — |
street | string | — |
building | string | — |
floor | string | — |
apartment | string | — |
city | string | — |
Show 11 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
state | string | — |
country | string | — |
country_code | string | — |
postal_code | string | — |
latitude | number | — |
longitude | number | — |
contact_info | object | — |
contact_info.phone | string | — |
contact_info.email | string | — |
is_primary | boolean | — |
save_to_address_book | boolean | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/addresses?language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "address_type": "user",6 "user_id": "{{user_id}}",7 "title": {8 "en": "Home Address"9 },10 "full_address": "123 Main St, Anytown, CA 12345",11 "address_line1": "123 Main St",12 "address_line2": "Apt 4B",13 "street": "Main St",14 "building": "123",15 "floor": "4",16 "apartment": "4B",17 "city": "Anytown",18 "state": "CA",19 "country": "United States",20 "country_code": "USA",21 "postal_code": "12345",22 "latitude": 37.7749,23 "longitude": -122.4194,24 "contact_info": {25 "phone": "+123456789",26 "email": "a@example.com"27 },28 "is_primary": false,29 "save_to_address_book": true30}'Replace {{placeholders}} with your own values before sending.
Response examples
1{2 "success": true,3 "action": "address_created",4 "message": "Address created successfully",5 "address": {6 "id": "uuid-example",7 "user_id": "user-uuid",8 "tenant_id": null,9 "address_type": "user",10 "is_primary": false,11 "title": {12 "en": "Home Address"13 },14 "address_line1": "123 Main St",15 "city": "Anytown",16 "country": "United States",17 "latitude": 37.7749,18 "longitude": -122.4194,19 "created_at": "2023-01-01T12:00:00Z",20 "updated_at": "2023-01-01T12:00:00Z"21 }22}Get Address
/addresses/:addressIdRetrieves a specific address by ID.
Users can only access their own addresses
Users can access addresses of tenants they belong to
System admins can access any address
Response
Returns the complete address object with all fields
Returns 404 if address not found
Returns 403 if user is not authorized to access the address
Path parameters
| Parameter | Type | Description |
|---|---|---|
addressIdRequired | string | UUID of the address to retrieve |
Query parameters
| Parameter | Type | Description |
|---|---|---|
language | string | Language of the response Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/addresses/${ADDRESSID}?language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "message": "Address retrieved successfully",4 "address": {5 "id": "uuid-example",6 "user_id": "user-uuid",7 "tenant_id": null,8 "address_type": "user",9 "is_primary": true,10 "title": {11 "en": "Home Address"12 },13 "full_address": "123 Main St, Anytown, CA 12345",14 "address_line1": "123 Main St",15 "address_line2": "Apt 4B",16 "street": "Main St",17 "building": "123",18 "floor": "4",19 "apartment": "4B",20 "city": "Anytown",21 "state": "CA",22 "country": "United States",23 "country_code": "USA",24 "postal_code": "12345",25 "latitude": 37.7749,26 "longitude": -122.4194,27 "is_billing": false,28 "is_shipping": true,29 "is_active": true,30 "metadata": {31 "delivery_instructions": "Leave at front door",32 "landmark": "Blue house with white fence",33 "is_verified": false,34 "verification_date": null35 },36 "created_at": "2023-01-01T12:00:00Z",37 "updated_at": "2023-01-01T12:00:00Z"38 }39}List Addresses
/addressesLists addresses with pagination and filtering options.
Authentication & Scope
No role: own addresses only
tenant_admin+ tenantId: returns all addresses from alltenant_adminusers of that tenantuserId param: filter to specific user's addresses
System admins can see all addresses
Response
Returns a paginated list of addresses
Includes pagination metadata (page, limit, total)
Query parameters
| Parameter | Type | Description |
|---|---|---|
page | string | Page number for pagination (default: 1) Example: |
limit | string | Number of items per page (default: 10) Example: |
userId | string | Filter addresses by user ID |
tenantId | string | Filter addresses by tenant ID (or from auth context) |
addressType | string | Filter by address type (user, tenant, branch, warehouse, customer, pickup, delivery) |
search | string | Search term to filter addresses by |
language | string | Language of the response Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/addresses?page=1&limit=10&userId=&tenantId=&addressType=&search=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "message": "Addresses retrieved successfully",4 "addresses": [5 {6 "id": "uuid-example-1",7 "user_id": "user-uuid",8 "tenant_id": null,9 "address_type": "user",10 "title": {11 "en": "Home Address"12 },13 "city": "Anytown",14 "country": "United States",15 "created_at": "2023-01-01T12:00:00Z",16 "updated_at": "2023-01-01T12:00:00Z"17 },18 {19 "id": "uuid-example-2",20 "user_id": "user-uuid",21 "tenant_id": null,22 "address_type": "user",23 "title": {24 "en": "Work Address"25 },26 "city": "Business City",27 "country": "United States",28 "created_at": "2023-01-02T12:00:00Z",29 "updated_at": "2023-01-02T12:00:00Z"30 }31 ],32 "page": 1,33 "limit": 10,34 "total": 235}Update Address
/addresses/:addressIdUpdates an existing address.
Required Fields
country,latitude,longitudeaddress_line1orfull_address(if missing,full_addressis copied toaddress_line1)
Optional Fields
address_type: Type of address (must be one of: 'user', 'tenant', 'branch', 'warehouse', 'customer', 'pickup', 'delivery')title: Title/name for this address (JSONB object with language keys)full_address: Complete formatted address as a single text fieldcity: City name; optional and may be an empty stringaddress_line2: Second line of the address (e.g., apartment, suite)street: Street namebuilding: Building name or numberfloor: Floor number or nameapartment: Apartment or unit numberstate: State/region; optional and may be an empty stringpostal_code: Postal code; optional and may be an empty stringis_primary: Set totrueonly when the user explicitly selects "Set as Primary". The backend then atomically unsets the previous primary address and promotes this address. Sendingfalsedoes not unset an existing primary address.is_active: Flag indicating if this address is currently active
Coordinate Uniqueness
The address may keep its own current coordinates.
It cannot be updated to the exact coordinates of another active address belonging to the same
user_id.The uniqueness key excludes
tenant_id, system scope, andaddress_type; coordinates are compared at 8-decimal database precision. Inactive addresses do not block reuse.Users can only update their own addresses
Users can update addresses of tenants they are admins for
System admins can update any address
Frontend integration contract
Send
country,latitude, andlongitudeon address update.Send
address_line1if available; otherwise sendfull_addressand it will be copied intoaddress_line1.Do not block save when
city,postal_code,state, or other optional fields are unavailable; empty optional strings are accepted.Send
is_primary: trueto set this address as the customer's default.Use the returned
address.is_primaryvalue to update the Primary badge and default-address selection.On
400, usedetails[].fieldto show the exact field that failed validation.On HTTP
409withcode=address_coordinates_already_exist, retain the edited form and show the localizedmessage.On
500, retain the existing selected delivery/default address because the primary promotion did not complete.
Note
user_idandtenant_idare ignored; ownership cannot be changed through this endpoint.
Path parameters
| Parameter | Type | Description |
|---|---|---|
addressIdRequired | string | UUID of the address to update |
Query parameters
| Parameter | Type | Description |
|---|---|---|
language | string | Language of the response Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
title | object | — |
title.en | string | — |
address_line1 | string | — |
city | string | — |
postal_code | string | — |
country | string | — |
latitude | number | — |
longitude | number | — |
is_primary | boolean | — |
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/addresses/${ADDRESSID}?language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "title": {6 "en": "Updated Home Address"7 },8 "address_line1": "456 New St",9 "city": "",10 "postal_code": "",11 "country": "United States",12 "latitude": 37.7749,13 "longitude": -122.4194,14 "is_primary": true15}'Response examples
1{2 "success": true,3 "message": "Address updated successfully",4 "address": {5 "id": "uuid-example",6 "user_id": "user-uuid",7 "tenant_id": null,8 "address_type": "user",9 "title": {10 "en": "Updated Home Address"11 },12 "address_line1": "456 New St",13 "city": "",14 "postal_code": "",15 "country": "United States",16 "latitude": 37.7749,17 "longitude": -122.4194,18 "is_primary": true,19 "created_at": "2023-01-01T12:00:00Z",20 "updated_at": "2023-01-03T15:30:00Z"21 }22}Delete Address
/addresses/:addressIdDeletes an address by ID.
Users can only delete their own addresses
Users can delete addresses of tenants they are admins for
System admins can delete any address
Response
Returns success message on successful deletion
Returns 404 if address not found
Returns 403 if user is not authorized to delete the address
Path parameters
| Parameter | Type | Description |
|---|---|---|
addressIdRequired | string | UUID of the address to delete |
Query parameters
| Parameter | Type | Description |
|---|---|---|
language | string | Language of the response Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request DELETE "https://staging-api.ondi.io/functions/v1/addresses/${ADDRESSID}?language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "message": "Address deleted successfully"4}