Store Management API
The Store Management API allows you to manage store information in the Nilo platform. These endpoints help you create, update, and retrieve store data, including store details, users, credit information, and settings.
Understanding Stores
Stores in Nilo represent the retail locations that can place orders:
-
Store Structure
- Unique internal code (matches ERP)
- Owner and legal information
- Address and location data
- User associations (via phone or email)
- Credit and payment status
- Settings and configurations
- Group associations (price lists, stock, promotions)
-
Store Hierarchy
- Independent entities with unique identifiers
- Can have multiple associated users
- Maintain their own credit status
- Can belong to different groupers
- Support batch operations for updates
Important Considerations
- Unique Codes: Each store requires a unique internal code that matches your ERP system
- User Management: Users are associated via phone number (with country code) or email
- Credit System: Stores have credit limits and payment status tracking
- Location Data: Stores require accurate address and geolocation information
- Multiple Groupers: Stores can belong to multiple promotion groupers if configured
- Batch Operations: Support for efficiently updating multiple stores
Single Store Operations
Create Store
/storeCreate a new store in the Nilo platform. This endpoint is used to register all store details including:
- Store information (owner name, legal details)
- Address and location data
- Contact information
- Group associations
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| ownerName | string | Yes | Name of the store owner |
| ownerIdentifier | string | No | Owner identifier |
| internalCode | string | Yes | Store code (matches ERP) |
| addresses | array | Yes | List of store addresses |
| legalName | string | Yes | Legal business name |
| legalId | string | Yes | Legal business identifier |
| latitude | string | No | Store latitude |
| longitude | string | No | Store longitude |
| addressFormat | string | No | Google Maps formatted address |
| supportContactEmail | string | No | Email for support contact |
| supportContactPhone | string | No | Phone for support contact |
| promotionGrouperCode | string | No | Code for promotion group association |
| promotionGrouperCodes | array | No | Array of promotion grouper codes (only if multiple grouper configuration is enabled by Nilo) |
| stockGrouperCode | string | No | Code for stock group association |
| deliveryConfigCode | string | No | Delivery configuration code to assign. If omitted, the current assignment is unchanged |
| priceListCode | string | No | Code for price list association |
| routeCode | string | No | Route code for delivery |
| settings | object | No | Store settings (dropSize, etc.) |
addresses array items:
| Parameter | Type | Required | Description |
|---|---|---|---|
| internalCode | string | No | Address code (same as in ERP) |
| addressLine | string | Yes | Full address |
| apartmentNumber | string | No | Apartment/unit number |
| zipCode | string | No | ZIP/postal code |
settings object:
| Parameter | Type | Required | Description |
|---|---|---|---|
| dropSize | object | No | Minimum order amount (amount, currency) |
Request Body Example
{
"ownerName": "Owner name",
"ownerIdentifier": "Owner identifier",
"internalCode": "1234",
"addresses": [
{
"internalCode": "1234",
"addressLine": "25 de mayo 1200, Buenos Aires, Argentina",
"apartmentNumber": "2",
"zipCode": "2400"
}
],
"legalName": "Legal Name S.A.",
"legalId": "30-12345678-9",
"latitude": "-34.545278",
"longitude": "-58.449722",
"addressFormat": "Av. Pres. Figueroa Alcorta 7597, C1428 Buenos Aires",
"supportContactEmail": "support@store.com",
"supportContactPhone": "+5491123456789",
"promotionGrouperCode": "1234",
"stockGrouperCode": "6789",
"deliveryConfigCode": "DELIVERY-1",
"priceListCode": "1222",
"routeCode": "ROUTE1",
"settings": {
"dropSize": {
"amount": 1000,
"currency": "USD"
}
}
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Get All Stores
/storeRetrieve a paginated list of all stores. This endpoint is useful for:
- Browsing through the store catalog
- Implementing cursor-based pagination
- Filtering stores by enabled status
When a store has a delivery configuration assigned, its response includes:
{
"deliveryConfig": {
"name": "Weekly delivery",
"internalCode": "DELIVERY-1"
}
}
The deliveryConfig property is omitted when the store has no delivery configuration assigned.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| take | number | No | Number of items per page (default: 50, max: 50) |
| page | string | No | Page number (default: 1) |
| cursor | string | No | Cursor for pagination. First call should pass 0, subsequent calls should use the cursor from the last item of the previous response |
| enabled | boolean | No | Filter by enabled status |
Response Example
{
"data": [
{
"ownerName": "Jane Doe",
"internalCode": "STORE-1234",
"ownerIdentifier": "OWNER-42",
"legalName": "Jane Doe Market LLC",
"legalId": "TAX-123456",
"addressFormat": "123 Main Street, Springfield",
"addresses": [
{
"internalCode": "ADDRESS-1",
"addressLine": "123 Main Street",
"apartmentNumber": "Suite 2",
"zipCode": "10001"
}
],
"latitude": "40.7128",
"longitude": "-74.0060",
"enabled": true,
"deleted": false,
"users": [
{
"username": "jane@example.com",
"name": "Jane Doe",
"phone": "5551234567",
"countryCode": "+1",
"lastLoginAt": "2026-07-31T20:46:14.325Z"
}
],
"credit": { "amount": 5000, "currency": "USD" },
"priceList": { "name": "Retail", "internalCode": "PRICE-1" },
"promotionGroup": {
"name": "Default promotions",
"internalCode": "PROMO-GROUP-1"
},
"stockGroup": {
"name": "Main stock",
"internalCode": "STOCK-GROUP-1"
},
"deliveryConfig": {
"name": "Weekly delivery",
"internalCode": "DELIVERY-1"
},
"settings": {
"supportContactEmail": "support@example.com",
"supportContactPhone": "+15551234567",
"dropSize": { "value": 1000, "text": "USD 1,000.00" }
},
"commertialRoute": {
"name": "North route",
"internalCode": "ROUTE-1"
}
}
],
"page": {
"cursorBased": {
"firstCursor": "1234",
"lastCursor": "1234",
"hasNextPage": false,
"hasPreviousPage": false
}
}
}
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store?take=50&cursor=0&enabled=true",
{
method: "GET",
headers: headers,
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store"
params = {
"take": 50,
"cursor": 0,
"enabled": True
}
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
response = requests.get(url, headers=headers, params=params)
print(response.text)
Upsert Store
/storeCreate a new store or update an existing one based on the internal code. This is useful for:
- Syncing store data from your ERP
- Creating stores if they don't exist, updating if they do
- Simplifying store management logic
Request Body Parameters
Same as Create Store, with enabled being required:
| Parameter | Type | Required | Description |
|---|---|---|---|
| internalCode | string | Yes | Store code (matches ERP) - used to find existing store |
| ownerName | string | Yes | Name of the store owner |
| addresses | array | Yes | List of store addresses |
| legalName | string | Yes | Legal business name |
| legalId | string | Yes | Legal business identifier |
| enabled | boolean | Yes | Whether the store is enabled |
| ownerIdentifier | string | No | Owner identifier |
| latitude | string | No | Store latitude |
| longitude | string | No | Store longitude |
| addressFormat | string | No | Google Maps formatted address |
| supportContactEmail | string | No | Email for support contact |
| supportContactPhone | string | No | Phone for support contact |
| promotionGrouperCode | string | No | Code for promotion group association |
| promotionGrouperCodes | array | No | Array of promotion grouper codes (only if multiple grouper configuration is enabled) |
| stockGrouperCode | string | No | Code for stock group association |
| deliveryConfigCode | string | No | Delivery configuration code to assign. If omitted, the current assignment is unchanged |
| priceListCode | string | No | Code for price list association |
| routeCode | string | No | Route code for delivery |
| latePayer | boolean | No | Whether the store is a late payer |
| settings | object | No | Store settings (dropSize, etc.) |
Request Body Example
{
"internalCode": "1234",
"ownerName": "Owner name",
"addresses": [
{
"addressLine": "25 de mayo 1200, Buenos Aires, Argentina",
"zipCode": "2400"
}
],
"legalName": "Legal Name S.A.",
"legalId": "30-12345678-9",
"enabled": true,
"stockGrouperCode": "6789",
"deliveryConfigCode": "DELIVERY-1",
"priceListCode": "1222"
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Get Store Details
/store/{code}Retrieve detailed information about a specific store. This endpoint returns:
- Store metadata
- Address information
- User associations
- Credit status
- Group associations
- The assigned delivery configuration, when present
The optional deliveryConfig response property has the same shape in this endpoint and in GET /store: { "name": string, "internalCode": string }. It is omitted when no delivery configuration is assigned.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Response Example
{
"ownerName": "Jane Doe",
"internalCode": "STORE-1234",
"ownerIdentifier": "OWNER-42",
"legalName": "Jane Doe Market LLC",
"legalId": "TAX-123456",
"addressFormat": "123 Main Street, Springfield",
"addresses": [
{
"internalCode": "ADDRESS-1",
"addressLine": "123 Main Street",
"apartmentNumber": "Suite 2",
"zipCode": "10001"
}
],
"latitude": "40.7128",
"longitude": "-74.0060",
"enabled": true,
"deleted": false,
"users": [
{
"username": "jane@example.com",
"name": "Jane Doe",
"phone": "5551234567",
"countryCode": "+1",
"lastLoginAt": "2026-07-31T20:46:14.325Z"
}
],
"credit": { "amount": 5000, "currency": "USD" },
"priceList": { "name": "Retail", "internalCode": "PRICE-1" },
"promotionGroup": {
"name": "Default promotions",
"internalCode": "PROMO-GROUP-1"
},
"stockGroup": {
"name": "Main stock",
"internalCode": "STOCK-GROUP-1"
},
"deliveryConfig": {
"name": "Weekly delivery",
"internalCode": "DELIVERY-1"
},
"settings": {
"supportContactEmail": "support@example.com",
"supportContactPhone": "+15551234567",
"dropSize": { "value": 1000, "text": "USD 1,000.00" }
},
"commertialRoute": {
"name": "North route",
"internalCode": "ROUTE-1"
}
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
};
fetch("https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234", {
method: "GET",
headers: headers,
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
response = requests.get(url, headers=headers)
print(response.text)
Update Store
/store/{code}Update an existing store's information. This endpoint allows you to:
- Modify store details
- Update address information
- Change group associations
- Adjust settings
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| ownerName | string | Yes | Name of the store owner |
| addresses | array | Yes | List of store addresses |
| legalName | string | Yes | Legal business name |
| legalId | string | Yes | Legal business identifier |
| enabled | boolean | Yes | Whether the store is enabled |
| ownerIdentifier | string | No | Owner identifier |
| latitude | string | No | Store latitude |
| longitude | string | No | Store longitude |
| addressFormat | string | No | Google Maps formatted address |
| supportContactEmail | string | No | Email for support contact |
| supportContactPhone | string | No | Phone for support contact |
| promotionGrouperCode | string | No | Code for promotion group association |
| promotionGrouperCodes | array | No | Array of promotion grouper codes (only if multiple grouper configuration is enabled) |
| stockGrouperCode | string | No | Code for stock group association |
| deliveryConfigCode | string | No | Delivery configuration code to assign. If omitted, the current assignment is unchanged |
| priceListCode | string | No | Code for price list association |
| routeCode | string | No | Route code for delivery |
| latePayer | boolean | No | Whether the store is a late payer |
| settings | object | No | Store settings (dropSize, etc.) |
Request Body Example
{
"ownerName": "Owner name",
"ownerIdentifier": "Owner identifier",
"addresses": [
{
"internalCode": "1234",
"addressLine": "25 de mayo 1200, Buenos Aires, Argentina",
"apartmentNumber": "2",
"zipCode": "2400"
}
],
"latitude": "-34.545278",
"longitude": "-58.449722",
"addressFormat": "Av. Pres. Figueroa Alcorta 7597, C1428 Buenos Aires",
"legalName": "Legal Name S.A.",
"legalId": "30-12345678-9",
"enabled": true,
"supportContactEmail": "support@store.com",
"supportContactPhone": "+5491123456789",
"promotionGrouperCode": "1234",
"stockGrouperCode": "6789",
"deliveryConfigCode": "DELIVERY-1",
"priceListCode": "1222",
"routeCode": "1234",
"latePayer": false,
"settings": {
"dropSize": {
"amount": 1000,
"currency": "USD"
}
}
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
ownerName: "Updated Owner Name",
addresses: [
{
addressLine: "New Address Line",
apartmentNumber: "3",
zipCode: "2401",
},
],
legalName: "Updated Legal Name",
promotionGrouperCode: "5678",
};
fetch("https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234", {
method: "PUT",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"ownerName": "Updated Owner Name",
"addresses": [
{
"addressLine": "New Address Line",
"apartmentNumber": "3",
"zipCode": "2401"
}
],
"legalName": "Updated Legal Name",
"promotionGrouperCode": "5678"
}
response = requests.put(url, headers=headers, json=data)
print(response.text)
Change Store Status
/store/{code}/statusEnable or disable a store. This endpoint allows you to:
- Control store visibility
- Manage store access
- Update operational status
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | Yes | Whether the store should be enabled |
Request Body Example
{
"enabled": true
}
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
enabled: true,
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/status",
{
method: "PUT",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/status"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"enabled": True
}
response = requests.put(url, headers=headers, json=data)
print(response.text)
Manage Store Users
Add User by Phone
/store/{code}/add/userAdd a user to a store using their phone number. This endpoint allows:
- Associating new users with the store via phone
- Setting up user access
- Managing store personnel
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| countryCode | string | Yes | Country code with + prefix (e.g., "+54") |
| phone | string | Yes | Phone number without country code |
| name | string | No | User's name |
Request Body Example
{
"countryCode": "+54",
"phone": "1123456789",
"name": "John Doe"
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
countryCode: "+54",
phone: "1123456789",
name: "John Doe",
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/add/user",
{
method: "PUT",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/add/user"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"countryCode": "+54",
"phone": "1123456789",
"name": "John Doe"
}
response = requests.put(url, headers=headers, json=data)
print(response.text)
Add User by Email
/store/{code}/add/user-emailAdd a user to a store using their email address. This endpoint allows:
- Associating new users with the store via email
- Setting up user access for email-based authentication
- Managing store personnel
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email | |
| name | string | No | User's name |
Request Body Example
{
"email": "user@example.com",
"name": "John Doe"
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
email: "user@example.com",
name: "John Doe",
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/add/user-email",
{
method: "PUT",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/add/user-email"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"email": "user@example.com",
"name": "John Doe"
}
response = requests.put(url, headers=headers, json=data)
print(response.text)
Remove Users
/store/{code}/remove/userRemove users from a store. This endpoint enables:
- Removing user associations
- Managing access control
- Updating store personnel
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| users | array | Yes | Array of users to remove |
users array items:
| Parameter | Type | Required | Description |
|---|---|---|---|
| countryCode | string | Yes | Country code with + prefix (e.g., "+54") |
| phone | string | Yes | Phone number without country code |
Request Body Example
{
"users": [
{
"countryCode": "+54",
"phone": "1123456789"
},
{
"countryCode": "+54",
"phone": "1198765432"
}
]
}
Response Codes
| Code | Description |
|---|---|
| 200 | Successful operation |
| 404 | Store not found |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
users: [
{ countryCode: "+54", phone: "1123456789" },
{ countryCode: "+54", phone: "1198765432" },
],
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/remove/user",
{
method: "PUT",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/remove/user"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"users": [
{"countryCode": "+54", "phone": "1123456789"},
{"countryCode": "+54", "phone": "1198765432"}
]
}
response = requests.put(url, headers=headers, json=data)
print(response.text)
Manage Store Credit
/store/{code}/creditUpdate store credit information. This endpoint allows:
- Setting credit limits
- Managing credit availability
- Updating payment terms
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| creditLimit | number | Yes | New credit limit for the store |
Request Body Example
{
"creditLimit": 5000
}
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
creditLimit: 5000,
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/credit",
{
method: "POST",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/credit"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"creditLimit": 5000
}
response = requests.post(url, headers=headers, json=data)
print(response.text)
Payment Status Management
Set as Defaulter
/store/{code}/debtorMark a store as a defaulter. When a store is marked as a defaulter:
- New orders are blocked
- Credit access is restricted
- Payment status is updated
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/debtor",
{
method: "POST",
headers: headers,
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/debtor"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
response = requests.post(url, headers=headers)
print(response.text)
Set as Late Payer
/store/{code}/latepayerMark a store as a late payer. This status means:
- Store can place new orders
- Credit access is restricted
- Payment status is monitored
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Store internal code (matches ERP) |
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/latepayer",
{
method: "POST",
headers: headers,
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/store/1234/latepayer"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY'
}
response = requests.post(url, headers=headers)
print(response.text)
Batch Operations
Assign Stores to Delivery Configurations
/batch/delivery-config/storesAdds or removes stores from delivery configurations asynchronously. Each operation identifies the delivery configuration with groupInternalCode and the store with storeInternalCode.
{
"add": {
"stores": [
{
"groupInternalCode": "2345",
"storeInternalCode": "124f"
}
]
},
"remove": {
"stores": []
}
}
At least one item must be present across add.stores and remove.stores. Empty arrays are accepted for the side that has no work. The endpoint returns 202 Accepted with separate batch IDs:
{
"code": 202,
"batchIds": {
"add": ["550e8400-e29b-41d4-a716-446655440000"],
"remove": []
},
"message": "Operation in processing"
}
For POST /store, PUT /store/{code}, and PUT /store, deliveryConfigCode is optional:
- If omitted, Nilo leaves the current delivery configuration assignment unchanged.
- If a valid code is provided, Nilo assigns or reassigns the store after validating that the configuration belongs to the authenticated supplier.
- Explicit
nullis invalid and does not remove an assignment. - Use this batch endpoint's
removeoperation to unassign a store.
Required permission: supplier/grouper.bulkwrite.
Change Store Status in Batch
/batch/store/statusEnables or disables multiple stores asynchronously. Each item requires code and enabled. The response returns 202 Accepted with batchIds, which can be followed through the Batch Operations API.
{
"items": [
{ "code": "STORE-001", "enabled": true },
{ "code": "STORE-002", "enabled": false }
]
}
Required permission: supplier/store.bulkwrite.
Update Store Settings
/batch/store/settingUpdate settings for multiple stores simultaneously. This endpoint is useful for:
- Bulk configuration updates
- Standardizing store settings
- Efficient store management
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| stores | array | Yes | Array of store settings to update |
Request Body Example for Batch Store Settings
{
"stores": [
{
"storeCode": "1234",
"settings": {
"credit": 5000,
"debtor": false,
"latePayer": false,
"allowPartialDelivery": true,
"minimumOrderAmount": 1000
}
},
{
"storeCode": "5678",
"settings": {
"credit": 10000,
"debtor": true,
"latePayer": true,
"allowPartialDelivery": false,
"minimumOrderAmount": 2000
}
}
]
}
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
stores: [
{
storeCode: "1234",
settings: {
credit: 5000,
debtor: false,
latePayer: false,
allowPartialDelivery: true,
minimumOrderAmount: 1000,
},
},
{
storeCode: "5678",
settings: {
credit: 10000,
debtor: true,
latePayer: true,
allowPartialDelivery: false,
minimumOrderAmount: 2000,
},
},
],
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/batch/store/setting",
{
method: "POST",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/batch/store/setting"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"stores": [
{
"storeCode": "1234",
"settings": {
"credit": 5000,
"debtor": False,
"latePayer": False,
"allowPartialDelivery": True,
"minimumOrderAmount": 1000
}
},
{
"storeCode": "5678",
"settings": {
"credit": 10000,
"debtor": True,
"latePayer": True,
"allowPartialDelivery": False,
"minimumOrderAmount": 2000
}
}
]
}
response = requests.post(url, headers=headers, json=data)
print(response.text)
Batch Store Updates
/batch/storePerform updates on multiple stores simultaneously. This endpoint supports:
- Creating multiple stores
- Updating existing stores
- Upserting store data
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| create | array | No | Array of stores to create |
| update | array | No | Array of stores to update |
| upsert | array | No | Array of stores to upsert |
| remove | array | No | Array of store codes to remove |
Request Body Example for Batch Store
{
"create": [
{
"ownerName": "Owner name",
"ownerIdentifier": "Owner identifier",
"internalCode": "1234",
"addresses": [
{
"internalCode": "1234",
"addressLine": "25 de mayo 1200, Buenos aires, Argentina",
"apartmentNumber": "2",
"zipCode": "2400"
}
],
"latitude": "-34.545278°",
"longitude": "-58.449722",
"addressFormat": "Av. Pres. Figueroa Alcorta 7597, C1428 Buenos Aires",
"legalName": "legal name",
"legalId": "legal id",
"supportContactEmail": "string",
"supportContactPhone": "string",
"promotionGrouperCode": "1234",
"stockGrouperCode": "6789",
"pricelistCode": "1222",
"routeCode": "1234",
"settings": {
"dropSize": {
"amount": 1000,
"currency": "USD"
}
}
}
],
"update": [
{
"ownerName": "Owner name updated",
"ownerIdentifier": "Owner identifier updated",
"internalCode": "5678",
"addresses": [
{
"internalCode": "5678",
"addressLine": "New address",
"apartmentNumber": "3",
"zipCode": "2401"
}
],
"latitude": "-34.545278°",
"longitude": "-58.449722",
"addressFormat": "New complete address",
"legalName": "new legal name",
"legalId": "new legal id",
"enabled": true,
"supportContactEmail": "new@email.com",
"supportContactPhone": "1234567890",
"promotionGrouperCode": "PROMO2",
"stockGrouperCode": "STOCK2",
"pricelistCode": "PRICE2",
"routeCode": "ROUTE2",
"latePayer": true,
"settings": {
"dropSize": {
"amount": 2000,
"currency": "USD"
}
}
}
],
"upsert": [
{
"internalCode": "9012",
"ownerName": "Owner name upsert",
"ownerIdentifier": "Owner identifier upsert",
"addresses": [
{
"internalCode": "9012",
"addressLine": "Upsert address",
"apartmentNumber": "4",
"zipCode": "2402"
}
],
"latitude": "-34.545278°",
"longitude": "-58.449722",
"addressFormat": "Upsert complete address",
"legalName": "upsert legal name",
"legalId": "upsert legal id",
"enabled": true,
"supportContactEmail": "upsert@email.com",
"supportContactPhone": "0987654321",
"promotionGrouperCode": "PROMO3",
"stockGrouperCode": "STOCK3",
"pricelistCode": "PRICE3",
"routeCode": "ROUTE3",
"latePayer": false,
"settings": {
"dropSize": {
"amount": 3000,
"currency": "USD"
}
}
}
],
"remove": ["9012"]
}
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
create: [
{
ownerName: "Owner 1",
internalCode: "1234",
addresses: [
{
addressLine: "Address 1",
zipCode: "2400",
},
],
legalName: "Legal Name 1",
},
{
ownerName: "Owner 2",
internalCode: "5678",
addresses: [
{
addressLine: "Address 2",
zipCode: "2401",
},
],
legalName: "Legal Name 2",
},
],
update: [
{
ownerName: "Updated Owner Name",
ownerIdentifier: "Updated Owner Identifier",
internalCode: "5678",
addresses: [
{
internalCode: "5678",
addressLine: "New Address",
apartmentNumber: "3",
zipCode: "2401",
},
],
latitude: "-34.545278°",
longitude: "-58.449722",
addressFormat: "New Complete Address",
legalName: "Updated Legal Name",
enabled: true,
supportContactEmail: "updated@email.com",
supportContactPhone: "1234567890",
promotionGrouperCode: "PROMO2",
stockGrouperCode: "STOCK2",
pricelistCode: "PRICE2",
routeCode: "ROUTE2",
latePayer: true,
settings: {
dropSize: {
amount: 2000,
currency: "USD",
},
},
},
],
upsert: [
{
internalCode: "9012",
ownerName: "Upsert Owner Name",
ownerIdentifier: "Upsert Owner Identifier",
addresses: [
{
internalCode: "9012",
addressLine: "Upsert Address",
apartmentNumber: "4",
zipCode: "2402",
},
],
latitude: "-34.545278°",
longitude: "-58.449722",
addressFormat: "Upsert Complete Address",
legalName: "Upsert Legal Name",
legalId: "Upsert Legal ID",
enabled: true,
supportContactEmail: "upsert@email.com",
supportContactPhone: "0987654321",
promotionGrouperCode: "PROMO3",
stockGrouperCode: "STOCK3",
pricelistCode: "PRICE3",
routeCode: "ROUTE3",
latePayer: false,
settings: {
dropSize: {
amount: 3000,
currency: "USD",
},
},
},
],
remove: ["9012"],
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/batch/store",
{
method: "POST",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/batch/store"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"create": [
{
"ownerName": "Owner 1",
"internalCode": "1234",
"addresses": [
{
"addressLine": "Address 1",
"zipCode": "2400"
}
],
"legalName": "Legal Name 1"
},
{
"ownerName": "Owner 2",
"internalCode": "5678",
"addresses": [
{
"addressLine": "Address 2",
"zipCode": "2401"
}
],
"legalName": "Legal Name 2"
}
],
"update": [
{
"ownerName": "Updated Owner Name",
"ownerIdentifier": "Updated Owner Identifier",
"internalCode": "5678",
"addresses": [
{
"internalCode": "5678",
"addressLine": "New Address",
"apartmentNumber": "3",
"zipCode": "2401"
}
],
"latitude": "-34.545278°",
"longitude": "-58.449722",
"addressFormat": "New Complete Address",
"legalName": "Updated Legal Name",
"enabled": True,
"supportContactEmail": "updated@email.com",
"supportContactPhone": "1234567890",
"promotionGrouperCode": "PROMO2",
"stockGrouperCode": "STOCK2",
"pricelistCode": "PRICE2",
"routeCode": "ROUTE2",
"latePayer": True,
"settings": {
"dropSize": {
"amount": 2000,
"currency": "USD"
}
}
}
],
"upsert": [
{
"internalCode": "9012",
"ownerName": "Upsert Owner Name",
"ownerIdentifier": "Upsert Owner Identifier",
"addresses": [
{
"internalCode": "9012",
"addressLine": "Upsert Address",
"apartmentNumber": "4",
"zipCode": "2402"
}
],
"latitude": "-34.545278°",
"longitude": "-58.449722",
"addressFormat": "Upsert Complete Address",
"legalName": "Upsert Legal Name",
"legalId": "Upsert Legal ID",
"enabled": True,
"supportContactEmail": "upsert@email.com",
"supportContactPhone": "0987654321",
"promotionGrouperCode": "PROMO3",
"stockGrouperCode": "STOCK3",
"pricelistCode": "PRICE3",
"routeCode": "ROUTE3",
"latePayer": False,
"settings": {
"dropSize": {
"amount": 3000,
"currency": "USD"
}
}
}
],
"remove": ["9012"]
}
response = requests.post(url, headers=headers, json=data)
print(response.text)
Response Types
Success Response
{
"code": 200,
"message": "Operation successful",
"data": {
"ownerName": "Owner name",
"internalCode": "1234",
"addresses": [
{
"addressLine": "25 de mayo 1200, Buenos aires, Argentina",
"apartmentNumber": "2",
"zipCode": "2400"
}
],
"enabled": true
}
}
Error Response Examples
Store Not Found
{
"code": 404,
"message": "Store not found"
}
Validation Error
{
"code": 400,
"message": "Invalid store data",
"errors": [
{
"field": "internalCode",
"message": "Internal code is required"
}
]
}
Best Practices
-
Store Management
- Use consistent naming conventions
- Maintain accurate address information
- Implement proper status management
- Keep store information up to date
-
User Management
- Validate user information
- Maintain user access records
- Document user changes
- Implement user removal procedures
-
Credit Management
- Monitor credit limits
- Track payment history
- Document status changes
- Implement credit checks
-
Performance Optimization
- Use batch operations for multiple updates
- Implement caching strategies
- Monitor API usage
- Optimize data synchronization
Common Use Cases
-
Initial Store Setup
- Create store profile
- Configure user access
- Set up credit limits
- Configure group associations
-
Store Maintenance
- Update store information
- Manage user access
- Monitor credit status
- Adjust store settings
-
Bulk Operations
- Import multiple stores
- Update store settings
- Modify group associations
- Sync store data
-
Credit Management
- Monitor payment status
- Update credit limits
- Handle defaulters
- Process credit changes
Implementation Guidelines
-
Store Creation
- Validate required fields
- Check for duplicate codes
- Process address data
- Set up initial configurations
-
User Management
- Validate user credentials
- Handle user permissions
- Manage user associations
- Track user activities
-
Credit Handling
- Implement credit checks
- Process payment status
- Handle credit updates
- Monitor credit usage
-
Batch Processing
- Validate batch data
- Handle partial failures
- Implement rollback
- Report batch results
Security
All API endpoints require two types of authentication:
- API Key in header:
x-api-key - Authorization token in header:
Authorization
Required Permissions
For store management endpoints, the following permissions are required:
- For read operations:
supplier/store.read - For write operations:
supplier/store.write - For batch operations:
supplier/store.bulkwrite - For credit operations:
supplier/credit.write
Error Codes
When an operation fails, the API returns a structured error response:
{
"code": 404,
"message": "STORE_NOT_FOUND",
"object": {
"statusCode": 404,
"code": "STORE_NOT_FOUND",
"message": "Store not found",
"entity": "store",
"entityCode": "STORE-001",
"timestamp": "2026-05-18T15:16:47.000Z"
}
}
The object field provides additional context about the error:
| Field | Description |
|---|---|
statusCode | HTTP status code |
code | Error code (same as top-level message) |
message | Human-readable error description |
entity | Entity type that caused the error |
entityCode | The internalCode of the entity involved |
timestamp | When the error occurred (ISO 8601) |
404 — Not Found
| Error Code | Description |
|---|---|
STORE_NOT_FOUND | The store does not exist for the given supplier |
STORE_INTERNAL_CODE_NOT_EXIST | The provided internal code does not match any existing store |
ROUTE_CODE_NOT_EXIST | The specified commercial route code does not exist |
STORE_CURRENCY_NOT_EXIST | The specified currency is not configured for this store |
ADDRESS_NOT_EXIST | The specified address does not exist for this store |
USER_NOT_FOUND | The user (email or phone) was not found in the system |
SUPPLIER_RELATION_NOT_FOUND | No relationship exists between the supplier and this store |
CHANNEL_NOT_FOUND | The specified channel does not exist |
409 — Conflict
| Error Code | Description |
|---|---|
STORE_ALREADY_EXIST | A store with the same name already exists |
STORE_INTERNAL_CODE_ALREADY_EXIST | A store with the same internal code already exists |
ADDRESS_ALREADY_EXIST | The specified address already exists for this store |
USER_ALREADY_EXIST | The username is already taken by another user |
USER_ALREADY_EXIST_IN_SFA | The user is already associated to a sales representative |
400 — Bad Request
| Error Code | Description |
|---|---|
ADDRESSES_REQUIRED | At least one address is required when creating a store |
INVALID_PAGE | The page parameter is invalid |
INVALID_PAGE_SIZE | The page size parameter is invalid |
INVALID_COUNTRY_CODE | The provided country code format is invalid |
422 — Business Rule Violation
| Error Code | Description |
|---|---|
STORE_NOT_TRANSACTIONAL | The store is not enabled for transactions |
STORE_NOT_BELONGS_TO_USER | The store does not belong to the specified user |
MAX_STORES_PER_USER_EXCEEDED | The user has exceeded the maximum number of stores allowed |
Error Handling
-
Input Validation
- Validate store codes
- Verify address data
- Check user information
- Validate credit data
-
Error Responses
- Use appropriate HTTP codes
- Provide clear messages
- Include field-level errors
- Add error tracking
-
Recovery Procedures
- Handle network failures
- Implement retries
- Maintain data consistency
- Log error details
-
Monitoring
- Track error rates
- Monitor API performance
- Alert on critical errors
- Analyze error patterns
Batch Add Users to Stores
/batch/store/add/userThis endpoint allows you to add users to multiple stores at once. Each item must provide either an email, or a country code and phone number to identify the user.
Use this endpoint when you need to:
- Onboard multiple store users simultaneously
- Assign users to stores in bulk from your CRM
- Synchronize store-user relationships from your ERP system
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| add | array | Yes | Array of user-store assignment objects |
| add[].storeInternalCode | string | Yes | Store internal code where the user will be added |
| add[].email | string | No | User email (required if countryCode/phone not provided) |
| add[].countryCode | string | No | Country code (required if email not provided) |
| add[].phone | string | No | Phone number (required if email not provided) |
| add[].name | string | No | User display name |
Each item must include either email OR countryCode + phone. If the user doesn't exist in the system, they will be invited automatically.
Request Body Example
{
"add": [
{
"storeInternalCode": "STORE-001",
"email": "owner@store1.com",
"name": "Store Owner 1"
},
{
"storeInternalCode": "STORE-002",
"countryCode": "+54",
"phone": "1155667788",
"name": "Store Owner 2"
},
{
"storeInternalCode": "STORE-003",
"email": "manager@store3.com"
}
]
}
Response Codes
| Code | Description |
|---|---|
| 202 | Request accepted, processing initiated |
| 404 | Store not found |
Response Example
{
"code": 202,
"batchIds": {},
"message": "Operation in processing"
}
Example Usage
- Javascript
- Python
const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const data = {
add: [
{
storeInternalCode: "STORE-001",
email: "owner@store1.com",
name: "Store Owner 1",
},
{
storeInternalCode: "STORE-002",
countryCode: "+54",
phone: "1155667788",
name: "Store Owner 2",
},
],
};
fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/batch/store/add/user",
{
method: "POST",
headers: headers,
body: JSON.stringify(data),
},
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
import requests
url = "https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/batch/store/add/user"
headers = {
'Authorization': 'YOUR_AUTH_TOKEN',
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {
"add": [
{
"storeInternalCode": "STORE-001",
"email": "owner@store1.com",
"name": "Store Owner 1"
},
{
"storeInternalCode": "STORE-002",
"countryCode": "+54",
"phone": "1155667788",
"name": "Store Owner 2"
}
]
}
response = requests.post(url, headers=headers, json=data)
print(response.text)