Create and Update
One endpoint PUT /listings for all listing operations: creation, updating, and publishing. The API automatically determines whether to create a new listing or update an existing one.
Create a Listing
Send property data. If externalId is new — a listing is created, if it exists — it's updated.
const response = await fetch('https://crm.rentix.md/api/v1/listings', {
method: 'PUT',
headers: {
'Authorization': 'ApiKey YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
externalId: 'apt-001',
announcementType: 'rent',
propertyType: 'residential',
propertySecondaryType: 'apartment',
announcementValue: 500,
announcementCurrency: 'EUR',
announcementPayPeriod: 'monthly',
propertyArea: 65,
propertyFloorNumber: 3,
propertyFloorsTotal: 9,
propertyQuantitySize: 'custom-value',
propertyQuantitySizeValue: 3, // 3 rooms
propertyHousingMarket: 'new-build',
propertyVisualState: 'euro-renovation',
propertyAddress: 'Chișinău, str. Columna 81/1', // or propertyCoordinates: { lat, lng } (preferred)
announcementDescription: 'Cozy 3-room apartment with heated floors and autonomous heating.'
})
});
const result = await response.json();
console.log(result.created ? 'Created' : 'Updated');
curl -X PUT https://crm.rentix.md/api/v1/listings \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalId": "apt-001",
"announcementType": "rent",
"propertyType": "residential",
"propertySecondaryType": "apartment",
"announcementValue": 500,
"announcementCurrency": "EUR",
"announcementPayPeriod": "monthly",
"propertyArea": 65,
"propertyFloorNumber": 3,
"propertyFloorsTotal": 9,
"propertyQuantitySize": "custom-value",
"propertyQuantitySizeValue": 3,
"propertyHousingMarket": "new-build",
"propertyVisualState": "euro-renovation",
"propertyAddress": "Chișinău, str. Columna 81/1",
"announcementDescription": "Cozy 3-room apartment with heated floors and autonomous heating."
}'
$data = [
'externalId' => 'apt-001',
'announcementType' => 'rent',
'propertyType' => 'residential',
'propertySecondaryType' => 'apartment',
'announcementValue' => 500,
'announcementCurrency' => 'EUR',
'announcementPayPeriod' => 'monthly',
'propertyArea' => 65,
'propertyFloorNumber' => 3,
'propertyFloorsTotal' => 9,
'propertyQuantitySize' => 'custom-value',
'propertyQuantitySizeValue' => 3,
'propertyHousingMarket' => 'new-build',
'propertyVisualState' => 'euro-renovation',
'propertyAddress' => 'Chișinău, str. Columna 81/1',
'announcementDescription' => 'Cozy 3-room apartment with heated floors and autonomous heating.'
];
$ch = curl_init('https://crm.rentix.md/api/v1/listings');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: ApiKey YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
{
"id": 42,
"externalId": "apt-001",
"status": "draft",
"publicUrl": "https://rentix.md/announcement/42",
"created": true,
"jobId": null
}
The listing is created in draft status. Photos are required for publishing.
Publish a Listing
For publishing you need:
- At least 3 photos
- Status
active
The simplest way — pass photo URLs directly when creating. Adding externalFileId is recommended for tracking:
{
"externalId": "apt-001",
"announcementStatus": "active",
"files": [
{ "url": "https://placehold.co/1920x1080/jpg?text=Living+Room", "externalFileId": "apt-001-photo-1" },
{ "url": "https://placehold.co/1920x1080/jpg?text=Bedroom", "externalFileId": "apt-001-photo-2" },
{ "url": "https://placehold.co/1920x1080/jpg?text=Kitchen", "externalFileId": "apt-001-photo-3" }
]
}
You can also use already uploaded files:
{
"externalId": "apt-001",
"announcementStatus": "active",
"files": [
{ "id": 123 },
{ "externalFileId": "apt-001-photo-2" },
{ "externalFileId": "apt-001-photo-3" }
]
}
{
"id": 42,
"externalId": "apt-001",
"status": "pending_active",
"publicUrl": "https://rentix.md/announcement/42",
"updated": true,
"jobId": 789
}
Status pending_active means the listing is being processed (photo optimization, translation). It will become active in a few seconds.
Update a Listing
Pass only changed fields — others are preserved:
{
"externalId": "apt-001",
"announcementValue": 600,
"announcementDescription": "Updated apartment description..."
}
To clear a field, send null:
{
"externalId": "apt-001",
"propertyFloorNumber": null
}
Hide or Close a Deal
| Action | How |
|---|---|
| Hide from website | "announcementStatus": "hidden" |
| Restore to website | "announcementStatus": "active" |
| Mark as completed | "announcementStatus": "completed" |
Response Fields
| Field | Type | Description |
|---|---|---|
id | number | Rentix internal ID |
externalId | string | Your CRM ID |
status | string | Current listing status |
publicUrl | string | Listing URL on rentix.md |
created | boolean | true if listing was created |
updated | boolean | true if listing was updated |
jobId | number | Job ID (when publishing) |
Request Parameters
Identification
| Field | Type | Description |
|---|---|---|
id | number | Rentix internal ID |
externalId | string | Your CRM ID (up to 255 characters) |
idorexternalId — not both at once.Listing Type (required)
| Field | Type | Values |
|---|---|---|
announcementType | enum | rent, sale |
propertyType | enum | residential, commercial, parking |
propertySecondaryType | enum | Depends on propertyType (see overview) |
Price
| Field | Type | Description |
|---|---|---|
announcementValue | number | Price (from 1 to 1,000,000,000) |
announcementCurrency | enum | EUR, USD, MDL |
announcementPayPeriod | enum | monthly, daily, hourly, yearly (rental only) |
Characteristics
| Field | Type | Description |
|---|---|---|
propertyArea | number | Area, m² |
propertyLandArea | number | Land area, m² |
propertyFloorNumber | number | Floor (from -10 to 100) |
propertyFloorsTotal | number | Total floors (from 1 to 100) |
propertyCeilingHeight | number | Ceiling height, m |
propertyQuantitySize | enum | apartment-studio, custom-value |
propertyQuantitySizeValue | number | Number of rooms (if custom-value) |
Location
| Field | Type | Description |
|---|---|---|
propertyCoordinates | object | { lat, lng } — exact GPS coordinates (recommended) |
propertyAddress | string | Street address — geocoded to coordinates automatically (max 500 characters) |
propertyCoordinatesorpropertyAddress — not both. Coordinates are recommended for accuracy. propertyAddress format: City, Street Number (e.g. Chișinău, str. Columna 81/1).Condition
| Field | Type | Values |
|---|---|---|
propertyVisualState | enum | classic-renovation, euro-renovation, design-renovation, requires-renovation, white-finish, rough-finish |
propertyHousingMarket | enum | secondary, new-build |
propertyBuildingMaterial | enum | brick, mixed, cotilet, monolithic, concrete, block, wood, panel, aerated-concrete |
propertyLayout | enum | 102, 135, 143, brezhnevka, varnitskaia, gostinka, custom, small-family, moldovan-series, ground-level, rubashka, stalinka, khrushchyovka, cheska |
propertyAttributes | array | Amenities and rules (see schema) |
Rental Terms
| Field | Type | Description |
|---|---|---|
announcementMinRentPeriod | number | Minimum rental period, hours |
announcementPrepayment | enum | no-prepayment, first-and-last-month, months-3, months-6, custom-amount |
announcementPrepaymentValue | number | Amount (if custom-amount) |
announcementRentDeposit | enum | months-1, months-3, custom-amount |
announcementRentDepositValue | number | Amount (if custom-amount) |
announcementBargain | enum | yes, no |
Description and Media
| Field | Type | Description |
|---|---|---|
announcementDescription | string/object | Description (40–2000 characters) or object with translations |
files | array | Array of files (see below) |
applyAnalysis | boolean | Auto-detect attributes from photos and description (default true) |
files element format:
| Format | Example | Description |
|---|---|---|
| URL + external ID | { "url": "...", "externalFileId": "..." } | Recommended — auto-import with tracking |
| URL only | { "url": "https://..." } | Auto-import without tracking |
| By internal ID | { "id": 123 } | Already uploaded file |
| By external ID | { "externalFileId": "photo-1" } | File with your ID |
externalFileId when passing URLs — this allows tracking files and avoiding duplication on repeat requests.User and Status
| Field | Type | Description |
|---|---|---|
user | object | { userId } or { externalUserId } — assign an agent |
announcementStatus | enum | draft, active, hidden, completed |
Validation
Check data without saving — useful for validating forms in your CRM.
POST /api/v1/listings/validate
curl -X POST https://crm.rentix.md/api/v1/listings/validate \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"announcementType": "rent",
"propertyType": "residential",
"propertySecondaryType": "apartment",
"announcementValue": 500,
"announcementDescription": "Short"
}'
{
"valid": false,
"errors": [
{
"field": "announcementDescription",
"code": "STRING_TOO_SHORT",
"message": "Minimum length: 40 characters"
}
],
"warnings": []
}
{
"valid": true,
"errors": [],
"warnings": []
}
Multilingual Description
Description can be a string or an object with translations:
{
"announcementDescription": {
"ru": "Уютная 3-комнатная квартира с тёплыми полами...",
"en": "Cozy 3-room apartment with heated floors...",
"ro": "Apartament confortabil cu 3 camere cu podele calde..."
}
}
If you pass a string — the system will automatically translate to other languages.
Supported locales: ru, en, ro
Common Errors
| Error | Cause | Solution |
|---|---|---|
Cannot provide both id and externalId | Both identifiers were passed | Use only one |
announcementDescription too short | Description is less than 40 characters | Add more details |
Minimum 3 photos required | Not enough photos for publishing | Upload at least 3 photos |
Invalid propertySecondaryType | Subtype doesn't match type | Check allowed combinations |
Next Steps
- Upload photos — media upload methods
- Bulk operations — create multiple listings at once
- Get listings — query list and details