Reten Docs
Commerces

Sync Commerces

Batch upsert commerces from external systems.

POST /api/commerces/sync

Bulk upsert commerces with addresses and users. Uses external_id as the match key — creates new commerces or updates existing ones.

Auth: Required — SYNC_COMMERCES permission

Request Body

FieldTypeRequiredDescription
itemsarrayYesArray of commerce objects to sync

Each commerce object:

FieldTypeRequiredDescription
external_idstringYesExternal system identifier (match key)
namestringYesCommerce name
global_external_idstringNoGlobal external ID across systems
tax_idstringNoTax ID
metadataobjectNoArbitrary JSON
addressesarrayNoAddresses to sync
usersarrayNoUsers to sync

Each address object:

FieldTypeRequiredDescription
address_aliasstringNoAlias or label for this address
is_primarybooleanNoSet as primary address
country_codestringNoCountry code
regionstringNoState or region
communestringNoCommune or district
citystringNoCity
streetstringNoStreet name
street_numberstringNoStreet number
unitstringNoApartment, suite, or unit
formatted_addressstringNoFull formatted address string
latitudenumberNoLatitude coordinate
longitudenumberNoLongitude coordinate
source_refstringNoExternal reference from the source system

Each user object:

FieldTypeRequiredDescription
external_idstringYesExternal system identifier for the user
namestringNoFull name
rolesstring[]NoCommerce user roles
contactsarrayNoUser contacts

Each contact object:

FieldTypeRequiredDescription
contact_typestringYesPHONE, EMAIL, WHATSAPP, or OTHER
valuestringYesContact value
is_primarybooleanNoSet as primary for this type

Example

curl -X POST https://api.reten.ai/api/commerces/sync \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "external_id": "store-001",
        "name": "Main Street Store",
        "tax_id": "12345678-9",
        "addresses": [
          {
            "street": "123 Main St",
            "city": "Santiago",
            "region": "Metropolitana",
            "country_code": "CL",
            "is_primary": true,
            "latitude": -33.4489,
            "longitude": -70.6693
          }
        ],
        "users": [
          {
            "external_id": "usr-001",
            "name": "Maria Garcia",
            "roles": ["OWNER"],
            "contacts": [
              {
                "contact_type": "PHONE",
                "value": "+56912345678",
                "is_primary": true
              }
            ]
          }
        ]
      }
    ]
  }'
import axios from 'axios';

const response = await axios.post(
  'https://api.reten.ai/api/commerces/sync',
  {
    items: [
      {
        external_id: 'store-001',
        name: 'Main Street Store',
        tax_id: '12345678-9',
        addresses: [
          {
            street: '123 Main St',
            city: 'Santiago',
            region: 'Metropolitana',
            country_code: 'CL',
            is_primary: true,
            latitude: -33.4489,
            longitude: -70.6693,
          },
        ],
        users: [
          {
            external_id: 'usr-001',
            name: 'Maria Garcia',
            roles: ['OWNER'],
            contacts: [
              {
                contact_type: 'PHONE',
                value: '+56912345678',
                is_primary: true,
              },
            ],
          },
        ],
      },
    ],
  },
  {
    headers: {
      Authorization: 'Bearer <token>',
      'x-tenant-id': '<tenant-id>',
    },
  }
);

const { created, updated, total } = response.data;

Response 201 Created

{
  "created": 1,
  "updated": 0,
  "total": 1
}

Notes

  • Uses external_id as match key for idempotent upsert
  • Placeholder commerces (isPlaceholder = true) are created for referenced but undefined entries
  • Metadata uses merge semantics on update