Schemas
OrderCreatedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderUpdatedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderConfirmedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderUnreachableEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderPreparingEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderReadyEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderCancelledEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderLineReturnedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginOrderDeletedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentHandedOffEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentOutForDeliveryEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentDeliveryFailedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentDeliveredEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentReturnStartedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentReturnedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentCancelledEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginShipmentVoidedEvent
idsequencetypeversionorderIdoccurredAtrecordedAtoriginStoreConfig
idStore UUID
namedomainlogolangThe store's primary language
localeThe language this config is served in: ?locale= when the store publishes it, else lang
The published languages, primary first
The requesting theme's text edits for the published languages; empty without theme
The merchant's values for the requesting theme's settings, as saved, by setting key; empty without theme. The theme reads them against its declaration (resolveThemeSettings in @wocart/theme), which falls back to its defaults.
currencycurrencySymbolmetaTitlemetaDescriptionogImageHow the storefront fetches and resizes every image key (ADR 0021)
reviewsEnabledWhen false, the reviews section is hidden on the storefront
cartEnabledWhen true the storefront renders the shopping cart alongside the direct order form. False (the default) leaves the storefront exactly as it was.
freeShippingThresholdOrder subtotal (DZD) at or above which delivery is free. null = no threshold. Exposed so the storefront can show the promise and how far the shopper is from it.
otpEnabledWhen true, storefront checkout requires WhatsApp phone verification (dzverify). True only when a store_otp_config row exists AND is enabled.
turnstileEnabledWhen true, storefront checkout requires a Cloudflare Turnstile token that the server verifies against siteverify. True only when a store_turnstile_config row exists AND is enabled.
turnstileSiteKeyPublic Turnstile widget site key for rendering the checkout widget. null when Turnstile is disabled. The siteverify secret key is never exposed.
Published pages that opt into the footer, titled in the store's own language (stores.lang), ordered for display. The checkout consent line resolves Terms/Refund from here by kind, never by a hardcoded slug — a merchant may rename any page's slug freely.
How a shopper reaches the store, from its legal profile (Settings → Store Pages); each null until the merchant writes it. RC, NIF and the legal name are never exposed here, only inside the documents themselves. The WhatsApp number is whatsapp.href.
The merchant's order-form configuration, already resolved: a store that never customised it gets the defaults, which describe the form exactly as it behaved before this feature existed. The theme renders this and holds no form rules of its own — cod-server enforces every one of them on POST /store/orders, so a hidden field posted from an edge-cached page is dropped and a required one refuses the order. The raw stored column is never exposed.
whatsappThe WhatsApp contact widget, already resolved — or null, which is what a store gets when the widget is off, has no number, or holds a number that no longer normalises. A theme's entire gate is this being non-null and the current surface being on in surfaces. The raw stored column is never exposed.
MediaImage
keyA Media Key: the image's identity in the store's media. Never a URL.
urlWhere browsers fetch it, from the store's Media Delivery
widthPixels, when known
heightPixels, when known
StorefrontLanguage
codeBCP 47 language tag
nativeNameThe language's name in itself
directionMediaDelivery
kindHow images are resized: imagekit (?tr=), cloudflare (/cdn-cgi/image/), or direct (not resized)
originA key's URL is this origin, a slash and the key
StoreWhatsAppWidget
hrefThe wa.me link, ready to use. Digits only — a '+' in the path makes WhatsApp answer with an invalid-number page.
agentNameWho the shopper is talking to. Null means the theme uses the store name.
captionThe line under the name, e.g. how fast the merchant answers.
avatarUrlThe avatar's URL, from the store's Media Delivery. Null means the theme falls back to the store logo.
welcomeMessageThe bubble in the panel, before the shopper opens WhatsApp.
launcherLabelText on the floating launcher.
ctaLabelThe panel's button that opens WhatsApp.
prefillGeneralThe message WhatsApp opens with on a page that has no product. May contain {url}, {order} and {store}, which the theme resolves from the page.
prefillProductSame, for a product or landing page. May also contain {product}.
thankYouButtonLabelThe WhatsApp button on the order confirmation.
prefillThankYouThe message that button opens WhatsApp with. May contain {order}.
accentBrand green, or the store's own primary colour.
positionWhich physical side the launcher sits on, in both LTR and RTL.
attentionOne attention pulse per session, suppressed under prefers-reduced-motion.
Which kinds of page the launcher appears on. checkout and landing are off by default: both already carry their own sticky order CTA, and a second floating control competing for the same thumb costs the order.
StorefrontMenu
handle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the menu
titleOnly items a shopper can follow: one whose destination is deleted or not public is left out, with its children
StorefrontMenuItem
labelIn the requested language when the store translated it
hrefA path of the store without a language prefix (/products/robe), or the URL the merchant entered
typeErrorResponse
errorcodecategoryAdditional context about the error (optional)
StorefrontCollection
handle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the collection
titleIn the requested language when the store translated it
descriptionproductCountHow many products a shopper sees in it
imageThe first photo of the first product it lists, in the merchant's order, that has one; null when none does
StoreProductImage
keyA Media Key: the image's identity in the store's media. Never a URL.
urlWhere browsers fetch it, from the store's Media Delivery
widthPixels, when known
heightPixels, when known
idaltTextAlt text for accessibility
positionDisplay order (1 = first)
StoreProductList
idnamedescriptiondescriptionFormatHow description is stored. text renders as literal text (legacy rows and products created without a format); html is sanitised rich text — render only via a strict HTML sink.
descriptionPlainTag-free rendering of description for and JSON-LD. Identical to description for text rows; null when description is null.
handlecurrencypricecompareAtPricetypehasVariantsskuinventorytrackInventorylowStockThresholdThreshold for low stock warnings
categoryIdmetaTitleThe title search engines and shared links show, in the requested language when translated; null: use the product's name.
metaDescriptionThe description search engines and shared links show, in the requested language when translated; null: use descriptionPlain, shortened.
Parsed variant option axes. null for simple products.
tagsParsed tag list
coverImageThe first photo of the first product it lists, in the merchant's order, that has one; null when none does
reviewStatsAggregate review stats (approved reviews only). null if no approved reviews exist for this product.
StoreProductDetail
idnamedescriptiondescriptionFormatHow description is stored. text renders as literal text (legacy rows and products created without a format); html is sanitised rich text — render only via a strict HTML sink.
descriptionPlainTag-free rendering of description for and JSON-LD. Identical to description for text rows; null when description is null.
handlecurrencypricecompareAtPricetypehasVariantsskuinventorytrackInventorylowStockThresholdThreshold for low stock warnings
categoryIdmetaTitleThe title search engines and shared links show, in the requested language when translated; null: use the product's name.
metaDescriptionThe description search engines and shared links show, in the requested language when translated; null: use descriptionPlain, shortened.
Parsed variant option axes. null for simple products.
tagsParsed tag list
categoryJoined category, or null if no category assigned.
Active variants ordered by position. Empty array for simple products.
imagesAll product images ordered by position.
reviewStatsAggregate review stats (approved reviews only). null if no approved reviews exist for this product.
quantityPricingThe product's live quantity pricing — price tiers by quantity — or null. A separate field from offers (whose kinds published SDKs validate): the highest tier the quantity reaches prices every unit at its per-unit price; the cart quote and the order charge exactly that.
Live Buy X Get Y and free-delivery offers for this product (quantity pricing is quantityPricing). Only includes offers where status=active and the current time is within the optional schedule window. The storefront uses this list to display offer banners and to show the free reward row in the order summary when the customer selects a matching variant and quantity.
StoreQuantityPricing
offerIdnameThe offer's name, in the requested language
triggerVariantIdWhen set, only this variant's units count and are priced by the tiers
In increasing quantity
StoreLandingPage
idslugnamestatusimageGapPixels between stacked images
metaTitlemetaDescriptionpublishedAtimagesThe image stack, ordered by position (1 = top)
productThe product in its full store-product shape — the landing page renders the same data the product page does, so the order form works unmodified. Null when the product is no longer publicly visible.
This page's own composition (its lp:<id> page document) for the requesting theme, written by Wocart Cloud's editor; null when it has none or no theme is named — the theme then renders its landing default.
Which Meta pixel THIS page loads and fires at, already resolved server-side: the page's own pixel when it has one in force, otherwise the store's. The browser never works this out for itself, so it cannot disagree with the Conversions API mirror.
PageDocument
versionsurfaceStorePublicTracking
pixelIdThe Meta Pixel to load, or null when no pixel should load at all. Public by definition — it appears in the page source. The Conversions API token is never included.
conversionEventWhich moment counts as a conversion here. Inert while pixelId is null.
StorePagePublic
idkindsluglocaleThe locale actually served — the store's own language, or the fallback locale when that translation doesn't exist (see legal/render.ts's resolution order).
titlebodyHtmlSanitised HTML. Render with set:html and never re-sanitise.
metaTitlemetaDescriptionStoreOrderTracking
pixelIdThe Meta pixel this order belongs to, or null when tracking is off.
eventThe browser event the thank-you page should fire, or null when none should — tracking is off, or the merchant's conversion fires further down the funnel from the server only.
ShopperOrderStatus
orderNumberplacedAtWhen the order was placed (ISO 8601)
stageWhere the order is, in the shopper's words: placed (not confirmed yet), confirmed, preparing, shipped, out_for_delivery, delivered, returned (refused at the door) or cancelled.
deliveryTypetotalWhat the shopper pays on delivery
trackingThe carrier's tracking number once the parcel is with it; null before, or with the store's own driver
UploadTicket
mediaIdComplete the upload with this id
keyA Media Key: the image's identity in the store's media. Never a URL.
expiresAtHow to send the file: form — POST multipart fields plus the file as fileField to url; put — PUT the bytes to url with exactly headers; relay — PUT the bytes to this server's url (a path) with headers.
ActivityLog
idactorIdactorNameactorRoleactionDot-notation action identifier. Valid values: order.created, order.status_changed, order.driver_assigned, order.dispatched, order.deleted, shipment.voided, shipment.released, customer.created, customer.updated, customer.deleted, customer_group.created, customer_group.updated, customer_group.deleted, customer_group.member_added, customer_group.member_removed, customer_tag.created, customer_tag.updated, customer_tag.deleted, customer_tag.assigned, customer_tag.unassigned, driver.created, driver.updated, driver.status_changed, driver.deleted, product.created, product.updated, product.status_changed, product.deleted, review.approved, review.rejected, review.deleted, user.created, user.updated, user.role_changed, user.scope_granted, user.scope_revoked, user.api_key_generated, user.api_key_revoked
entityTypeEntity category the action applies to. Valid values: order, customer, customer_group, customer_tag, driver, product, review, user
entityIdentityLabelHuman-readable label at the time of action (order number, customer name, etc.)
metadataJSON-encoded extra context. Shape varies by action: { from, to } for order.status_changed, { amount } for payments, { scope } for permission changes, { role } for role changes, { rating, orderNumber } for review actions
createdAtBusinessEvent
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more | |
| type = object · requires: id, sequence, type +8 more |
idsequencetypeversionorderIdoccurredAtrecordedAtoriginEventConsumer
idkindHow it is reached: webhook (an endpoint of the merchant's own) or meta_capi (Meta conversions)
nameenabledbuiltInKept by its App (Meta conversions, by the Meta App): it can be started and stopped, not edited or deleted
subscriptionThe Event Types it receives, each named exactly, by subject (order.*), or *
catalogueVersionThe catalogue version its Deliveries are written in
disabledReasonWhy it stopped receiving, while disabled: failing (every Attempt failed for 3 days), merchant, gone (its endpoint answered HTTP 410 Gone), bot_blocked (its Telegram chat blocked the bot), or not_connected (no Telegram chat connected yet)
failingSinceSince when every Attempt has failed; null once one succeeds
webhookA webhook Consumer's endpoint; null for any other kind
createdAtupdatedAtWebhookCreated
signingSecretThe Signing Secret, in full: shown this once. Verify Deliveries with it (Standard Webhooks)
SigningSecret
signingSecretThe Signing Secret, in full: shown this once. Verify Deliveries with it (Standard Webhooks)
previousSecretSignsUntilUntil when Deliveries are also signed with the secret this one replaces
WebhookTest
outcomeWhat a Delivery's Attempt would have come to
httpStatusdurationMsresponseThe start of what the endpoint answered
errorRedelivery
reopenedSettled Deliveries made due again
createdDeliveries made for events the Consumer never had one for
EventDelivery
idconsumerIdstatedue (on its way), delivered, skipped (declined on purpose) or dead (given up on)
attemptsAttempts since it was last made due; a retry or Replay starts them over
nextAttemptAtlastErrorcreatedAtsettledAtEventDeliveryDetail
idconsumerIdstatedue (on its way), delivered, skipped (declined on purpose) or dead (given up on)
attemptsAttempts since it was last made due; a retry or Replay starts them over
nextAttemptAtlastErrorcreatedAtsettledAtEvery Attempt, oldest first — those before a retry or Replay too
EventDeliveryAttempt
attemptattemptedAtdurationMsoutcomehttpStatusresponseExcerptThe first kilobyte of what the Consumer answered
errorOrderListItem
idorderNumbercustomerIdcustomerNamephonewilayaIdwilayaWilaya Arabic name, joined from reference table
communeIdcommuneCommune Arabic name, joined from reference table
cityaddresspriceProduct subtotal (excluding delivery fee)
deliveryFeecodAmountWhat the customer owes on delivery: price + deliveryFee
statusThe order's processing; its delivery is its shipment's (see stage)
orderTypedeliveryTypeWhat the customer asked for; the shipment may ship otherwise
stationCodedriverNameThe name of the store's driver delivering it, when its shipment is a driver's
noteslandingPageIdThe landing page the order was placed on, if any
createdAtupdatedAtarchivedAtWhen the finished order was archived: it is left out of the working lists and their counts, and still counts in sales and the customer's history. Null while not archived.
deliveryOfferIdThe offer that made delivery free (a free-shipping offer, or a quantity tier that includes it); null when none did
deliveryOfferNameThat offer's name when the order was placed — kept when the offer is renamed or deleted
couponIdThe coupon the order was placed with; null when none, or once the coupon is deleted
couponCodeThe code the order used, kept when the coupon is deleted
couponDiscountWhat the coupon took off; price is already net of it
localeThe language the order was placed in — the shopper's storefront language, the store's primary for a dashboard or agent order — and the one its customer messages are written in; null for an order placed before it was recorded
customerEmailEmail supplied at order time
customFieldsJsonCustom checkout fields snapshot JSON
hasReview1 if a customer review exists for this order, 0 otherwise. Included in list responses only (GET /api/orders).
lastUpdatedByUser ID of the last status-change actor. Included in list responses only (GET /api/orders).
shipmentIdThe order's shipment, or null before handoff. List responses only.
shipmentKindHanded to a carrier, or to the store's driver; null before handoff. List responses only.
carrierNameThe delivery company carrying it, for a carrier shipment. List responses only.
trackingNumberThe parcel's tracking number at the carrier. List responses only.
stageWhere the order stands overall — its processing, then its shipment's delivery. List responses only.
needsAttentionWhether the order's delivery needs the merchant. List responses only.
Order
idorderNumbercustomerIdcustomerNamephonewilayaIdwilayaWilaya Arabic name, joined from reference table
communeIdcommuneCommune Arabic name, joined from reference table
cityaddresspriceProduct subtotal (excluding delivery fee)
deliveryFeecodAmountWhat the customer owes on delivery: price + deliveryFee
statusThe order's processing; its delivery is its shipment's (see stage)
orderTypedeliveryTypeWhat the customer asked for; the shipment may ship otherwise
stationCodedriverNameThe name of the store's driver delivering it, when its shipment is a driver's
noteslandingPageIdThe landing page the order was placed on, if any
createdAtupdatedAtarchivedAtWhen the finished order was archived: it is left out of the working lists and their counts, and still counts in sales and the customer's history. Null while not archived.
deliveryOfferIdThe offer that made delivery free (a free-shipping offer, or a quantity tier that includes it); null when none did
deliveryOfferNameThat offer's name when the order was placed — kept when the offer is renamed or deleted
couponIdThe coupon the order was placed with; null when none, or once the coupon is deleted
couponCodeThe code the order used, kept when the coupon is deleted
couponDiscountWhat the coupon took off; price is already net of it
localeThe language the order was placed in — the shopper's storefront language, the store's primary for a dashboard or agent order — and the one its customer messages are written in; null for an order placed before it was recorded
customerEmailEmail supplied at order time
customFieldsJsonCustom checkout fields snapshot JSON
Order line items. Included in GET /api/orders/{id} (detail view only).
Full status change log. Included in GET /api/orders/{id} (detail view only).
shipmentThe order's delivery, with its history and the actions available now; null before handoff. Detail view only.
stageWhere the order stands overall — its processing, then its shipment's delivery.
needsAttentionThe merchant must act on the delivery: the carrier flagged it, the handoff outcome is unknown, or the carrier cancelled it
OrderProduct
idorderIdproductIdNull once the product was removed: the line keeps what was sold
productNamevariantIdNull for a product without variants, or once the variant was removed
variantLabelskuDenormalized SKU at time of order
quantitypricePerUnitlineTotalstatusPer-line fulfilment outcome — updated via PATCH /orders/{id}/products/{productLineId}/return
returnedQuantityUnits the customer refused at the door. Always 0 when status=fulfilled, = quantity when status=returned.
createdAtofferIdThe offer that shaped the line: the quantity-pricing offer that set its price, or the gift offer that gave it. Null at the catalog price.
offerNameThe offer's name when the order was placed — kept when the offer is renamed or deleted. Null without an offer.
rewardA gift, given by offerId at no charge
discountThe line's share of the order's coupon discount; lineTotal is already net of it
StatusHistoryItem
idorderIdstatustimestampWhen the status change happened
byUser ID who triggered the status change
byNameUser display name
ShipmentEvent
idsourcevocabularyWhose words the status is in (the carrier's field, or codflow)
providerStatusThe status exactly as reported
providerStatusLabelinterpretationmilestoneattentionanomalyreasonWhy, when the carrier says (a refusal, no answer…)
occurredAtrecordedAtactorIdOrderCreatedData
idNewly created order ID
orderNumberdeliveryFeeCalculated delivery fee (from shipping profile or admin override)
priceProduct subtotal (excluding delivery fee)
codAmountTotal amount to collect (price + deliveryFee)
customerIdcustomerNamephonewilayaIdcommuneIddeliveryTypeorderTypestatusInitial order status
OrderRemoval
idorderNumbershipmentNo shipment yet, one on its way, or one that ended (delivered, returned, cancelled)
deletableOnly an order never handed to delivery
archivableA finished order (cancelled, or its shipment ended) not archived yet
archivedAtlinesIts order lines, removed with it
restockUnitsUnits deleting it puts back in stock
reviewsIts reviews, removed with it
ReturnProductData
returnedQuantitystatusHandoffResult
orderIdorderNumberoutcomeaccepted: the carrier has the parcel, or the driver has the order · unknown: the carrier may or may not have it — resolve it, never re-send · refused: nothing was created; the order is unchanged
validationErrorCreated, but the carrier refused to validate it
messageShipment
idorderIdkindcompanyIdcarrierNameThe delivery company carrying it; null for the store's driver
driverIdhandoffStatesubmitting: the carrier is being called · accepted: the carrier has the parcel · unknown: the outcome must be resolved
carrierParcelIdtrackingNumberdeliveryTypestationCodecodAmountCash the courier collects (price + delivery fee)
driverFeeweightisFragileproviderStatusThe carrier's latest status, as reported
providerStatusLabelproviderStatusKindproviderStatusAtUTC ISO-8601, or null
validatedAtUTC ISO-8601, or null
outForDeliveryAtUTC ISO-8601, or null
deliveredAtUTC ISO-8601, or null
returnStartedAtUTC ISO-8601, or null
returnedAtUTC ISO-8601, or null
cancelledAtUTC ISO-8601, or null
deliveryAttemptsattentionSinceUTC ISO-8601, or null
lastSyncedAtUTC ISO-8601, or null
createdBycreatedAtupdatedAtactionsWhat can be done to this shipment now
BulkHandoffData
HandoffResolution
outcomemessageShipmentOperationResult
recordedEvents new to the shipment
duplicatesEvents it already had
reachedMilestones reached for the first time
anomaliesUser
idnameemailemailVerifiedimageAvatar image URL
rolestatuslanguageUI language preference for emails: "ar" | "en"
createdAtupdatedAtscopesPermission scopes for this user. Always ["*"] for admins. The apiKey field is never included in these responses — use POST /{id}/api-key/rotate for a one-time key reveal.
Customer
idnamephoneAlgerian mobile number starting with 05, 06, or 07
phone2Secondary phone number
emailEmail, lower-cased: typed by the merchant, or taken from the first order that brought one
wilayaIdOfficial wilaya number (1–58)
communeIdCommune UUID from reference table
wilayaWilaya Arabic name — denormalized display value, derived from wilayaId
communeCommune Arabic name — denormalized display value, derived from communeId
addresstotalOrdersDenormalized count, incremented on each order created
totalSpentcreatedAtlastOrderAtUp to 10 most recent full order records (same shape as the Orders API), newest first. Included only in GET /api/customers/{id}; not present in list responses.
CustomerOrderSummary
idorderNumberstatuspricecreatedAtwilayaIdcommuneIdwilayaWilaya Arabic name, joined from reference table
communeCommune Arabic name, joined from reference table
stageWhere the order stands overall — delivered, returned… (the same stage as GET /api/orders)
CustomerOrderStatus
idorderIdstatustimestampbyCustomerGroupMembership
idnamecolordescriptionmemberCountcreatedAtupdatedAtassignedAtWhen the customer was added to this group
CustomerTagMembership
idnamecolorassignmentCountcreatedAtupdatedAtassignedAtWhen the tag was assigned to this customer
CustomerGroup
idnamedescriptioncolormemberCountDenormalized count, kept in sync on add/remove member
createdAtupdatedAtIncluded only when ?members=true is passed to GET /api/customer-groups/{id}.
CustomerGroupMember
idnamephonewilayatotalOrderstotalSpentassignedAtCustomerTag
idnamecolorassignmentCountDenormalized count, kept in sync on assign/unassign
createdAtupdatedAtIncluded only when ?customers=true is passed to GET /api/customer-tags/{id}.
CustomerTagCustomer
idnamephonewilayatotalOrderstotalSpentassignedAtDriver
idfirstNamelastNamephoneAlgerian mobile number starting with 05, 06, or 07
phone2Optional secondary phone
vehicleTypeType of vehicle; null if unknown
statustotalDeliveredCumulative deliveries completed (incremented on status → delivered)
totalEarningsCumulative delivery fees earned (incremented on status → delivered)
pendingCashCOD cash collected by driver but not yet remitted to the business
totalPaidTotal COD cash remitted to the business
notesInternal notes about the driver (not visible to customers)
createdAtupdatedAtcompensationWilayaCountNumber of wilayas with a configured per-delivery fee for this driver
The 10 most recent orders given to this driver, newest first. Detail, create and update responses only.
openShipmentCountOrders the driver still has out (not delivered, returned or cancelled).
DriverCompensationRow
wilayaIdwilayaNamewilayaNameArfeePerDeliveryDZD per delivery; null when not configured.
DeliveryCompany
idnamenameArcodewebsiteactiveapiEndpointisConnectedTrue when API credentials are stored. Credentials themselves are never returned.
supportsHomeDeliverysupportsStopDeskautoValidateWhen true, the server calls validateShipment immediately after createShipment on dispatch. The order is locked at the carrier (no edits/deletes). When false, the order stays editable and the team must manually confirm it. If omitted/null, a provider-specific default is used.
notesproviderThe carrier adapter serving this company; null = it cannot take parcels.
The adapter's settings; secrets masked (•••• + last 4).
webhookSecretSetTrue when the webhook signing secret is stored. The secret itself is never returned.
capabilitiesWhat its carrier can do; null when it has no provider
webhookEndpointIdcreatedAtupdatedAtCarrierCapabilities
homeDeliverystopDeskseparateValidationA created parcel waits for a separate validation before the carrier handles it
bulkCreateMost parcels one bulk handoff sends at once; 0 = one at a time
Parcel fields the carrier takes at creation
The carrier's own ceilings, checked before calling it
updatecancelhistoryIts status history can be read (sync)
historyBatchfindByReferenceA parcel can be found by the order number — resolves an unknown handoff
updatesHow its updates reach Wocart: pushed by webhook, or pulled every few minutes
labelaskReturnrequestNewAttemptconfirmReturnstopDeskListgeoNamesverifyConnectionStopDesk
idcompanyIdcodeStation code to use as stationCode when dispatching a stop-desk order. Format differs by provider: Noest = alphanumeric code (e.g. "16A"); Yalidine = numeric center_id (e.g. "160101"); ZR Express = territory UUID; EcoTrack = postal code string.
namecommunewilayaIdaddressphonesContact phone numbers for the stop-desk station.
activeAdmin toggle. When false, this stop desk is hidden from merchant UI. Survives re-sync.
syncedAtLast time this row was fetched from the carrier API (via POST .../sync-stop-desks).
Product
idnamedescriptiondescriptionFormatHow description is stored. text renders as literal text (legacy rows and products created without a format); html was sanitised at write against the rich-text allow-list.
descriptionPlainTag-free rendering of description for meta/JSON-LD (tags stripped, images dropped, entities decoded, whitespace collapsed). Identical to description for text rows; null when description is null.
handleURL slug — auto-generated from name if not provided
currencypricePrice in DZD (smallest unit)
compareAtPricecostPricetypehasVariantsVariant option axes. Parsed from JSON storage — null when the product has no options.
skuOnly used by simple products (hasVariants=false); variant products carry SKU on each variant.
inventoryStock for simple products; ignored for variant products.
lowStockThresholdAlert when stock drops to this level. Ignored for variant products (threshold is per-variant).
trackInventorycategoryIdtagsParsed from JSON storage.
visibilitystatusshowInStorepublishedAtAuto-set when status changes to ACTIVE
shippingProfileIdShipping profile ID for this product. Null = store default profile is used.
createdAtupdatedAtmetaTitleSearch-engine title (60 characters at most); null: the product's name
metaDescriptionSearch-engine description (160 characters at most); null: the product's description, shortened
variantsCountNumber of variants attached to this product
totalInventorySum of variant inventory for variant products; product.inventory for simple products
Variants ordered by position; variations are parsed into objects
primaryImageThe gallery's first image. Included in list responses only.
reviewCountApproved review count. Included in list responses only.
avgRatingAverage approved rating (1 decimal), null when unreviewed. Included in list responses only.
categoryFull category record. Included only in GET /{id} detail responses.
Images ordered by position. Included only in GET /{id} detail and mutation responses.
ProductVariant
idproductIdKey-value map matching the product's variantOptions axes
currencypricePrice in DZD
compareAtPriceskuUnique stock-keeping unit identifier. Used for order tracking and inventory management.
barcodeinventorylowStockThresholdAlert when this variant's stock drops to this level.
weightKgimageIdProduct image ID associated with this variant
isDefaultactivepositioncreatedAtupdatedAtProductImage
idproductIdkeyA Media Key: the image's identity in the store's media. Never a URL.
urlWhere browsers fetch it, from the store's Media Delivery
widthheightaltTextAlt text for accessibility
positionDisplay order (1 = first)
createdAtupdatedAtProductDetail
idnamedescriptiondescriptionFormatHow description is stored. text renders as literal text (legacy rows and products created without a format); html was sanitised at write against the rich-text allow-list.
descriptionPlainTag-free rendering of description for meta/JSON-LD (tags stripped, images dropped, entities decoded, whitespace collapsed). Identical to description for text rows; null when description is null.
handleURL slug — auto-generated from name if not provided
currencypricePrice in DZD (smallest unit)
compareAtPricecostPricetypehasVariantsVariant option axes. Parsed from JSON storage — null when the product has no options.
skuOnly used by simple products (hasVariants=false); variant products carry SKU on each variant.
inventoryStock for simple products; ignored for variant products.
lowStockThresholdAlert when stock drops to this level. Ignored for variant products (threshold is per-variant).
trackInventorycategoryIdtagsParsed from JSON storage.
visibilitystatusshowInStorepublishedAtAuto-set when status changes to ACTIVE
shippingProfileIdShipping profile ID for this product. Null = store default profile is used.
createdAtupdatedAtmetaTitleSearch-engine title (60 characters at most); null: the product's name
metaDescriptionSearch-engine description (160 characters at most); null: the product's description, shortened
variantsCountNumber of variants attached to this product
totalInventorySum of variant inventory for variant products; product.inventory for simple products
Variants ordered by position; variations are parsed into objects
collectionIdsThe collections the product is in (curated lists such as featured or best-sellers)
primaryImageThe gallery's first image. Included in list responses only.
reviewCountApproved review count. Included in list responses only.
avgRatingAverage approved rating (1 decimal), null when unreviewed. Included in list responses only.
categoryFull category record. Included only in GET /{id} detail responses.
Images ordered by position. Included only in GET /{id} detail and mutation responses.
ProductRemoval
idnamevariantsimagesreviewsoffersOffers it triggers or rewards: removed with it
landingPagesIts landing pages, with their images and pixel settings: removed with it
landingPageOrdersOrders those landing pages brought: kept, without the landing page link
orderLinesOrder lines that sold it: kept as sold, without the product link
ordersToShipOrders holding it not handed to delivery yet: they keep the line, which is never put back in stock
ProductCategory
idnameslugLowercase letters, numbers and hyphens; auto-generated from name with a unique suffix when omitted
descriptionparentIdParent group ID for nested hierarchies; null for top-level groups
imageThe group's image, from its Media Key
metaTitleSEO page title (max 60 chars)
metaDescriptionSEO description (max 160 chars)
metaKeywordsComma-separated SEO keywords
positionDisplay order; lower values come first
createdAtupdatedAtproductsCountNumber of active (non-deleted) products assigned to this group
Immediate sub-categories. Included only in GET /api/product-groups/{id}.
LandingPageListItem
idslugnamestatusproductIdproductNameproductHandleimageCountviewsordersrevenuepublicUrlThe shareable storefront URL for this page
publishedAtcreatedAtupdatedAttrackingThis page's own pixel, or null when it inherits the store's. Enough to badge a list row; the access token is never included. Whether it is actually in force also depends on the store's per-page tracking switch.
LandingPage
idslugPublic URL identifier — /lp/
nameInternal label, never rendered publicly
productIdstatusdraft → published → archived. Only published pages resolve publicly.
imageGapPixels between stacked images — the only spacing setting
metaTitlemetaDescriptionviewspublicUrlThe shareable storefront URL (from the store's domain, or the deployment's storefront fallback; relative /lp/
publishedAtcreatedAtupdatedAtThe image stack, ordered by position (1 = top)
productThe single product this page sells
LandingPageImage
idlandingPageIdkeyA Media Key: the image's identity in the store's media. Never a URL.
urlWhere browsers fetch it, from the store's Media Delivery
altTextAlt text for accessibility
sourceHow the image entered the stack (AI generation is a future phase)
positionStack order (1 = top of the page)
widthIntrinsic pixel width — the storefront reserves this space to prevent layout shift; null on legacy rows
heightIntrinsic pixel height — the storefront reserves this space to prevent layout shift; null on legacy rows
createdAtLandingPageStats
viewsordersrevenueSum of attributed order prices in DZD
LandingPageTrackingState
configThe page's own pixel, or null when it inherits the store's.
lastEventThe last Conversions API attempt for this page, or null when there has been none.
LandingPageTracking
idlandingPageIdpixelIdThe Meta Pixel this page reports to. Public by definition — it appears in the page source.
adAccountNameThe merchant's own label for the ad account. Reference only, never sent to Meta.
accessTokenMaskedLast four characters of the stored Conversions API token. The token itself never leaves the server.
testEventCodeconversionEventWhich moment counts as a conversion for THIS page's campaigns — independent of the store's choice.
testModeenabledSwitched off returns the page to the store pixel without losing what was configured.
createdAtupdatedAtLandingPageTrackingActivity
eventNamestageWhich business moment produced it: checkout, confirmed, or delivered.
statussent | failed | skipped | claimed
pixelIdWhich pixel it went to. Null only for rows written before this was recorded.
errorMeta's own message when the attempt failed.
sentAtStorePageSummary
idkindslugPublic URL segment — /pages/
statusshowInFooterpositiontemplateVersionWhich template revision this page's prose was last seeded/reset from. Null for custom pages.
createdAtupdatedAtStorePageTranslationSummary
localetitlesource'template' = still the seeded text, never reviewed. 'merchant' = edited at least once.
updatedAtStoreLegalProfile
storeIdlegalNamercNumberRegistre de Commerce number
nifNuméro d'Identification Fiscale
addresscontactEmailcontactPhonereturnWindowDays0 = no post-delivery return window offered; the refund page's return clause is dropped.
deliveryMinDaysdeliveryMaxDaysupdatedAtStorePageDetail
idkindslugPublic URL segment — /pages/
statusshowInFooterpositiontemplateVersionWhich template revision this page's prose was last seeded/reset from. Null for custom pages.
createdAtupdatedAtFull body per locale. A locale never saved is absent, not null.
StorePageTranslationBody
pageIdlocaletitlebodyHtmlSanitised HTML — h2/p/strong/ul/li/etc. Render with set:html, never re-sanitise.
bodyPlainmetaTitlemetaDescriptionsourceupdatedAtMenuSummary
idhandle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the menu
titleitemCountupdatedAtMenuDestinationOption
idlabelpathIts public path
visibleFalse when shoppers cannot see it now: an item pointing at it is left out of the menu
MenuDetail
idhandle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the menu
titleupdatedAtMenuItem
idlabeldestinationStatusmissing: the destination was deleted. hidden: it exists but shoppers cannot see it (a draft page, an inactive product). Either way the storefront leaves the item out.
destinationLabelThe destination's name (a product's or category's name, a page's slug)
MenuDestination
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: type | |
| type = object · requires: type, ref | |
| type = object · requires: type, url |
typeA page of the store: the home, every product, search, order tracking or contact
MenuItemInput
labelidAn existing item's id, to keep it (and its translations)
CollectionSummary
idhandle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the collection
titleproductCountupdatedAtCollectionDetail
idhandle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the collection
titledescriptionupdatedAtCheckoutFormPolicy
addressHome delivery only. Hidden is allowed; the dispatch guard ensures a home parcel has an address before leaving.
notesemailDefaults to hidden, which is the storefront's behaviour before this feature. Stored on the order (orders.customer_email) when the shopper supplies one.
At least one must stay on — a form with neither cannot be submitted.
CheckoutFormCustomField
labeltypeid^cf_[a-z0-9]{8}$Server-minted id. Omit it to create a field; send it to edit the field it names. An id the store does not already have is rejected — ids key the answer snapshots on existing orders.
requiredoptionsDropdown choices — select only, and required for it.
CheckoutFormPolicyInput
App
keyThe App Key: its name in URLs, the API and permissions
categorystatusnot_set_up | on | off | needs_attention (on, but what it sends is failing, or it cannot do what it is on for)
StorePixelConfig
idstoreIdpixelIdadAccountNameMerchant's own label for the Meta ad account — reference only, never sent to Meta.
accessTokenMaskedMasked hint of the stored Meta access token — the token itself is write-only.
testEventCodeMeta test event code — used only while Test Mode is on. Set to null in production.
conversionEventMerchant-chosen conversion event: 'Purchase' fires immediately at checkout, 'Purchase_Confirmed' fires on order confirmation, 'Purchase_Delivered' fires on confirmed delivery, and 'Lead' fires at checkout.
testModeWhen true, Conversions API events carry test_event_code to Meta's test stream.
enabledperPageTrackingEnabledMaster switch for per-landing-page pixels. While false (the default), every landing page reports to this pixel no matter what is configured against it — which is also this feature's rollback.
createdAtupdatedAtWhatsAppButtonConfig
enabledphoneStored in E.164, however the merchant typed it.
agentNamecaptionavatarKeyThe agent's photo, from a completed upload; null shows the store's logo.
welcomeMessagelauncherLabelctaLabelprefillGeneralprefillProductthankYouButtonLabelprefillThankYouaccentpositionattentionWhich kinds of storefront page the launcher appears on. A fixed registry rather than URL patterns, and every surface off is a valid paused state.
WhatsAppButtonSurfaces
homecatalogproductpagesthankYoucheckoutlandingWhatsAppButtonConfigInput
TelegramApp
consumerIdThe Telegram Consumer the bot sends through: its deliveries are under /api/event-deliveries
enableddisabledReasonWhy it is off: not_connected (no chat yet), bot_blocked (the chat blocked the bot), merchant, failing; null while on
failingSinceSince when every message has failed; null once one is delivered
botThe saved bot; null once it was disconnected
chatThe connected chat; null until someone presses Start on a pairing link
pairingExpiresAtUntil when the latest pairing link works; null when none is open
eventslanguagewritesInThe language messages are written in now
TelegramChange
eventsThe Event Types the bot tells, one or more
languageThe language messages are written in; null for the store's primary language
enabledOn or off. Turning it on needs a connected chat.
ReviewRules
enabledWhen false, reviews are hidden on the storefront and shoppers cannot send one
maxPhotosPhotos a shopper may add to a review, 0 (none) to 6
Longest voice note a shopper may add, in seconds (30, 60, 90, 120); null = no voice notes
autoPublishWhich shopper reviews publish without checking: none (off), text-only ones (text_only: anything with a photo or voice note waits), or all
ShippingLabelConfig
sizeThe physical label: 100×150 mm, the 4×6 inch roll of thermal printers
languageThe language of the label's own words; the order's details print as written
showLogosenderPhonePrinted for the sender; null prints the legal profile's contact phone
showItemsWhat is in the parcel: quantity, name and variant of each line
showNotesThe order's notes, for the driver
openParcelWhether the customer may open the parcel before paying; unset prints nothing
footerShippingLabelSender
namelogoUrlphoneaddressShippingLabelParcel
shipmentIdorderNumberhandedAtWhen the order was given to the driver
amountThe cash to collect, frozen on the shipment
notesdriverShippingProfile
idnameisDefaultExactly one profile is always the default; its rates auto-apply on order creation
notesproductCountHow many products are assigned to this profile
createdAtupdatedAtruleCountNumber of wilaya rules in this profile
ShippingProfileWithRules
idnameisDefaultExactly one profile is always the default; its rates auto-apply on order creation
notesproductCountHow many products are assigned to this profile
createdAtupdatedAtShippingRule
idprofileIdwilayaIdwilayaNameWilaya French/name — joined from reference table
wilayaNameArhomePricestopDeskPricehomeEnabledstopDeskEnabledcreatedAtCommuneOverride
communeIdcommuneNamecommuneNameArpostalCodehomeEnablednull = inherited from wilaya rule
stopDeskEnablednull = inherited from wilaya rule
homePricenull = inherited from wilaya rule
stopDeskPricenull = inherited from wilaya rule
effectiveHomeEnabledeffectiveStopDeskEnabledeffectiveHomePriceeffectiveStopDeskPricehasOverrideDriverPayment
iddriverIdUUID of the driver this payment is for
typecod_remittance: driver hands COD cash to business. fee_payment: business pays driver fees. net_settlement: both at once (driver hands COD − fees net amount).
amountSettled amount, computed server-side from the shipments' frozen values: cash total (cod_remittance), fee total (fee_payment), or cash − fees (net_settlement).
orderCountNumber of shipments (one per order) this payment settles.
notesOptional internal note about this payment record.
createdByUser ID of the team member who recorded this payment.
createdByNameDenormalised display name for audit trail.
createdAtPendingSettlement
shipmentIdorderIdorderNumbercustomerNamecodAmountCash the driver collected (DZD)
driverFeeThe driver's frozen fee (DZD)
deliveredAtcodPaymentIdThe payment that settled the cash; null while the driver still holds it
feePaymentIdThe payment that settled the fee; null while it is owed
Store
idnamedomainCustom storefront domain
logoThe store's logo
themeIdThe storefront theme's slug, e.g. "theme-00"
langThe store's primary language: its storefront language and first fallback
currencycurrencySymbolmetaTitlemetaDescriptionogImageThe image links to the store show when shared
cartEnabledWhen true the storefront renders the shopping cart alongside the direct order form
freeShippingThresholdOrder subtotal (DZD) at or above which delivery is free. null = off
cartShippingModeWhich rate a basket spanning several shipping profiles pays
storeApiKeyPlaintext storefront API key — visible to the merchant in Store Settings. Not the dashboard API key.
createdAtupdatedAtEvery language the store has added, primary first, published or not.
StoreLanguage
localepublishedShown to shoppers. Always true for the primary.
primaryReview
idproductIdproductNameorderIdThe order it rests on; null for a store review without one
orderNumbercustomerIdcustomerNameratingtitlebodystatussourceSent by a shopper (storefront) or entered by the store (merchant)
verifiedRests on a delivered order: the storefront shows it as a verified purchase
mediaDroppedPhotos or voice notes received but not kept (unreadable, too long)
createdByThe staff member who entered a store review
createdAtupdatedAtReviewMedia
idkindurlA photo at 1600 px at most (WebP), or the voice note as recorded
thumbUrlA photo's 480 px version for lists
contentTypebyteswidthheightdurationMsA voice note's length
Offer
idOffer UUID
nameMerchant-facing display name.
triggerProductThe product the customer must purchase to trigger this offer. Null when the trigger product no longer exists.
triggerVariantSpecific variant required to trigger the offer. null = any variant of the trigger product.
triggerQuantityMinimum quantity of the trigger product the customer must order.
rewardProductThe product the customer receives for free when the offer triggers. null for free_shipping offers.
rewardVariantSpecific variant given as the reward. null = same variant as the ordered item (when same product) or the first active variant (when different product). Always null for free_shipping offers.
rewardQuantityNumber of free reward units added to the order. 0 for free_shipping offers.
discountTypefree = reward product added at price 0. free_shipping = delivery fee waived (no reward product).
startsAtUTC ISO-8601 datetime when the offer becomes active. null = no start restriction.
endsAtUTC ISO-8601 datetime when the offer expires. null = no end restriction.
statusOnly active offers within the schedule window are auto-applied to store orders.
stateWhere the offer stands now: switched off, not started, ended, or live — the only state shoppers see it in.
createdAtupdatedAtCouponSummary
idcodekindvaluemaxDiscountminSubtotalminQuantityscopeaudienceusageLimitoncePerCustomerstartsAtendsAtstatusstateWhere the coupon stands now.
usesOrders that used it and are not cancelled.
discountGivenWhat those orders were given off, in dinars.
createdAtupdatedAtCoupon
idcodekindvaluemaxDiscountminSubtotalminQuantityscopeaudienceusageLimitoncePerCustomerstartsAtendsAtstatusstateWhere the coupon stands now.
usesOrders that used it and are not cancelled.
discountGivenWhat those orders were given off, in dinars.
createdAtupdatedAtStockOverview
totalSkusTotal number of tracked SKUs (simple + variants).
outOfStockCountlowStockCounttotalInventoryValueSum of (inventory × price) across all tracked SKUs, in DZD.
currencyItems at or below their low stock threshold (but still in stock).
Every tracked SKU. Sorted: out-of-stock first, then by inventory ascending. Used by the inventory table.
StockAlertItem
productIdvariantIdproductNamevariantLabelConcatenated variant option values, e.g. 'Red / M'. Null for simple products.
skuSKU code of the tracked row. Null when a simple product has none.
inventorylowStockThresholdisOutOfStockupdatedAtLast write to the SKU row — every stock adjustment updates it.
StockMovement
idproductIdvariantIdVariant ID for variant-level movements; null for simple products
typedeltaPositive = stock in, negative = stock out. Never zero.
qtyBeforeqtyAfterreasonUser-supplied note. Required by the API for ADJUSTMENT_ADD, ADJUSTMENT_REMOVE and OFFLINE_SALE.
referenceorderId for ORDER_* movement types; null otherwise.
createdBycreatedByNamecreatedAtAbandonedOrder
idsessionIdStorefront session ID — unique per abandoned checkout
customerNamephonewilayaIdcommuneIdwilayaNamecommuneNameproductIdproductNameThe only product, or the FIRST line of the basket. Always populated, so this column reads the same for both shapes.
variantIdvariantLabelpriceCart value at abandonment — the basket subtotal, or one unit's price
The whole basket, when the shopper abandoned a cart checkout. Null for a single-product checkout, where the flat product fields above are the record.
itemCountDistinct lines in the basket. Null for a single-product checkout.
deliveryTypefbc_fbc cookie captured at input — links recovery back to the ad click
fbp_fbp browser identity cookie
ipAddressuserAgentstatusconvertedOrderIdSet when the customer completes an order after contact
convertedOrderNumberrecoveryAttemptscreatedAtupdatedAtAbandonedOrderItem
productIdproductNamequantityunitPricePrice shown to the shopper at abandonment. Display only.
variantIdvariantLabelAbandonedOrderStats
totalAbandonedOrders currently in abandoned status
totalConvertedconversionRateRecovered percentage: converted / (abandoned + converted), rounded
estimatedLostRevenueSum of cart values still sitting in abandoned status, in DZD