Skip to content

Submitting applications

POST /units/{id}/applications is the only write operation in the Catalogue API. It turns an end client’s enquiry about a specific unit into records in the CRM of the company that owns the key: the client, their interests (an opportunity), a draft offer for the selected unit, and the link between the offer and the opportunity. All four are written in a single transaction — either everything is created or nothing is.

There is no signed-in user behind the request, so ownership and authorship are taken from the key: the agency that owns the key receives the application, and the user who issued the key is recorded as its author. A unit of a draft or deleted project, or of a developer without an approved contract, is treated as not found (404).

The operation is not idempotent: each call creates a new opportunity and a new offer. An existing client is reused if the company already has one with the same email address or the same mobile number (compared by digits only); in that case client.created is false and the client’s fields are left unchanged.

Field Notes
client.first_name Required, up to 255 characters.
client.email / client.mobile_number At least one is required. Email is lower-cased and must contain @; the mobile number is stored as given, including the country code.
client.last_name, landline_number, address_line1/2, city, country, postcode Optional.
client.social_links Handles only (instagram, tiktok, facebook, x), without URLs.
preferences.based_on_unit Adds the project’s property type and area, the unit’s tags, the project’s features and amenities, and the unit price as budget bounds.
preferences.property_types, preferred_area_ids, property_features, preference_ids, project_preference_ids Explicit interests, up to 100 items each. Unknown reference IDs return 400.
preferences.investment_type, min_budget, max_budget Optional. An explicit budget bound takes precedence over the unit price.
message The client’s own message, up to 5000 characters; stored in the opportunity notes.
language Offer language, en by default.
currency AED or USD; defaults to the project currency if it is one of those, otherwise AED.
Terminal window
curl https://agent-dev.azizdubai.com/units/123/applications \
-H "X-API-Key: $AZIZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"client": {
"first_name": "Ivan",
"last_name": "Petrov",
"email": "ivan.petrov@example.com",
"mobile_number": "+971 50 111 22 33"
},
"preferences": { "based_on_unit": true },
"message": "Please call me after 6 pm"
}'

A successful call returns 201 with the created (or reused) client, the opportunity with its board stage, and the draft offer including its public uuid. The offer PDF is generated and sent by the main Aziz backend, so offer.is_sent is always false here.

400 covers a body that is not JSON or exceeds 64 KiB, a missing first name, no contact channel (client.email or client.mobile_number is required), an unknown reference ID, an inverted budget range, or a value over its maximum length. 401 additionally covers a key whose company or author has been removed (api key author is gone). 500 offer status catalogue is empty means reference data is not configured on the server and cannot be fixed by the caller.