Cart
Create the cart, add items, apply a code, and choose shipping with the Storefront API.
Andrea buys two T-shirts from Miraflores, in Lima. She uses the code
BIENVENIDA10 and asks for delivery on Thursday at 10:00. This guide builds
that cart up to checkout.
Requirements
- The store slug or a configured domain, in
x-Store-Domain. You don't need an access token. - A published variant and active shipping methods. See Headless store and Zones and rates.
Create the cart
POST /
creates a cart in the store's currency. Keep token: it identifies the cart in
every call.
curl -X POST https://storefront.ecomiq.pe/v1/carts \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{ "email": "andrea.ramos@example.com" }'{
"token": "kP3vX9qL2mT7wR4nB8sD1A",
"cartNumber": "C-04325176",
"currencyCode": "PEN",
"status": "inProgress"
}The examples below reuse API, headers, and cart.
emailis optional. You can also send it with the buyer's details.- If the customer is signed in, create the cart with their
X-Customer-Session. The cart then uses their prices and their reserved codes. See Customer accounts.
Read the cart
GET /
returns the full cart. Use it when the page reloads.
curl https://storefront.ecomiq.pe/v1/carts/<cart-token> \
-H "x-Store-Domain: mi-tienda"- A cart with no activity moves to
abandoned. Reading or changing it reopens it. - A
completedorcancelledcart no longer accepts changes. Create a new one.
Add items
POST /
adds a variant. This and every other operation return the recalculated cart.
curl -X POST https://storefront.ecomiq.pe/v1/carts/<cart-token>/items \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{ "variantId": "7204558912004325377", "quantity": 2 }'{
"items": [
{
"id": "7204558912004325450",
"title": "Polo de algodón",
"quantity": 2,
"unitPrice": 79
}
],
"totals": {
"subtotal": 158,
"discountTotal": 0,
"shippingTotal": 0,
"total": 158
}
}- Adding the same variant again increases its line.
- Stock is checked against the variant's total quantity in the cart.
- Adding, changing, or removing an item that ships clears the shipping chosen for its group. Choose shipping last.
Change the quantity
PATCH /
sets a line's quantity. Use the item id, not the variant id. With 0, the
line is removed.
curl -X PATCH https://storefront.ecomiq.pe/v1/carts/<cart-token>/items/7204558912004325450 \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{ "quantity": 3 }'Remove an item
DELETE /
removes the line.
curl -X DELETE https://storefront.ecomiq.pe/v1/carts/<cart-token>/items/7204558912004325450 \
-H "x-Store-Domain: mi-tienda"Apply a code
POST /
applies a coupon. Lowercase is fine: the code is stored in uppercase.
curl -X POST https://storefront.ecomiq.pe/v1/carts/<cart-token>/promotion-codes \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{ "code": "bienvenida10" }'The code shows up in promotionCodes. 10% of S/ 158 brings
totals.discountTotal to -15.8 and totals.total to 142.2.
- If the cart doesn't meet the coupon's conditions, the code is still saved, but it won't discount anything until the cart meets them.
Remove a code
DELETE /
removes the code and recalculates the total.
curl -X DELETE https://storefront.ecomiq.pe/v1/carts/<cart-token>/promotion-codes/BIENVENIDA10 \
-H "x-Store-Domain: mi-tienda"Add the buyer's details
PATCH /
saves the buyer's contact details and ID document.
curl -X PATCH https://storefront.ecomiq.pe/v1/carts/<cart-token>/buyer \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{
"email": "andrea.ramos@example.com", "phone": "+51987654321",
"firstName": "Andrea", "lastName": "Ramos",
"identificationType": "DNI", "identificationNumber": "45678912"
}'- Send every field on each call: the ones you leave out are cleared. Only
invoiceTypeis kept when you omit it. - For an invoice (factura), send
invoiceType: "invoice", the RUC inentityTaxId, and the company name inentityName.
Build the address form
The department, province, and district pickers come from the ubigeo catalog.
Request each level with the code of the one above:
departments,
provinces,
and districts.
curl https://storefront.ecomiq.pe/v1/geo/departments -H "x-Store-Domain: mi-tienda"
curl "https://storefront.ecomiq.pe/v1/geo/provinces?departmentCode=15" -H "x-Store-Domain: mi-tienda"
curl "https://storefront.ecomiq.pe/v1/geo/districts?provinceCode=1501" -H "x-Store-Domain: mi-tienda"Each area has an id, a code, and a name, for example 150122 and
Miraflores. In Peru, code is the INEI ubigeo and source is inei.
- Without
countryCode, it usesPE. Each list is sorted by name and returns up to 200 areas. - To prefill a saved address, resolve its ubigeo with
GET /. Sendv1/ geo/ resolve countryCode=PE,source=inei, and the ubigeo incode.
Save the address
PATCH /
saves the shipping address. If you don't send billingAddress, checkout uses
the shipping address.
curl -X PATCH https://storefront.ecomiq.pe/v1/carts/<cart-token>/addresses \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{
"shippingAddress": {
"name": "Andrea Ramos", "phone": "+51987654321",
"address1": "Av. Larco 1234", "address2": "Dpto. 501",
"department": "Lima", "departmentCode": "15",
"province": "Lima", "provinceCode": "1501",
"district": "Miraflores", "districtCode": "150122",
"city": "Lima", "postalCode": "15074", "countryCode": "PE"
}
}'- In Peru,
department,province, anddistrictare required, along withname,address1,city, andcountryCode. - If you send codes, send all three. Each one starts with the previous one:
15,1501,150122. Shipping quotes and slots use those codes. - Each
PATCHreplaces the address: without codes, its previous codes are cleared. - If shipping is already chosen, changing the address quotes it again. If it no longer applies or its price changed, it is removed.
List shipping options
GET /
quotes shipping for the cart's address. It groups items by seller and shipping
profile.
curl https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-options \
-H "x-Store-Domain: mi-tienda"{
"groups": [
{
"sellerId": "7204558912004325305",
"shippingProfileId": "7204558912004329819",
"rates": [
{
"shippingMethodId": "7204558912004325207",
"rateId": "7204558912004322088",
"name": "Delivery Lima",
"type": "localDelivery",
"target": "location",
"targetId": "7204558912004325563",
"price": 10,
"serviceCode": null
}
]
}
]
}- Choose one rate per group.
- If no item needs shipping,
groupsis empty. - Without an address, you can quote with
?postalCode=15074.
Check delivery slots
GET /
returns the slots for one day. Send the rate's target, targetId, and
rateId, and the day in date.
curl -G https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-methods/7204558912004325207/slots \
-H "x-Store-Domain: mi-tienda" \
-d target=location -d targetId=7204558912004325563 \
-d rateId=7204558912004322088 -d date=2026-10-08{
"date": "2026-10-08",
"capacity": 30,
"scheduledCount": 12,
"slots": ["10:00:00", "12:00:00"]
}- Only
pickupandlocalDeliverymethods have slots. - Times are in the store's local time.
capacityis the day's limit andscheduledCountis what is already booked. - If the day is closed or full,
slotsis empty. Try another day.
Choose shipping
PUT /
saves the chosen rate. Copy shippingMethodId, rateId, target, targetId,
and serviceCode from the rate, and sellerId and shippingProfileId from the
group. In the code, shippingOptions is the shipping options response.
curl -X PUT https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-method \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{
"shippingProfileId": "7204558912004329819",
"shippingMethodId": "7204558912004325207", "rateId": "7204558912004322088",
"target": "location", "targetId": "7204558912004325563",
"scheduledDate": "2026-10-08", "scheduledTime": "10:00:00"
}'The response has the shipping in shippingMethods. totals.shippingTotal is
10 and totals.total is 152.2.
- With
target: "automatic",targetIdisnull. - Send
scheduledDateandscheduledTimetogether or not at all. Use a time fromslots, with no time zone.
Remove shipping
DELETE /
removes the chosen shipping from every group. With sellerId or
shippingProfileId, only from that group.
curl -X DELETE "https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-method?shippingProfileId=7204558912004329819" \
-H "x-Store-Domain: mi-tienda"Go to checkout
Checkout needs items, an email, a shipping address, and shipping for every group with items that ship. Continue in Checkout and payment.
Checkout recalculates the discounts. If a code stopped applying, it returns
409 with Promotions.CodeNoLongerApplies; if an automatic promotion ran out,
with Promotions.NoLongerApplies.
Errors
Read code in the error body.
code | Status | What to do |
|---|---|---|
Carts.NotFound | 404 | The token doesn't exist in the store. Create a new cart. |
Carts.NotActive | 400 | The cart was already bought or cancelled. Create a new one. |
Checkout.InProgress | 409 | A checkout is running. Wait and read the cart. |
Common.Validation | 400 | A field is missing or malformed. Check errors. |
Catalog.VariantNotFound | 404 | The variant doesn't exist or isn't published in the store. |
Catalog.InsufficientStock | 400 | Not enough stock for that quantity. Lower it. |
Promotions.CodeNotFound | 400 | The code doesn't exist. |
Promotions.CodeLimitReached | 400 | The coupon ran out. |
Promotions.CodeInactive | 400 | The coupon is inactive, hasn't started, or expired. |
ShippingMethods.RateNotFound | 400 | The rate no longer applies. List the options again. |
ShippingMethods.GroupRequired | 400 | Send the group's sellerId and shippingProfileId. |
ShippingMethods.InvalidSchedule | 400 | That slot isn't available. Check the slots again. |
With a token that doesn't exist, the other operations return 404 with no
body. More coupon codes in
Promotions and coupons.
Next steps
Last updated: