● Sandbox openGraphQL · REST · MCPv0.1.054 types

Schema

Every type the GraphQL API serves, generated from the code that answers it. Type names link to their definition. Tools read the plain file: /schema.graphql. To run a query, open the GraphQL explorer.

type Query {
  product(cprcode: ID!, branchCode: ID = null): Product
  products(filter: ProductFilter = null, branchCode: ID = null, first: Int! = 20, after: String = null): ProductConnection!
  categories: [CategoryCount!]!
  branches: [FulfilmentBranch!]!
  search(query: String!, mode: SearchMode! = SEMANTIC, limit: Int! = 20, branchCode: ID = null): [SearchHit!]!
  searchSuggest(query: String!, limit: Int! = 30): [String!]!
  inventory(branchCode: ID!, cprcodes: [ID!] = null): [InventoryLevel!]!
type Mutation {
  """
  A personal key that lets the signed-in shopper's own AI client shop as them on Villa's direct channel.
  """
  personalKeyCreate(label: String! = "Personal key"): PersonalKeyCreated!
  personalKeyRevoke(keyId: ID!): Boolean!
  basketAdd(input: BasketAddInput!): BasketPayload!
  basketRemove(input: BasketRemoveInput!): BasketPayload!
  basketSetQuantity(input: BasketSetQuantityInput!): BasketPayload!
  basketSetBranch(branchCode: ID!): BasketPayload!
  guestSession: GuestSessionPayload!
  basketEmpty: BasketPayload!
  orderCreate(input: OrderCreateInput = null): OrderPayload!
  quote(input: QuoteInput!): QuotePayload!
  quoteApplyCoupon(input: QuoteInput!): QuotePayload!
  paymentLinkCreate(orderId: ID!): PaymentLinkPayload!
  paymentStart(input: PaymentStartInput!): PaymentPayload!
}
input AddressInput {
  lat: Float = null
  lon: Float = null
  postcode: String = null
  address: String = null
  firstName: String = null
  lastName: String = null
  phone: String = null
  email: String = null
}
type Basket {
  basketId: ID!
  ownerId: ID!
  branchCode: ID!
  lines: [BasketLine!]!
}
input BasketAddInput {
  cprcode: ID!
  quantity: Int! = 1
  branchCode: ID = null
  attribution: BasketAttributionInput = null
}
"""
Which search put this product in the basket (the latest attributed add wins).
"""
type BasketAttribution {
  searchId: String!
  position: Int!
  source: String!
}
"""
Which search put the product in the basket. searchId is opaque, at most 128 characters; position is 1-based, 0 means unknown; source is search, suggestion (auto-complete picks too) or browse.
"""
input BasketAttributionInput {
  searchId: String!
  position: Int! = 0
  source: String! = "search"
}
"""
One basket change or placed order line, without the shopper (vca-f9c.3).
"""
type BasketEvent {
  """add, quantity, remove or order"""
  type: String!
type BasketEventPage {
  nodes: [BasketEvent!]!
type BasketLine {
  cprcode: ID!
  quantity: Int!
  attribution: BasketAttribution
  product: Product
}
type BasketPayload {
  basket: Basket
  userErrors: [UserError!]!
}
input BasketRemoveInput {
  cprcode: ID!
}
input BasketSetQuantityInput {
  cprcode: ID!
  quantity: Int!
  attribution: BasketAttributionInput = null
}
type Category {
  l1: String
  l2: String
  l3: String
}
type CategoryCount {
  name: String!
  count: Int!
}
type FulfilmentBranch {
  branchCode: ID!
  name: String
  alcoholLicensed: Boolean
  deliveryAvailable: Boolean
  nameTh: String
  lat: Float
  lon: Float
  address: String
  province: String
  postcode: String
  phone: String
  distanceKm: Float
}
input FulfilmentResolveInput {
  lat: Float = null
  lon: Float = null
  postcode: String = null
}
enum FulfilmentType {
  DELIVERY
  PICKUP
}
type GuestSessionPayload {
  token: String
  ownerId: String
  expiresAt: String
  userErrors: [UserError!]!
}
type InventoryLevel {
  cprcode: ID!
  branchCode: ID!
  listable: Boolean!
  sellableQty: Int
  ibCfQty: Int
  qtySource: InventoryQtySource
}
enum InventoryQtySource {
  NEW_IB_VS_STOCK_CV
  IB_CF_QTY
}
"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
"""
scalar JSON @specifiedBy(url: "https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf")
type MerchantEarnings {
  partnerId: ID!
  currency: String!
  royaltyRate: Float!
  orders: Int!
  paidOrders: Int!
  paidSales: Float!
  royaltyAccrued: Float!
  royaltyPending: Float!
  recent: [MerchantOrder!]!
}
type MerchantOrder {
  orderId: ID!
  createdAt: String
  grandTotal: Float!
  paid: Boolean!
  royalty: Royalty
  lineCount: Int!
  orderSource: String
}
type Money {
  amount: Float!
  currency: String!
  branchCode: ID
  source: PriceSource!
type Order {
  orderId: ID!
  ownerId: ID
  branchCode: ID
  grandTotal: Float
  isPaid: Boolean
  specialComment: String
  lines: [OrderLine!]!
  payment: OrderPayment
  shipping: OrderShipping
  status: String
  createdAt: String
  orderSource: String
  sandbox: Boolean
  subTotal: Float
  deliveryFee: Float
  totalDiscount: Float
  paymentLink: PaymentLink
  royalty: Royalty
  fulfilmentStatus: String
  deliveredAt: String
}
type OrderConnection {
  nodes: [Order!]!
  pageInfo: PageInfo!
}
input OrderCreateInput {
  branchCode: ID = null
  specialComment: String = null
  lines: [OrderLineInput!] = null
  shippingType: String! = "PICKUP"
  scheduleMode: String! = "REGULAR"
  address: AddressInput = null
  couponCodes: [String!] = null
}
type OrderLine {
  cprcode: ID!
  productName: String
  quantity: Int!
  price: Float
  rowTotal: Float
}
input OrderLineInput {
  cprcode: ID!
  quantity: Int!
}
type OrderPayload {
  order: Order
  userErrors: [UserError!]!
}
type OrderPayment {
  isPaid: Boolean
  status: String
  grandTotal: Float
  method: String
}
type OrderSchedule {
  mode: String
  dateTime: String
  pickingStatus: String
  deliveryFee: Float
}
type OrderShipping {
  fulfilmentType: FulfilmentType
  schedules: [OrderSchedule!]
}
type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}
type PaymentLinkPayload {
  paymentLink: PaymentLink
  userErrors: [UserError!]!
}
type PaymentPayload {
  payment: PaymentSession
  userErrors: [UserError!]!
}
type PaymentSession {
  orderId: ID!
  amountThb: Float!
  currency: String!
  publicKey: String
  merchantId: String
  sdkUrl: String
  redirectUrl: String
  available: Boolean!
}
input PaymentStartInput {
  orderId: ID!
  basketId: ID = null
  callbackUrl: String = null
}
type PersonalKey {
  keyId: ID!
  label: String!
type PersonalKeyCreated {
  """the whole key — shown once, never again"""
  key: String
  personalKey: PersonalKey
  userErrors: [UserError!]!
}
enum PriceSource {
  BRANCH_FEED
  DETAIL_FALLBACK
}
type Product {
  cprcode: ID!
  nameEn: String
  nameTh: String
  brandEn: String
  sizeDesc: String
  countryEn: String
  barcode: String
  category: Category
  imageUrl: String
  availStore: [ID!]
  price: Money
  inventory: InventoryLevel
}
type ProductConnection {
  nodes: [Product!]!
  pageInfo: PageInfo!
  totalCount: Int
}
input ProductFilter {
  query: String = null
  l1: String = null
  l2: String = null
  l3: String = null
  alcoholOnly: Boolean! = false
  activeOnly: Boolean = null
  onlineOnly: Boolean! = true
  pricedOnly: Boolean! = false
}
type Quote {
  quoteId: ID!
  grandTotal: Float!
  currency: String!
  branchCode: ID
  expiresInSeconds: Int!
  raw: JSON
  subTotal: Float
  deliveryFee: Float
  discountedDeliveryFee: Float
  shippingDiscount: Float
  expressShippingCost: Float
  totalDiscount: Float
  lines: [QuoteLine!]!
  couponCodes: [String!]!
  failedCoupons: JSON
}
input QuoteInput {
  branchCode: ID = null
  lines: [OrderLineInput!] = null
  shippingType: String! = "PICKUP"
  couponCodes: [String!] = null
  scheduleMode: String! = "REGULAR"
  address: AddressInput = null
}
type QuoteLine {
  cprcode: ID!
  productName: String
  quantity: Int!
  price: Float
  rowTotal: Float
  discountedRowTotal: Float
}
type QuotePayload {
  quote: Quote
  userErrors: [UserError!]!
}
type Royalty {
  rate: Float!
  base: Float!
  amount: Float!
  currency: String!
type SearchHit {
  cprcode: ID!
  name: String
  product: Product
}
enum SearchMode {
  AUTOCOMPLETE
  SEMANTIC
}
type UserError {
  code: String!
  message: String!
  field: String
}