Skip to content

storefront

← All modules

17 endpoints.

GET /api/v1/storefront/items

List Items By Sku

Parameters

NameInRequiredTypeDescription
skusqueryyesstringComma-separated item codes/SKUs

200 — Successful Response

json
{
  "type": "array",
  "items": {
    "properties": {
      "sku": {
        "type": "string",
        "title": "Sku"
      },
      "name": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Name"
      },
      "uom": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Uom"
      },
      "is_sales": {
        "type": "boolean",
        "title": "Is Sales"
      },
      "is_stock_item": {
        "type": "boolean",
        "title": "Is Stock Item"
      },
      "disabled": {
        "type": "boolean",
        "title": "Disabled"
      }
    },
    "type": "object",
    "required": [
      "sku",
      "name",
      "uom",
      "is_sales",
      "is_stock_item",
      "disabled"
    ],
    "title": "StorefrontItem"
  },
  "title": "Response List Items By Sku Api V1 Storefront Items Get"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

GET /api/v1/storefront/item-prices

List Item Prices

General list pricing only (customer_id IS NULL) — not customer-specific negotiated rates.

Parameters

NameInRequiredTypeDescription
skusqueryyesstringComma-separated item codes/SKUs
price_listquerynoPrice list name; omit for all enabled selling price lists

200 — Successful Response

json
{
  "type": "array",
  "items": {
    "properties": {
      "sku": {
        "type": "string",
        "title": "Sku"
      },
      "price_list": {
        "type": "string",
        "title": "Price List"
      },
      "currency": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Currency"
      },
      "rate": {
        "type": "number",
        "title": "Rate"
      },
      "rate_gbp": {
        "anyOf": [
          {
            "type": "number"
          },
          {
            "type": "null"
          }
        ],
        "title": "Rate Gbp"
      },
      "min_qty": {
        "type": "number",
        "title": "Min Qty"
      }
    },
    "type": "object",
    "required": [
      "sku",
      "price_list",
      "currency",
      "rate",
      "rate_gbp",
      "min_qty"
    ],
    "title": "StorefrontItemPrice"
  },
  "title": "Response List Item Prices Api V1 Storefront Item Prices Get"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

GET /api/v1/storefront/customers

Find Customer By Email

Parameters

NameInRequiredTypeDescription
emailqueryyesstringExact email match (case-insensitive)

200 — Successful Response

json
{
  "type": "array",
  "items": {
    "properties": {
      "id": {
        "type": "string",
        "title": "Id"
      },
      "name": {
        "type": "string",
        "title": "Name"
      },
      "email": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Email"
      },
      "phone": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Phone"
      },
      "currency": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Currency"
      },
      "disabled": {
        "type": "boolean",
        "title": "Disabled"
      },
      "customer_group": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Customer Group"
      },
      "default_price_list": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Default Price List"
      }
    },
    "type": "object",
    "required": [
      "id",
      "name",
      "email",
      "phone",
      "currency",
      "disabled",
      "customer_group",
      "default_price_list"
    ],
    "title": "StorefrontCustomer"
  },
  "title": "Response Find Customer By Email Api V1 Storefront Customers Get"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/storefront/customers

Create Storefront Customer

Create a brand-new Customer for a first-time storefront checkout. No generic /accounting/documents/{doctype} equivalent exists — Customer was never one of the doctypes that endpoint supports (see accounting_documents._ITEM_DOCS) — so this is a small, purpose-built create, same spirit as the rest of this module. Group/territory are resolved by name if a row with that name exists; left unset otherwise (both nullable) rather than failing the whole checkout over it.

Request body

json
{
  "properties": {
    "name": {
      "type": "string",
      "title": "Name"
    },
    "email": {
      "type": "string",
      "title": "Email"
    },
    "phone": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Phone"
    }
  },
  "type": "object",
  "required": [
    "name",
    "email"
  ],
  "title": "StorefrontCustomerIn"
}

201 — Successful Response

json
{
  "properties": {
    "id": {
      "type": "string",
      "title": "Id"
    },
    "name": {
      "type": "string",
      "title": "Name"
    },
    "email": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Email"
    },
    "phone": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Phone"
    },
    "currency": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Currency"
    },
    "disabled": {
      "type": "boolean",
      "title": "Disabled"
    },
    "customer_group": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Customer Group"
    },
    "default_price_list": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Default Price List"
    }
  },
  "type": "object",
  "required": [
    "id",
    "name",
    "email",
    "phone",
    "currency",
    "disabled",
    "customer_group",
    "default_price_list"
  ],
  "title": "StorefrontCustomer"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/storefront/orders/{order_id}/pay

