Operații bulk
Operațiile bulk permit procesarea a până la 100 anunțuri într-o singură cerere. Folosește-le pentru sincronizarea inițială și actualizări în masă.
De ce să folosești bulk
| Abordare | Cereri pentru 100 anunțuri |
|---|---|
| Cereri separate | 100 |
| Operație bulk | 1 |
Bulk reduce costurile de rețea și accelerează sincronizarea.
Tipuri de operații
Fiecare operație trebuie să conțină câmpul op care definește tipul acțiunii:
| Operație | Descriere |
|---|---|
upsert | Creează sau actualizează anunț |
link | Leagă external ID la un anunț existent |
unlink | Dezleagă external ID |
delete | Șterge anunț |
validate | Verifică date fără salvare |
Creează sau actualizează anunțuri
Operația upsert creează un anunț nou sau actualizează unul existent după externalId.
const response = await fetch('https://crm.rentix.md/api/v1/listings/bulk', {
method: 'POST',
headers: {
'Authorization': 'ApiKey YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
operations: [
{
op: 'upsert',
externalId: 'apt-001',
announcementType: 'rent',
propertyType: 'residential',
propertySecondaryType: 'apartment',
announcementValue: 500,
announcementCurrency: 'EUR',
announcementDescription: 'Apartament confortabil în centru...',
files: [
{ url: 'https://example.com/photo1.jpg', externalFileId: 'apt-001-photo-1' },
{ url: 'https://example.com/photo2.jpg', externalFileId: 'apt-001-photo-2' },
{ url: 'https://example.com/photo3.jpg', externalFileId: 'apt-001-photo-3' }
],
announcementStatus: 'active'
},
{
op: 'upsert',
externalId: 'apt-002',
announcementType: 'rent',
propertyType: 'residential',
propertySecondaryType: 'apartment',
announcementValue: 700,
announcementCurrency: 'EUR',
announcementDescription: 'Apartament spațios cu balcon...',
files: [
{ url: 'https://example.com/photo4.jpg', externalFileId: 'apt-002-photo-1' },
{ url: 'https://example.com/photo5.jpg', externalFileId: 'apt-002-photo-2' },
{ url: 'https://example.com/photo6.jpg', externalFileId: 'apt-002-photo-3' }
],
announcementStatus: 'active'
}
]
})
});
const result = await response.json();
console.log(`Succes: ${result.summary.succeeded}/${result.summary.total}`);
curl -X POST https://crm.rentix.md/api/v1/listings/bulk \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{
"op": "upsert",
"externalId": "apt-001",
"announcementStatus": "active",
"announcementType": "rent",
"propertyType": "residential",
"propertySecondaryType": "apartment",
"announcementValue": 500,
"announcementCurrency": "EUR",
"files": [
{ "url": "https://example.com/photo1.jpg", "externalFileId": "apt-001-photo-1" }
]
}
]
}'
$data = [
'operations' => [
[
'op' => 'upsert',
'externalId' => 'apt-001',
'announcementType' => 'rent',
'propertyType' => 'residential',
'propertySecondaryType' => 'apartment',
'announcementValue' => 500,
'announcementCurrency' => 'EUR',
'announcementStatus' => 'active',
'files' => [
['url' => 'https://example.com/photo1.jpg', 'externalFileId' => 'apt-001-photo-1']
]
]
]
];
$ch = curl_init('https://crm.rentix.md/api/v1/listings/bulk');
curl_setopt($ch, CURLOPT_POST, true);
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);
{
"results": [
{
"op": "upsert",
"externalId": "apt-001",
"id": 42,
"success": true,
"created": true,
"updated": false
},
{
"op": "upsert",
"externalId": "apt-002",
"id": 43,
"success": true,
"created": true,
"updated": false
}
],
"summary": {
"total": 2,
"succeeded": 2,
"failed": 0
}
}
Leagă external ID
Operația link conectează ID-ul tău din CRM cu un anunț existent în Rentix. Folosește-o pentru anunțuri create prin interfața web.
{
"operations": [
{ "op": "link", "id": 42, "externalId": "apt-001" },
{ "op": "link", "id": 43, "externalId": "apt-002" }
]
}
{
"results": [
{ "op": "link", "id": 42, "externalId": "apt-001", "success": true, "linked": true },
{ "op": "link", "id": 43, "externalId": "apt-002", "success": true, "linked": true }
]
}
Dezleagă external ID
Operația unlink elimină legătura dintre anunț și external ID.
{
"operations": [
{ "op": "unlink", "id": 42 },
{ "op": "unlink", "externalId": "apt-002" }
]
}
Șterge anunțuri
Operația delete șterge anunțurile.
{
"operations": [
{ "op": "delete", "externalId": "apt-old-001" },
{ "op": "delete", "id": 99 }
]
}
{
"results": [
{ "op": "delete", "externalId": "apt-old-001", "success": true, "deleted": true }
]
}
Verifică datele
Operația validate verifică datele fără salvare. Folosește pentru validarea formularelor în CRM.
{
"operations": [
{
"op": "validate",
"externalId": "apt-new",
"announcementType": "rent",
"propertyType": "residential",
"propertySecondaryType": "apartment",
"announcementValue": 500
}
]
}
{
"results": [
{
"op": "validate",
"externalId": "apt-new",
"success": true,
"valid": true,
"errors": [],
"warnings": []
}
]
}
Combină operații
Într-o singură cerere poți executa tipuri diferite de operații:
{
"operations": [
{ "op": "upsert", "externalId": "apt-001", "announcementValue": 550 },
{ "op": "upsert", "externalId": "apt-002", "announcementStatus": "hidden" },
{ "op": "link", "id": 99, "externalId": "apt-003" },
{ "op": "delete", "externalId": "apt-old" }
]
}
Coduri HTTP de răspuns
Codul HTTP al răspunsului bulk depinde de rezultatul operațiilor individuale:
| Status | Condiție | Descriere |
|---|---|---|
| 200 | Toate operațiile au reușit | Fiecare operație are success: true |
| 207 | Succes parțial | Unele operații au reușit, altele au eșuat |
| 422 | Toate operațiile au eșuat | Fiecare operație are success: false |
Verifică întotdeauna câmpul summary și results individuale indiferent de codul HTTP.
Gestionarea erorilor
O eroare într-o operație nu oprește celelalte. Verifică success pentru fiecare rezultat.
{
"results": [
{ "op": "upsert", "externalId": "apt-001", "id": 42, "success": true },
{
"op": "upsert",
"externalId": "apt-002",
"id": null,
"success": false,
"error": {
"statusCode": 400,
"body": {
"error": "propertyType is required",
"error_code": "VALIDATION_ERROR"
}
}
},
{ "op": "upsert", "externalId": "apt-003", "id": 44, "success": true }
],
"summary": {
"total": 3,
"succeeded": 2,
"failed": 1
}
}
Procesează operațiile nereușite:
const result = await response.json();
const failed = result.results.filter(r => !r.success);
if (failed.length > 0) {
console.error('Erori:', failed);
// Logare sau reîncercare mai târziu
}
Recomandări
Trimite secvențial
Trimite pachetele secvențial, nu în paralel. Sistemul procesează operațiile în ordinea cozii — trimiterea paralelă nu va accelera procesarea.
Actualizează doar datele modificate
După sincronizarea inițială, trimite doar anunțurile modificate. Retrimiterea tuturor anunțurilor fără modificări este o utilizare ineficientă a API-ului.
Folosește actualizări parțiale
Transmite doar câmpurile modificate. Pentru a goli un câmp, trimite null:
{
"op": "upsert",
"externalId": "apt-001",
"announcementValue": 600,
"propertyFloorNumber": null
}
Limitări
| Parametru | Valoare |
|---|---|
| Maximum operații per cerere | 100 |
Câmpuri operație upsert | vezi PUT /listings |
Coduri eroare
| Cod | Descriere | Soluție |
|---|---|---|
VALIDATION_ERROR | Eroare validare câmpuri | Verifică câmpurile obligatorii și formatele |
USER_RESOLUTION_FAILED | Agent negăsit | Verifică userId sau externalUserId |
NOT_FOUND | Anunț negăsit | Folosește externalId pentru upsert |
EXTERNAL_ID_ALREADY_LINKED | External ID deja folosit | Folosește un external ID unic |