Generated API reference

Endpoint reference generated at build time from the OpenAPI annotations in the Ebda Store API source. The raw document is available as /openapi.json (OpenAPI 3.0.0).

Stores

GET https://api.ebda.app/api/v1/stores

List all stores Get paginated list of all stores (admin only)

Requires authentication (Bearer access token or the auth cookie).

Parameters

NameInTypeDescription
pagequeryinteger
limitqueryinteger

Responses

  • 200 List of stores (object)
  • 401
  • 403

POST https://api.ebda.app/api/v1/stores

Create a new store Create a new store (admin only)

Requires authentication (Bearer access token or the auth cookie).

Request body

NameTypeDescription
name (required)stringExample: "My Store"
slugstringExample: "my-store"
domainstringExample: "mystore.com"
settingsobject
{
  "name": "My Store",
  "slug": "my-store",
  "domain": "mystore.com",
  "settings": null
}

Responses

  • 201 Store created successfully (object)
  • 400
  • 401

Products

GET https://api.ebda.app/api/v1/stores/{storeId}/products

List products Get paginated list of products for a store

No authentication required.

Parameters

NameInTypeDescription
storeId (required)pathstring (uuid)
pagequeryinteger
limitqueryinteger
statusquerystring: "active" | "draft" | "archived"
categoryquerystring
searchquerystring
featuredquerybooleanOmit for all products; 'true' or 'false' filters. Any other value is a 400.

Responses

  • 200 List of products (object)

Authentication

POST https://api.ebda.app/api/v1/auth/register

Register a new user Create a new user account with email verification

No authentication required.

Request body

NameTypeDescription
email (required)string (email)Example: "user@example.com"
password (required)stringExample: "securePassword123"
firstNamestringExample: "John"
lastNamestringExample: "Doe"
{
  "email": "user@example.com",
  "password": "securePassword123",
  "firstName": "John",
  "lastName": "Doe"
}

Responses

  • 200 Verification email sent. Identical for new and existing emails (T1-4 enumeration close) — no user, tokens, cookies or csrfToken are issued; the session starts at /auth/login after verification. (object)
  • 400

POST https://api.ebda.app/api/v1/auth/login

Login user Authenticate user and return JWT tokens

No authentication required.

Request body

NameTypeDescription
email (required)string (email)
password (required)string
{
  "email": "string",
  "password": "string"
}

Responses

  • 200 Login successful (object)
  • 401 Invalid credentials

Schemas

Error

NameTypeDescription
successbooleanExample: false
errorobject
error.codestringExample: "VALIDATION_ERROR"
error.messagestringExample: "Invalid request data"

Pagination

NameTypeDescription
pageintegerExample: 1
limitintegerExample: 20
totalintegerExample: 100
totalPagesintegerExample: 5

User

NameTypeDescription
idstring (uuid)
emailstring (email)
firstNamestring
lastNamestring
rolestring: "customer" | "store_admin" | "super_admin"
isVerifiedboolean
createdAtstring (date-time)

Store

NameTypeDescription
idstring (uuid)
namestring
nameArstring
slugstring
descriptionstring
logostring (uri)
domainstring
statusstring: "active" | "suspended" | "pending"
createdAtstring (date-time)

Product

NameTypeDescription
idstring (uuid)
storeIdstring (uuid)
namestring
nameArstring
slugstring
descriptionstring
descriptionArstring
priceintegerPrice in piastres (1 EGP = 100 piastres)
compareAtPriceinteger
skustring
badgeLabelstring
badgeLabelArstring
searchTermsstringExtra words shoppers type (dialect / Franco / English); comma-separated, cleaned to "a, b, c". Searched, never displayed. null clears.
inventoryinteger
statusstring: "active" | "draft" | "archived"
imagesProductImage[]
images.idstring (uuid)
images.urlstring (uri)
images.altstring
images.positioninteger
categoryCategory
category.idstring (uuid)
category.namestring
category.nameArstring
category.slugstring
category.descriptionstring
category.descriptionArstring
category.imagestring (uri)
createdAtstring (date-time)

ProductImage

NameTypeDescription
idstring (uuid)
urlstring (uri)
altstring
positioninteger

Category

NameTypeDescription
idstring (uuid)
namestring
nameArstring
slugstring
descriptionstring
descriptionArstring
imagestring (uri)

Order