Pay Storefront Order

Start a Paystack checkout for an already-created+submitted Sales Order — thin wrapper around the same accounting_payment_paystack.init_quote_like_payment that powers the public "Pay Now" link on a Quotation/Sales Order PDF (GET /paystack/pay-quote/{token}). Deliberately calls the service directly with the caller's own callback_url instead of reusing that GET route, which hardcodes a redirect back to this platform's own /portal — the external storefront needs its shopper landing back on its own checkout success page. Once Paystack confirms payment, the existing webhook (settlement == "quote_like") books the on-account Payment Entry automatically — no separate booking call needed from the caller.

Parameters

NameInRequiredTypeDescription
order_idpathyesinteger

Request body

json
{
  "properties": {
    "callback_url": {
      "type": "string",
      "title": "Callback Url"
    }
  },
  "type": "object",
  "required": [
    "callback_url"
  ],
  "title": "StorefrontOrderPayIn"
}

200 — Successful Response

json
{
  "properties": {
    "ok": {
      "type": "boolean",
      "title": "Ok"
    },
    "authorization_url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Authorization Url"
    },
    "reference": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Reference"
    },
    "message": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Message"
    }
  },
  "type": "object",
  "required": [
    "ok"
  ],
  "title": "StorefrontOrderPayOut"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/settings/storefront/extract-favicon

Extract Favicon

Isolate the icon/symbol mark from an uploaded logo (dropping any wordmark) via Gemini image generation, and return it as a real transparent-background PNG. Mirrors app.grids.accounting's item-photo generator's green-screen-then-key-out trick — Gemini has no way to emit real alpha, so it's asked for a flat chroma-key background that gets keyed out server-side afterwards (see gemini_client.remove_green_screen). Pure preview: nothing is persisted here, the caller still has to Save.

Request body

json
{
  "properties": {
    "logo_url": {
      "type": "string",
      "maxLength": 750000,
      "title": "Logo Url"
    }
  },
  "type": "object",
  "required": [
    "logo_url"
  ],
  "title": "ExtractFaviconIn"
}

200 — Successful Response

json
{}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/settings/storefront/generate-hero-image

Generate Hero Image

Generate a photographic hero banner from a text brief via Gemini image generation. Pure preview like extract_favicon: nothing is persisted here, the caller still has to Save (into branding.hero_image_url).

Request body

json
{
  "properties": {
    "prompt": {
      "type": "string",
      "maxLength": 500,
      "title": "Prompt"
    }
  },
  "type": "object",
  "required": [
    "prompt"
  ],
  "title": "GenerateHeroImageIn"
}

200 — Successful Response

json
{}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

GET /api/v1/settings/storefront

Get Settings

200 — Successful Response

json
{}

PUT /api/v1/settings/storefront

Update Settings

Request body

