Skip to content

GraphQL API

Vectis exposes a single GraphQL endpoint at /graphql powered by Strawberry (code-first, type-safe). All queries and mutations are composed from module resolvers via multiple inheritance in vectis/core/graphql.py.

Endpoint

Environment URL
Development http://localhost:8000/graphql
Via BFF proxy http://localhost:5174/api/graphql (storefront) or http://localhost:5173/api/graphql (admin)

The Strawberry GraphQL IDE is available at the development URL in the browser.

Authentication

All requests go through the BFF layer. The SvelteKit server attaches headers:

Header Source Purpose
Authorization Bearer {JWT} from Redis session Authenticated user identity
X-Session-ID vectis_cart_session cookie Guest cart tracking
X-Channel-ID Resolved by middleware Channel context (optional)
X-Locale vectis_locale cookie Content translation language
X-Currency vectis_currency cookie Price display currency

Key Queries

Query Description
channelInfo Channel configuration: commerce mode, supported languages/currencies
me Current authenticated user
products(limit, offset) Product catalog with variants
product(id) Single product with full variant/pricing data
resolvePrice(variantId, quantity) Resolved price for a variant respecting hierarchy + currency
myCart Current user/session cart with enriched lines
order(id) / orders(...) Order lookup with lines, tax, shipping, fraud status
accountCommerceSummary(accountId, currency) B2B account rollup: order count, revenue total, average order value, last order time. Counts and sums use orders whose status is not Cancelled or Refunded (same currency label as currency; amounts are from stored order grand_total).
accounts(...) Paginated B2B accounts with filters: search (company, legal name, owner email), status, creditHoldStatus, customerGroupId, taxExempt, currency, riskLevel (use __unset__ for accounts with no risk level), createdFrom / createdTo, updatedFrom / updatedTo, sortBy, sortDir, limit, offset. Returns updatedAt, customerGroup, taxId, limits, etc.
customerGroups All customer groups (name, slug) for admin filters and display
customerGroup(id) Single customer group by ID (for edit form)
accountAdminNotes(accountId, limit, offset, includeArchived) Staff-only notes on a B2B account. Returns { notes, total }. Requires account.update.
quotes(accountId, status, limit, offset) Quote list; returns { quotes, total } (not a bare array)
exchangeRates(baseCurrency) Active exchange rates
discountRules(enabledOnly) Promotion rules
savedPaymentMethods(accountId, locationId) Saved cards for an account, optionally scoped by location
paymentMethods(channelId) Configured payment gateways
paymentTransactions(orderId) Transaction ledger for an order
auditLog(entityType, entityId, limit) Audit trail entries (includes createdAt); when authenticated: requires audit.view. Ordered by created_at descending.
notificationTemplates Registered email templates: code, name, module, subjectTemplate, bodyTemplate, enabled, variables (JSON)
notificationLogs(limit) Recent delivery attempts (template code, recipient, channel, status)
warehouses(search, activeOnly) Warehouse list with optional search/filter; requires inventory.view
stockLevels(warehouseId, productId, search, sortBy, sortDir, limit, offset) Paginated stock levels enriched with SKU/product/variant names; requires inventory.view
stockLevelsForProduct(productId, warehouseId) All variant stock levels for a product (bulk editor); requires inventory.view
stockAdjustmentLog(variantId, warehouseId, limit, offset) Paginated audit trail with user email; requires inventory.view
savedReports Saved report definitions (SavedReport): name, reportType, JSON config, visibility (Decided #82)
storefrontSearchConfig Typesense host, collection, scoped browser key, plus autocomplete flags and limits (autocompleteEnabled, autocompleteMinChars, autocompleteDebounceMs, autocompleteMaxResults) loaded from search.% settings (Decided #105)

Key Mutations

Mutation Description
login(email, password) Authenticate and receive access token
registerCustomer(...) B2C customer registration
addToCart(input) Add variant to cart with price resolution
applyCoupon(code) Apply coupon code to cart
removeCoupon(code) Remove coupon from cart
checkout(input) Full checkout: promotions, shipping, tax, payment, order creation
updateOrderStatus(orderId, status) Transition order state (triggers auto void/refund on cancel)
modifyOrder(orderId, ...) Modify an authorized order: add/remove/update lines with reauthorization
adminCreateOrder(...) Staff: create order directly from line items with saved card charging
adminReleaseFraudHold(orderId, transactionId) Staff: release a transaction held by gateway fraud filters
adminCaptureTransaction(transactionId, amount) Staff: capture an authorized transaction
adminVoidTransaction(transactionId) Staff: void an authorized transaction
adminRefundTransaction(transactionId, amount, lastFour) Staff: refund a captured transaction
adminChargeSavedCard(savedPaymentMethodId, amount, ...) Staff: charge a customer's saved card
addPaymentMethod(...) Save a new card from Accept.js opaque data
deletePaymentMethod(id) Delete a saved card
setDefaultPaymentMethod(id) Set a saved card as default
createPaymentMethod(...) Admin: configure a payment gateway (requires settings.edit when authenticated)
updatePaymentMethod(id, ...) Admin: update gateway configuration (requires settings.edit when authenticated)
setExchangeRate(input) Admin: set currency exchange rate
setAccountPrice(input) Admin: set account-level price override
createCustomerGroup(input) Admin: create customer group. Requires settings.edit.
updateCustomerGroup(id, input) Admin: update customer group name/slug. Requires settings.edit.
deleteCustomerGroup(id) Admin: delete customer group (blocked if accounts/customers reference it). Requires settings.edit.
updateAccount(accountId, input) Admin: update account fields including customerGroupId.
addAccountAdminNote(accountId, body, attachments?) Admin: add staff-only note to account with optional image attachments (JSON array of {url, filename, content_type, size}). Requires account.update.
updateAccountAdminNote(noteId, body?, attachments?) Admin: edit a note's body and/or attachments. Authors can edit within 24 hours; super admins (* permission) can edit any note at any time. Returns AccountNoteType with updatedAt and attachments. Requires account.update.
archiveAccountAdminNote(noteId) Admin: archive a note. Requires account.update.
toggleChannelExtension(...) Admin: enable/disable extension per channel
createProduct(input) When authenticated: requires product.create permission
updateProduct(input) When authenticated: requires product.update permission
createVariant(input) When authenticated: requires product.create permission
createTaxCategory / createTaxRate / updateTaxRate / deleteTaxRate When authenticated: requires settings.edit
createPage / updatePageBlocks When authenticated: requires settings.edit
createSearchSynonym When authenticated: requires settings.edit
registerNotificationTemplate / updateNotificationTemplate / sendNotification When authenticated: requires settings.edit
updateNotificationPreference When authenticated: requires settings.edit; upserts NotificationPreference for a user and category
notificationPreferences(userId) When authenticated: requires settings.edit; lists preferences for the given user
subscribeToRestock(variantId, email) Restock alerts (Decided #84): signed-in uses userId from session; guests must pass email
unsubscribeFromRestock(variantId) Remove restock subscription for the signed-in user (guest email subscriptions require sign-in to manage via API)
createSalesRep / assignSalesRep When authenticated: requires settings.edit
issueStoreCredit(amount, reason, accountId?, customerId?, notes?, locationId?) Issue store credit to a B2B account or B2C customer. Optional locationId scopes to a specific location (B2B only). When authenticated: requires order.update. Records created_by from the authenticated user.
cancelStoreCredit(transactionId, reason) Cancel an active credit transaction. Creates a reversal and decrements the balance. Requires order.update.
redeem_gift_card(code, accountId?, customerId?, userId?, amount?) Redeem a gift card into store credit. Supports B2B (accountId) and B2C (customerId). Derives from session context if neither is provided.
createTag(input: CreateTagInput) Create a tag. Requires settings.edit. Input accepts name, color, and optional applicableEntityTypes: [String] to scope the tag.
updateTag(id, input: UpdateTagInput) Update tag name, color, or applicableEntityTypes. Requires settings.edit. Re-derives slug on name change; rejects duplicate slugs.
deleteTag(id) Delete tag and all its assignments. Requires settings.edit.
assignTag(input: {tagId, entityType, entityId}) Assign a tag to an entity. Requires {entity}.update permission for the given entityType (see Tagging section in conventions.md). assigned_by set from session. Enforces tag scoping: if applicableEntityTypes is set on the tag, the entityType must be in the list.
unassignTag(tagId, entityType, entityId) Remove tag from entity. Same permission gate as assignTag.

TagType Fields

Field Type Description
id ID Tag identifier
name String Tag display name
slug String URL-safe slug auto-derived from name
color String? Hex color for display
applicableEntityTypes [String]? Entity types this tag can be assigned to. null means all types.

Tag Queries

Query Args Returns Description
tags [TagType] All tags (for admin Tags page)
tagsForEntity entityType, entityId [TagType] Tags assigned to a specific entity
tagsForEntityType entityType: String! [TagType] Tags applicable to a given entity type (for tag picker dropdowns). Returns tags where applicableEntityTypes is null OR contains the given type.

Tags on Entity Types

All five entity types expose a tags: [TagType] field:

Type tags resolved via
ProductType Batch-loaded on products() list; single-load on product() detail
OrderType Batch-loaded on orders() list; single-load on order() detail
AccountType Batch-loaded on accounts() list; single-load on account() detail
LocationType Batch-loaded on account() detail (nested locations)
EmployeeType Batch-loaded on account() detail (nested employees)

Tag Filtering on List Queries

Query New arg Behavior
products(tagIds: [Int!]) tagIds Filter products tagged with ANY of the provided tag IDs
orders(tagIds: [Int!]) tagIds Filter orders tagged with ANY of the provided tag IDs
accounts(tagIds: [Int!]) tagIds Filter accounts tagged with ANY of the provided tag IDs

AI Content Generation

Query / Mutation Description
aiProviders List installed AI providers with health status
aiPromptTemplates List all prompt templates (stored DB rows merged with built-in defaults). Returns isBuiltin flag
generateAiContent(useCase, context, providerName?, maxTokens?, temperature?) Generate content using a prompt template. Falls back to built-in defaults when no stored template exists
upsertAiPromptTemplate(useCase, template) Create or update a prompt template
deleteAiPromptTemplate(useCase) Delete a stored template. For built-in use cases, reverts to the default prompt

Inventory (Decided #113)

Mutation Description
createWarehouse(input) Create a new warehouse. Requires inventory.manage.
updateWarehouse(warehouseId, input) Update warehouse fields. Requires inventory.manage.
deactivateWarehouse(warehouseId) Soft-deactivate a warehouse. Requires inventory.manage.
adjustStock(variantId, warehouseId, newQuantity, reason, notes) Set stock to an absolute quantity, writes audit log. Requires inventory.manage.
bulkAdjustStock(input) Batch stock updates for multiple variants. Input includes items: [{variantId, warehouseId, newQuantity}], reason, notes. Requires inventory.manage.
importInventory(items, notes) Import stock from CSV data. Items: [{sku, warehouseCode, quantity}]. Matches by SKU + warehouse code. Requires inventory.manage.

Reporting (Decided #82)

Mutation Description
createSavedReport Persist a named report with reportType and JSON config (e.g. date_from, date_to).
runReport(reportId) Load the saved report, execute ReportExecutionService, return rows as JSON.
exportReport(reportId, format) Same execution; returns CSV as a string when format is csv (other formats rejected until implemented).
createScheduledReport Create a ScheduledReport row (schedule string, recipients, format) linked to a SavedReport.
updateScheduledReport Update schedule and/or enabled on a scheduled report (id argument).

Supported reportType values: sales_summary, product_performance, customer_orders, inventory_levels, tax_collected. Order-based reports honor config.date_from and config.date_to when present.

Payment gateway configuration mutations

createPaymentMethod, updatePaymentMethod, and deletePaymentMethod when removing a configured gateway (PaymentMethod row) require settings.edit when the caller is authenticated. (Customer saved-card deletion may use the same field name depending on schema composition.)

Fulfillment and shipping mutations

Shipping configuration mutations (createShippingZone, updateShippingZone, deleteShippingZone, setZoneMethods, provider/method/box create–update–delete) require the settings.edit permission when the caller is authenticated. Shipment lifecycle mutations (createShipment, shipShipment, deliverShipment) require order.update. The shippingRatesForCheckout query is intentionally unguarded so the storefront can resolve rates without staff permissions.

Store Credit API

Queries

Query Args Returns Description
storeCreditBalance accountId?, customerId?, locationId? StoreCreditBalanceType Balance and transactions for a specific ledger
storeCreditSummary accountId?, customerId? StoreCreditSummaryType All ledgers for an account or customer
myStoreCredit (none — uses session) StoreCreditBalanceType Caller's own credit (storefront use). Uses account_id or customer_id from session context.
customers search?, limit?, offset? [CustomerType] List B2C customers (admin use). Search by name or email.

Types

  • StoreCreditBalanceType: accountId, customerId, locationId, locationName, balance (MoneyType), transactions ([CreditTransactionType])
  • StoreCreditSummaryType: accountId, customerId, ledgers ([StoreCreditBalanceType])
  • CreditTransactionType: id, amount (MoneyType), type, status, reason, referenceType, referenceId, notes, createdAt, createdByName

Checkout Integration

The CheckoutInput accepts storeCreditAmount (String, optional). At checkout the system:

  1. Caps the requested amount at min(requested, balance, grandTotal)
  2. Debits store credit before calling the payment gateway
  3. Charges the remainder to the gateway (or skips it if fully covered)
  4. On gateway failure, compensates by refunding the debited credit back

The OrderType exposes storeCreditApplied (MoneyType) showing how much credit was used.

Checkout Mutation Input

The checkout mutation accepts a comprehensive input:

mutation Checkout($input: CheckoutInput!) {
  checkout(input: $input) {
    id
    orderNumber
    status
    currency
    paymentStatus
    fraudStatus
    subtotal { amount currency }
    discountTotal { amount currency }
    taxTotal { amount currency }
    shippingTotal { amount currency }
    grandTotal { amount currency }
    lines {
      sku
      productName
      quantity
      lineTotal { amount currency }
      taxTotal { amount currency }
      discountAmount { amount currency }
    }
  }
}

Input fields:

Field Type Description
email String Required for guest checkout
poNumber String B2B purchase order reference
acceptPolicy Boolean Terms acceptance
shippingAddress AddressInput Ship-to address
billingAddress AddressInput Bill-to address
shippingCarrier String Selected carrier code
shippingMethodCode String Selected shipping method
paymentMethod String Payment gateway code
paymentData JSON Gateway-specific payload
couponCodes [String] Additional coupon codes to apply at checkout
savedPaymentMethodId Int Use a saved card (CIM profile)
opaqueDataDescriptor String Accept.js token descriptor
opaqueDataValue String Accept.js token value
saveCard Boolean Save the card for future use after checkout
storeCreditAmount String Amount of store credit to apply (Decimal as string). Capped at min(requested, balance, grandTotal).

Order Type

The OrderType includes payment and fraud fields:

Field Type Description
paymentStatus String authorized, captured, held_for_review, voided, refunded, failed
paymentCardBrand String Card network slug from the latest successful charge/authorization (visa, mastercard, amex, …) when the gateway stored it; null if unknown
fraudStatus String null, held_for_review, released, declined
fraudDetails JSON FDS filter names and details when flagged
storeCreditApplied MoneyType Amount of store credit used on this order (split payment). 0 if none.

Money Type

All monetary values use the MoneyType:

type MoneyType {
  amount: String!   # Decimal as string for precision
  currency: String! # ISO 4217 code
}

Admin Cart API (Decided Cart Mgmt #2)

Admin cart operations require cart.view (queries) or cart.edit (mutations) permission.

Queries

Query Args Returns Description
adminCarts channelId, accountId, search, hasLines, sortBy, sortDir, limit, offset AdminCartListResult Paginated cart dashboard
adminCart id AdminCartType Full cart detail with enriched lines
cartSnapshots cartId, limit [CartSnapshotType] Snapshot timeline
cartValidation cartId [CartValidationIssueType] Non-blocking error checking
cartAuditLog cartId, limit [CartAuditEntryType] Audit trail for this cart

Mutations

Mutation Args Description
adminCreateCart channelId, accountId?, locationId?, employeeId?, customerId?, currency? Create a new empty cart
adminAddCartLine cartId, variantId, quantity, managedPrice? Add item with optional managed price
adminUpdateCartLine cartId, lineId, quantity Change quantity
adminRemoveCartLine cartId, lineId Remove item
adminSetManagedPrice cartId, lineId, price? Set/clear managed price override
adminApplyCoupon cartId, code Apply coupon code
adminRemoveCoupon cartId, code Remove coupon code
adminSetCartAddresses cartId, shippingAddressId?, billingAddressId? Update addresses
adminSetCartNotes cartId, notes Set admin notes
adminSetLineNotes cartId, lineId, notes Set per-line admin notes
adminLockCart cartId Acquire editing lock (Decided #92)
adminUnlockCart cartId Release editing lock
adminRestoreCartSnapshot cartId, snapshotId Restore cart to snapshot state

All mutations return AdminCartType with the updated cart state.

Registration (Decided #114)

Queries

Query Args Returns Purpose
registrationForms activeOnly?, channelId? [RegistrationFormType] List registration forms with steps/sections/fields
registrationForm id?, slug? RegistrationFormType Get form by ID or slug (or default)
registrationRules activeOnly? [RegistrationRuleType] List geo-conditional rules
documentTypes activeOnly? [DocumentTypeType] List document types
agreementTemplates activeOnly?, formId? [AgreementTemplateType] List agreement templates
invitationCodes activeOnly? [InvitationCodeType] List invitation codes
registrationSubmissions status?, formId?, limit, offset SubmissionListResult Paginated submissions
registrationSubmission id RegistrationSubmissionType Submission detail with docs/sigs
evaluateRegistrationRules country?, state?, county?, city?, postalCode?, formId? RulesEvaluationType Evaluate rules for a geo location
accountDocuments accountId [DocumentUploadType] Documents for a specific account

Mutations

Mutation Args Description
createRegistrationForm input: CreateRegistrationFormInput Create a new registration form
updateRegistrationForm id, input: UpdateRegistrationFormInput Update form metadata
deleteRegistrationForm id Delete form and all nested structure
saveFormStructure formId, steps: [FormStructureStepInput] Replace full step/section/field tree
createRegistrationRule input: CreateRuleInput Create geo-conditional rule
updateRegistrationRule id, input: UpdateRuleInput Update rule
deleteRegistrationRule id Delete rule
createDocumentType input: CreateDocumentTypeInput Create document type
updateDocumentType id, input: UpdateDocumentTypeInput Update document type
deleteDocumentType id Delete document type
createAgreementTemplate input: CreateAgreementTemplateInput Create agreement
updateAgreementTemplate id, input: UpdateAgreementTemplateInput Update agreement
deleteAgreementTemplate id Delete agreement
createInvitationCode input: CreateInvitationCodeInput Create invitation code
updateInvitationCode id, input: UpdateInvitationCodeInput Update code
deleteInvitationCode id Delete code
reviewDocument input: ReviewDocumentInput Approve/reject uploaded document
submitRegistration input: SubmitRegistrationInput Public: submit registration form
reviewRegistration input: ReviewSubmissionInput Admin: approve/deny/request-docs

Queries

Query Arguments Description
banners activeOnly: Boolean List all banners
banner id: ID! Get single banner
bannersByPlacement placementType: String!, entitySlug: String Get banners for a placement
sliders activeOnly: Boolean List all sliders
slider id: ID! Get single slider with slides

Mutations

Mutation Arguments Description
createBanner input: BannerInput! Create banner
updateBanner id: ID!, input: BannerInput! Update banner
deleteBanner id: ID! Delete banner
createSlider input: SliderInput! Create slider
updateSlider id: ID!, input: SliderInput! Update slider
deleteSlider id: ID! Delete slider and all slides
addSlide sliderId: ID!, input: SlideInput! Add slide to slider
updateSlide id: ID!, input: SlideInput! Update slide
removeSlide id: ID! Remove slide
reorderSlides sliderId: ID!, slideIds: [ID!]! Reorder slides

Tracking & Attribution (Decided #118)

Queries

Query Arguments Description
trackingAnalytics entityType, entityId?, dateFrom?, dateTo? Aggregate analytics
trackingEvents entityType?, entityId?, dateFrom?, dateTo?, limit, offset Paginated event log

Mutations

Mutation Arguments Description
trackEvent eventType, entityType, entityId, pageUrl?, referrerUrl? Record tracking event (public)

Email Campaigns (Decided #115)

Queries

Query Arguments Description
emailCampaigns statusFilter?: String List campaigns
emailCampaign id: ID! Get single campaign

Mutations

Mutation Arguments Description
createEmailCampaign input: EmailCampaignInput! Create campaign
updateEmailCampaign id: ID!, input: EmailCampaignInput! Update campaign
sendEmailCampaign id: ID! Send campaign
cancelEmailCampaign id: ID! Cancel campaign
deleteEmailCampaign id: ID! Delete campaign

Auto-Generated Reference

See Reference for the full auto-generated schema documentation including all types, inputs, queries, and mutations.