NameTypeDescription
idstring (uuid)
orderNumberstring
statusstring: "pending" | "confirmed" | "processing" | "shipped" | "delivered" | "cancelled" | "refunded"
subtotalinteger
taxinteger
shippinginteger
totalinteger
shippingAddressobject
billingAddressobject
itemsOrderItem[]
items.idstring (uuid)
items.productIdstring (uuid)
items.productNamestring
items.skustring
items.quantityinteger
items.priceinteger
items.totalinteger
customerUser
customer.idstring (uuid)
customer.emailstring (email)
customer.firstNamestring
customer.lastNamestring
customer.rolestring: "customer" | "store_admin" | "super_admin"
customer.isVerifiedboolean
customer.createdAtstring (date-time)
createdAtstring (date-time)

OrderItem

NameTypeDescription
idstring (uuid)
productIdstring (uuid)
productNamestring
skustring
quantityinteger
priceinteger
totalinteger

Cart

NameTypeDescription
idstring (uuid)
itemsCartItem[]
items.idstring (uuid)
items.productIdstring (uuid)
items.quantityinteger
items.productProduct
items.product.idstring (uuid)
items.product.storeIdstring (uuid)
items.product.namestring
items.product.nameArstring
items.product.slugstring
items.product.descriptionstring
items.product.descriptionArstring
items.product.priceintegerPrice in piastres (1 EGP = 100 piastres)
items.product.compareAtPriceinteger
items.product.skustring
items.product.badgeLabelstring
items.product.badgeLabelArstring
items.product.searchTermsstringExtra words shoppers type (dialect / Franco / English); comma-separated, cleaned to "a, b, c". Searched, never displayed. null clears.
items.product.inventoryinteger
items.product.statusstring: "active" | "draft" | "archived"
items.product.imagesProductImage[]
items.product.categoryCategory
items.product.createdAtstring (date-time)
itemCountinteger
subtotalinteger

CartItem

NameTypeDescription
idstring (uuid)
productIdstring (uuid)
quantityinteger
productProduct
product.idstring (uuid)
product.storeIdstring (uuid)
product.namestring
product.nameArstring
product.slugstring
product.descriptionstring
product.descriptionArstring
product.priceintegerPrice in piastres (1 EGP = 100 piastres)
product.compareAtPriceinteger
product.skustring
product.badgeLabelstring
product.badgeLabelArstring
product.searchTermsstringExtra words shoppers type (dialect / Franco / English); comma-separated, cleaned to "a, b, c". Searched, never displayed. null clears.
product.inventoryinteger
product.statusstring: "active" | "draft" | "archived"
product.imagesProductImage[]
product.images.idstring (uuid)
product.images.urlstring (uri)
product.images.altstring
product.images.positioninteger
product.categoryCategory
product.category.idstring (uuid)
product.category.namestring
product.category.nameArstring
product.category.slugstring
product.category.descriptionstring
product.category.descriptionArstring
product.category.imagestring (uri)
product.createdAtstring (date-time)

Review

NameTypeDescription
idstring (uuid)
ratinginteger
titlestring
commentstring
isVerifiedboolean
isApprovedboolean
helpfulCountinteger
createdAtstring (date-time)

Return

NameTypeDescription
idstring (uuid)
returnNumberstring
typestring: "return" | "exchange" | "refund"
statusstring: "pending" | "approved" | "rejected" | "shipped" | "received" | "inspecting" | "completed" | "cancelled"
reasonstring
refundAmountinteger
itemsReturnItem[]
items.idstring (uuid)
items.productIdstring (uuid)
items.productNamestring
items.quantityinteger
items.reasonstring
items.conditionstring
items.orderItemobject
items.orderItem.bundleGroupIdstring (uuid)
items.orderItem.bundleNamestring
items.orderItem.bundleNameArstring
createdAtstring (date-time)

ReturnItem

NameTypeDescription
idstring (uuid)
productIdstring (uuid)
productNamestring
quantityinteger
reasonstring
conditionstring
orderItemobject
orderItem.bundleGroupIdstring (uuid)
orderItem.bundleNamestring
orderItem.bundleNameArstring

DashboardStats

NameTypeDescription
totalOrdersinteger
totalRevenueinteger
totalProductsinteger
totalCustomersintegerDistinct customers in the period, keyed like the Customers page (user, else shipping email, else phone)
allTimeCustomersinteger
ordersChangenumber (float)
revenueChangenumber (float)
conversionRatenumber (float)Orders per product view (%), null when no views were recorded
totalProfitintegerPiastres; null when sold lines have no cost price
profitItemsMissingCostinteger
profitRevenueMissingCostinteger