json
{
  "properties": {
    "display_mode": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Display Mode"
    },
    "paystack_enabled": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Paystack Enabled"
    },
    "published": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Published"
    },
    "builder_chat_enabled": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Builder Chat Enabled"
    },
    "store_name": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 255
        },
        {
          "type": "null"
        }
      ],
      "title": "Store Name"
    },
    "tagline": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 255
        },
        {
          "type": "null"
        }
      ],
      "title": "Tagline"
    },
    "branding": {
      "anyOf": [
        {
          "properties": {
            "logo_url": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 750000
                },
                {
                  "type": "null"
                }
              ],
              "title": "Logo Url"
            },
            "favicon_url": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 400000
                },
                {
                  "type": "null"
                }
              ],
              "title": "Favicon Url"
            },
            "hero_image_url": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 750000
                },
                {
                  "type": "null"
                }
              ],
              "title": "Hero Image Url"
            },
            "primary_color": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 20
                },
                {
                  "type": "null"
                }
              ],
              "title": "Primary Color"
            },
            "support_email": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 255
                },
                {
                  "type": "null"
                }
              ],
              "title": "Support Email"
            },
            "whatsapp_number": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 32
                },
                {
                  "type": "null"
                }
              ],
              "title": "Whatsapp Number"
            },
            "phone": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 32
                },
                {
                  "type": "null"
                }
              ],
              "title": "Phone"
            },
            "address": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 255
                },
                {
                  "type": "null"
                }
              ],
              "title": "Address"
            }
          },
          "type": "object",
          "title": "BrandingIn"
        },
        {
          "type": "null"
        }
      ]
    },
    "shipping_options": {
      "anyOf": [
        {
          "items": {
            "properties": {
              "key": {
                "type": "string",
                "maxLength": 64,
                "title": "Key"
              },
              "label": {
                "type": "string",
                "maxLength": 120,
                "title": "Label"
              },
              "amount": {
                "type": "number",
                "title": "Amount",
                "default": 0
              }
            },
            "type": "object",
            "required": [
              "key",
              "label"
            ],
            "title": "ShippingOptionIn"
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "title": "Shipping Options"
    },
    "template": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Template"
    },
    "value_props": {
      "anyOf": [
        {
          "items": {
            "properties": {
              "title": {
                "type": "string",
                "maxLength": 80,
                "title": "Title"
              },
              "description": {
                "type": "string",
                "maxLength": 200,
                "title": "Description",
                "default": ""
              }
            },
            "type": "object",
            "required": [
              "title"
            ],
            "title": "ValuePropIn"
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "title": "Value Props"
    },
    "hero_eyebrow": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 120
        },
        {
          "type": "null"
        }
      ],
      "title": "Hero Eyebrow"
    },
    "hero_heading": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 200
        },
        {
          "type": "null"
        }
      ],
      "title": "Hero Heading"
    },
    "hero_subtext": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 500
        },
        {
          "type": "null"
        }
      ],
      "title": "Hero Subtext"
    },
    "shipping_flat_base": {
      "anyOf": [
        {
          "type": "number",
          "minimum": 0
        },
        {
          "type": "null"
        }
      ],
      "title": "Shipping Flat Base"
    },
    "shipping_flat_qty": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": 0
        },
        {
          "type": "null"
        }
      ],
      "title": "Shipping Flat Qty"
    },
    "shipping_flat_extra": {
      "anyOf": [
        {
          "type": "number",
          "minimum": 0
        },
        {
          "type": "null"
        }
      ],
      "title": "Shipping Flat Extra"
    }
  },
  "type": "object",
  "title": "StorefrontIn",
  "description": "Partial update — a field omitted (``None``) is left untouched."
}

200 — Successful Response

json
{}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

GET /api/v1/settings/storefront/pages

Get Pages

200 — Successful Response

json
{}

PUT /api/v1/settings/storefront/pages

Set Pages

Request body

json
{
  "properties": {
    "pages": {
      "additionalProperties": {
        "type": "boolean"
      },
      "type": "object",
      "title": "Pages"
    }
  },
  "type": "object",
  "required": [
    "pages"
  ],
  "title": "PageToggleIn"
}

200 — Successful Response

json
{}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/settings/storefront/domain

Set Domain

Kick off custom-domain provisioning: validates the hostname, checks it isn't already claimed by another site, then queues the DNS-check + nginx/certbot automation as a background job (can take up to ~a minute — see :func:app.services.storefront_provisioning.provision_domain).

Request body

json
{
  "properties": {
    "domain": {
      "type": "string",
      "maxLength": 253,
      "title": "Domain"
    }
  },
  "type": "object",
  "required": [
    "domain"
  ],
  "title": "DomainIn"
}

200 — Successful Response

json
{}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

DELETE /api/v1/settings/storefront/domain

Clear Domain

200 — Successful Response

json
{}

GET /api/v1/settings/storefront/domain/status

Domain Status

Lightweight poll target for the builder form's domain status badge.

200 — Successful Response

json
{}

POST /api/v1/settings/storefront/temp-domain

Set Temp Domain

Provision an instant <label>.erpcloud.co.za subdomain — unlike /domain, no DNS action is needed from the caller (the platform owns that zone); the DNS record itself is created as part of the background job. Independent of /domain — both can be live on the same site at once.

Request body

json
{
  "properties": {
    "label": {
      "type": "string",
      "maxLength": 32,
      "title": "Label"
    }
  },
  "type": "object",
  "required": [
    "label"
  ],
  "title": "TempDomainIn"
}

200 — Successful Response

json
{}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

DELETE /api/v1/settings/storefront/temp-domain

Clear Temp Domain

200 — Successful Response

json
{}

GET /api/v1/settings/storefront/temp-domain/status

Temp Domain Status

200 — Successful Response

json
{}

Lubb ERP Documentation