1. Features API
Storyous Public APIs
  • Introduction
  • Merchants API
    • Get merchant and all its places
  • Menu API
    • Get a menu tree
    • Get time-based menu
    • Get Remaining amounts of time-based menu
  • Bills API
    • Get list of payment bills
    • Get detail of a payment bill
  • Delivery API
    • Create an order through delivery API
    • Get status of delivery order
  • Deskview API
    • Get list of desks
    • Get list of sections
    • Get desk view of a place
  • Features API
    • {feature}/usage
      • Get feature usage
      • Adjust feature usage
    • Get list of merchants/places with a feature
      GET
  • Hotel accounts integration API
    • Provide list of accounts
    • Write consumed items to hotel account
  • Stocks API
    • Get list of stocks
    • Get list of items
    • Get list of stock ups
    • Get detail of stock up
    • Create new stock up
    • Modify stock up
    • Delete stock up
    • Get list of stock takings
    • Get detail of stock taking
    • Create new stock taking
    • Modify stock taking
    • Delete stock taking
    • Get suppliers
  • Loyalty API
    • Introduction
    • Prepayment
    • Item refunds with credit
    • Get benefit offer
    • Report offer validation error
    • Report benefit usage
    • Get loyalty benefit usages
    • Mark benefit usages as synchronized
  • DataSync
    • Webhook receiving endpoint
      • Receive new or updated records
    • Data domains
      • Stock management
        • Stocks domain
        • StockItemCategories domain
        • StockItems domain
        • StockMovements domain
      • Sales and costs
        • Bills domain
        • BillCosts domain
        • TerminalTransactions domain
        • PaymentTypes domain
        • Loyalty domain
      • Desks
        • DeskSections domain
        • Desks domain
      • Menu
        • ItemCategories domain
        • Items domain
        • PlaceITems domain
      • Merchants
        • Merchants domain
        • Places domain
        • Persons domain
  • Reservations API
    • Create Seated Reservation
    • Reservation Changed Webhook
  • Schemas
    • Schemas
      • Loyalty api
        • BalanceBenefitOfferRequest
        • ThirdPartyLoyaltyOfferRequest
        • LoyaltyOfferValidationError
        • LoyaltyBenefitUsagesPayload
        • BenefitInput
        • PaidItem
        • Applied Benefits
        • PaymentByBalance
        • UsedBalance
        • LoyaltyOfferResponse
        • MenuProductDefinition
        • UsedGeneralDiscount
        • Prepayment
      • Menu-api
        • TemplateItem
        • TemplateItems
        • TemplateBody
        • DayItems
        • SettingsBody
        • TimeLimit
        • SettingsResponse
        • PlacePricing
        • TemplateResponseItem
      • Desk
      • Section
    • Error
    • PlaceStateInterval
    • OkResponse
    • StateInterval
    • AssignInterval
    • PriceLevels
    • ActiveInterval
    • PlaceValues
    • RentalFee
    • InvoiceLine
    • ShortTermRental
    • Terminal
    • MerchantPricing
    • TemplateResponse
    • PayInvoiceResponse
    • ValidationError
  1. Features API

{feature}/usage

Feature usage#

Agreed contract, implementation pending. Schemas and payload examples are attached to the two endpoints.

Endpoints and scope#

Both accept optional query parameter placeId (string, ^[a-f0-9]{24}$). Omit it for merchant features; require it for place features. Empty or repeated values are invalid. Features validates the configured target, place ownership and caller permissions. Wrong scope returns 400. Admin uses the feature's configured target and its authenticated merchant/place context.
Merchant example, shared across all places:
Place example, independent balance and reset date:
The /features service prefix is included. GET has no body. POST uses JSON with action: "consume" or action: "refund"; scope identifiers are not repeated in its body. Authentication is inherited from Features API. POST requires a trusted internalApi backend caller with settings access.

Accounting rules#

AI stock-up uses 300 merchant-shared requests. Consume one per upload submission, regardless of pages/files. Limits and resets are changed only in Configurations.
Consume before work. Only consumed starts new work. Successful work needs no follow-up accounting request.
Refund a known failure using the original request ID and scope. Restore the original quantity once; an old-period refund never increases the new period balance.
Retry uncertain responses with the same ID and payload. Matching consumes return duplicate or refunded; changed quantity/fingerprint returns request_conflict. After a confirmed refund, a fresh attempt uses a new ID. Interrupted work may remain consumed.
Periods advance on demand from original enablement, not first use. Re-enablement preserves the anchor. Treat periodId as opaque; use expectedPeriodId when confirming against a displayed period.

Why fingerprint is required#

requestId identifies the attempt; fingerprint verifies that its input has not changed. Features compares the SHA-256 input hash when the same request ID is reused within the same scope. Matching input and quantity return the existing receipt; changed input or quantity returns request_conflict.
For example, retrying invoice A with its original request ID is safe. Sending invoice B with that same ID must be rejected; otherwise it could be mistaken for a retry and Admin could replay invoice A’s saved result. Features stores the hash, not the original document. The scope lock handles concurrency separately. Refunds need only the original request ID and scope, not a fingerprint.

MongoDB models#

Shared collections in Features. ObjectId and Date are BSON types. Merchant/place IDs keep the existing string representation.

Indexes#

Keep MongoDB's default unique _id indexes. Store placeId: null explicitly for merchant quotas; the scope index is neither sparse nor partial. A quota keeps its ObjectId through resets. Receipts reference that ObjectId and remain unique across periods. No receipt TTL is defined.
Use the existing scope lock and a MongoDB transaction for atomic balance/receipt changes. Indexes prevent duplicate identities; they do not replace atomic balance updates. Public receipts omit storage _id and quotaId. Neither is a URL parameter.
Design and policy details in Confluence
Previous
Get desk view of a place
Next
Get feature usage
Built with