Neon Commerce Storefront API

The Storefront API from Neon Commerce — 9 operation(s) for storefront.

OpenAPI Specification

neon-commerce-storefront-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Account Storefront API
  description: The Account API is used for managing player accounts.
  version: '1'
servers:
- url: https://api.neonpay.com
security:
- GlobalApiKey: []
tags:
- name: Storefront
paths:
  /storefront/items:
    post:
      summary: Create items
      operationId: createStorefrontItems
      description: 'Create items. Read more about inventory setup [here](https://neonpay.readme.io/docs/offers).

        If any operation fails, the error is returned and all changes are reverted.

        '
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/Item'
      responses:
        '201':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/offer-groups:
    post:
      summary: Create an offer group
      description: 'Offer groups are used to group offers in the storefront. Read more about inventory setup [here](https://neonpay.readme.io/docs/offers).

        This operation takes a list of offer groups and adds them to your existing offer groups. If any operation fails, all changes are reverted and the error is returned.

        '
      operationId: createStorefrontOfferGroups
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/OfferGroup'
      responses:
        '201':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/offers:
    post:
      summary: Create offers
      operationId: createStorefrontOffers
      description: 'An offer is the resource that players purchase on the storefront. Read more about inventory setup [here](https://neonpay.readme.io/docs/offers).

        This operation takes a list of offer objects and adds them to your existing offers. If any operation fails, all changes are reverted and the error is returned.

        '
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/Offer'
      responses:
        '201':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    get:
      summary: Get offers
      operationId: getStorefrontOffers
      description: Get a paginated list of offers.
      parameters:
      - in: query
        allowReserved: true
        name: limit
        required: false
        schema:
          type: integer
          default: 20
          minimum: 1
          maximum: 100
      - in: query
        allowReserved: true
        name: startingAfter
        required: false
        schema:
          type: string
          description: 'A cursor for use in pagination. An offer SKU that defines your place in the list of offers. It''ll fetch the next page of the list.

            '
      - in: query
        allowReserved: true
        name: endingBefore
        required: false
        schema:
          type: string
          description: 'A cursor for use in pagination. An offer SKU that defines your place in the list of offers. It''ll fetch the previous page of the list.

            '
      responses:
        '200':
          description: Offers retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                - links
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Offer'
                  links:
                    type: object
                    required:
                    - previous
                    - next
                    properties:
                      previous:
                        type:
                        - string
                        - 'null'
                        description: 'Link to paginate to the previous page of the list. If null, there is no previous page.

                          '
                      next:
                        type:
                        - string
                        - 'null'
                        description: 'Link to paginate to the next page of the list. If null, there is no next page.

                          '
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/item/{code}:
    delete:
      summary: Delete an item
      operationId: deleteStorefrontItem
      description: Delete an item by its code.
      parameters:
      - in: path
        name: code
        required: true
        schema:
          type: string
          example: gem
      responses:
        '200':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    get:
      summary: Get an item by code
      operationId: getStorefrontItem
      description: Get an item by its code.
      parameters:
      - in: path
        name: code
        required: true
        schema:
          type: string
          example: gem
      responses:
        '200':
          description: Item retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Item'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    put:
      summary: Update an item by code
      operationId: updateStorefrontItem
      description: Update an item. This replaces the existing item with the input data.
      parameters:
      - in: path
        name: code
        required: true
        schema:
          type: string
          example: gem
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Item'
      responses:
        '201':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/offer/{sku}:
    delete:
      summary: Delete an offer
      operationId: deleteStorefrontOffer
      description: Delete an offer by its SKU.
      parameters:
      - in: path
        name: sku
        required: true
        schema:
          type: string
          example: 500_GEMS
      responses:
        '200':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
        '409':
          $ref: '#/components/responses/Conflict'
      tags:
      - Storefront
    get:
      summary: Get an offer by SKU
      operationId: getStorefrontOffer
      description: Get an offer by its SKU.
      parameters:
      - in: path
        name: sku
        required: true
        schema:
          type: string
          example: 500_GEMS
      responses:
        '200':
          description: Offer retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Offer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    put:
      summary: Update an offer by SKU
      operationId: updateStorefrontOffer
      description: Update an offer. This replaces the existing offer with the input data.
      parameters:
      - in: path
        name: sku
        required: true
        schema:
          type: string
          example: 500_GEMS
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Offer'
      responses:
        '200':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/offer-group/{code}:
    delete:
      summary: Delete an offer group
      operationId: deleteStorefrontOfferGroup
      description: Delete an offer by its code.
      parameters:
      - in: path
        name: code
        required: true
        schema:
          type: string
          example: promoted
      responses:
        '200':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    get:
      summary: Get an offer group by code
      operationId: getStorefrontOfferGroup
      description: Get an offer group by its code.
      parameters:
      - in: path
        name: code
        required: true
        schema:
          type: string
          example: promoted
      responses:
        '200':
          description: Offer group retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfferGroup'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    put:
      summary: Update an offer group by code
      operationId: updateStorefrontOfferGroup
      description: Update an offer group. This replaces the existing offer group with the input data.
      parameters:
      - in: path
        name: code
        required: true
        schema:
          type: string
          example: promoted
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OfferGroup'
      responses:
        '201':
          description: Empty.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/prices:
    get:
      summary: Get localized pricing by IP address.
      operationId: getRegionalPricingByIpAddress
      security:
      - ClientKey: []
      parameters:
      - in: query
        allowReserved: true
        name: ip
        required: true
        description: The IP address of the user
        schema:
          type: string
      responses:
        '200':
          description: IP address parsed successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - isSupported
                - isFallback
                properties:
                  isSupported:
                    type: boolean
                    description: True if this IP can be served prices (either locally or via Global Store fallback), false otherwise
                  isFallback:
                    type: boolean
                    description: True when prices are served via Global Store fallback (USD) because the country is env-disabled or globally unsupported. Always false when `isSupported` is false or when prices are served locally.
                  prices:
                    type: object
                    description: Map of offer SKU to localized price
                    additionalProperties: true
                  country:
                    type: string
                    description: The country used for pricing (may be "US" if Global Store fallback is applied)
                  currency:
                    type: string
                    description: The currency of the included prices
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
      tags:
      - Storefront
  /storefront/theme:
    get:
      summary: Get a storefront theme
      description: Get a storefront theme
      operationId: getTheme
      responses:
        '201':
          $ref: '#/components/responses/Theme'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
    put:
      summary: Update the theme for a storefront
      description: Programatically update the configuration for a theme
      operationId: updateTheme
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Theme'
      responses:
        '200':
          description: Empty
          content:
            application/json:
              schema:
                type: object
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
      tags:
      - Storefront
  /storefront/callbacks:
    post:
      summary: Register a URL to handle events throughout the storefront and checkout flow.
      description: Learn more about callbacks [here](https://neonpay.readme.io/docs/webhooks-and-callbacks).
      operationId: subscribeToCallbacks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - url
              properties:
                url:
                  description: The destination URL for these callbacks
                  type: string
                  format: uri
                  example: https://gameUrl.com/account.getInventory
                secret:
                  description: A shared secret used to sign every callback. If not provided, Neon will generate a secret.
                  type: string
                enabledEvents:
                  description: The set of API calls this URL will handle
                  type: array
                  default:
                  - account.getInventory
                  items:
                    type: string
                    enum:
                    - account.getInventory
                eventVersion:
                  description: The version of schema to be used for calls to this URL
                  default: 1
                  type: number
                hooksToExpire:
                  description: 'Any callback IDs to expire.


                    Only one URL can be registered to listen to events for a specific callback. If you register a new

                    URL, you''ll need to expire the old URLs first. You can do so by passing their IDs here.

                    '
                  type: array
                  items:
                    type: string
                    description: Callback ID to expire
      responses:
        '201':
          description: Callback registered successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - secret
                - ids
                properties:
                  secret:
                    type: string
                    description: The secret used to sign this callback's data, either passed in or generated by Neon
                  ids:
                    type: array
                    description: The created callback IDs
                    items:
                      type: string
                      description: The UUID of the created callback
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
      callbacks:
        account.getInventory:
          '{$request.body#/url}':
            post:
              security: []
              parameters:
              - $ref: '#/components/parameters/NeonSignature'
              - in: header
                name: X-Neon-Webhook-Type
                required: true
                schema:
                  type: string
                  description: The type of this request (`account.getInventory`).
              requestBody:
                content:
                  application/json:
                    schema:
                      type: object
                      description: Request body for event version 1
                      properties:
                        data:
                          type: object
                          description: User-supplied data used to look up an account
                          required:
                          - account
                          properties:
                            account:
                              type: string
                              description: The user's unique account ID
              responses:
                '200':
                  description: The account's purchase limits
                  content:
                    application/json:
                      schema:
                        $ref: '#/components/schemas/PlayerInventory'
                '401':
                  description: No account matching the provided data could be found; Neon will not retry these requests
        account.validate:
          '{$request.body#/url}':
            post:
              security: []
              parameters:
              - $ref: '#/components/parameters/NeonSignature'
              - in: header
                name: X-Neon-Webhook-Type
                required: true
                schema:
                  type: string
                  description: The type of this request (`account.validate`).
              requestBody:
                content:
                  application/json:
                    schema:
                      type: object
                      description: Request body for event version 1
                      properties:
                        data:
                          type: object
                          description: User-supplied data used to look up an account
                          required:
                          - accountId
                          properties:
                            accountId:
                              type: string
                              maxLength: 1000
                              description: The user's unique account ID
              responses:
                '200':
                  description: Additional information about the user's account
                  content:
                    application/json:
                      schema:
                        type: object
                        required:
                        - isValid
                        properties:
                          isValid:
                            type: boolean
                            description: Whether or not this account ID corresponds to a valid account.
                          accountId:
                            type:
                            - string
                            - 'null'
                            description: The corrected or normalized account ID, if available. If provided, this will be used instead of the input account ID for fulfillment.
                          displayName:
                            type:
                            - string
                            - 'null'
                            description: 'The display name for the player. This will be used instead of the `accountId` for display if provided. This can be used when the player ID is not meant to be player-facing. Some common examples are a custom gamertag (e.g. "GreatGamer123"), the player''s name (e.g. "John Smith"), or an email address (e.g. "johnsmith@gmail.com").

                              '
                          metadata:
                            type: object
                            description: 'Additional metadata that you''d like to track alongside events for this user. This data will be included in analytics events and webhooks. It should not include any sensitive or internal data like internal authentication tokens. Common use cases are analytics session IDs or device IDs.

                              '
                            additionalProperties: true
                '401':
                  description: No account matching the provided data could be found; Neon will not retry these requests
      tags:
      - Storefront
components:
  parameters:
    NeonSignature:
      in: header
      name: X-Neon-Digest
      required: true
      schema:
        type: string
        description: 'The signature of this request. The signing key used is returned when the callbacks are generated.

          To verify the signature, convert the request body to a JSON string, compute an HMAC with the SHA-256 hash function using the signing key as the key and the JSONified request body as the message.

          '
  schemas:
    ItemText:
      type: object
      description: A Neon localized text object for an Item. See [here](https://neonpay.readme.io/docs/text-localization) for more details.
      required:
      - nameSingular
      - namePlural
      properties:
        nameSingular:
          type: string
          description: The translated singular form of this item.
          example: gem
        namePlural:
          type: string
          description: The translated plural form of this item.
          example: gems
        description:
          type:
          - string
          - 'null'
          description: A translated description for this item.
    ErrorDetail:
      type: object
      required:
      - source
      - message
      properties:
        source:
          type: string
          description: Specific entity that caused this error
          example: 0.imageFileName
        message:
          type: string
          description: Human readable description of the error for this entity (defined in `source`)
          example: 'No images were found matching the file name: gems.png'
    Offer:
      type: object
      required:
      - sku
      - priceTierCode
      - isTargetedOffer
      - shouldPreviewTargetedOffer
      - shouldHideOfferWhenClaimed
      - groups
      - imageFileName
      - backgroundImageFileName
      - items
      - text
      properties:
        sku:
          type: string
          description: The unique SKU for this item. This SKU is used for API operations, and to identify the offer during fulfillment.
        priceTierCode:
          description: The price tier code for this item. Read more about price tiers [here](https://neonpay.readme.io/docs/pricing).
          type: string
        isTargetedOffer:
          description: Whether the item should only be displayed based on player-specific information (e.g. reaching a certain in-game level).
          type: boolean
          default: false
        shouldPreviewTargetedOffer:
          description: Whether the targeted offer should be displayed if it is not yet unlocked. Only used if `isTargetedOffer` is set to `true`.
          type: boolean
          default: false
        shouldHideOfferWhenClaimed:
          description: Flag to indicate whether the offer should be hidden once it has been claimed.
          type: boolean
          example: true
          default: false
        isHidden:
          description: Flag to indicate whether the offer should be hidden from the storefront.
          type: boolean
          example: false
          default: false
        containsRandomizedContent:
          description: Flag to indicate whether this offer contains randomized content (e.g., loot boxes). Used for jurisdiction-based restrictions.
          type: boolean
          example: false
          default: false
        buttonLayout:
          type:
          - string
          - 'null'
          enum:
          - null
          - ADD_TO_CART
          - BUY_NOW
          - ADD_TO_CART_AND_BUY_NOW
          description: Controls which purchase button(s) are shown on the offer card. Null defaults to add-to-cart behaviour.
        limit:
          description: Number to be used if the offer should be limited to a certain number or purchases per user.
          type:
          - integer
          - 'null'
        timeLimits:
          type: array
          items:
            type: object
            description: Time limits to be set for this offer, if the offer is time-limited.
            required:
            - previewDate
            - startDate
            - endDate
            properties:
              previewDate:
                description: The time (in UTC) at which the item will first be visible on the storefront.
                type:
                - string
                - 'null'
                format: date-time
                example: '2023-06-23T20:00:00.000Z'
              startDate:
                description: The time (in UTC) at which the item will first be available for purchase.
                type:
                - string
                - 'null'
                format: date-time
                example: '2023-06-23T20:00:00.000Z'
              endDate:
                description: The time (in UTC) at which the item will no longer be available for purchase.
                type:
                - string
                - 'null'
                format: date-time
                example: '2023-06-23T20:00:00.000Z'
        groups:
          type: array
          description: Offer group configuration for this offer. Offer groups can be created by calling `POST /storefront/offer-groups`, and must be created prior to calling this endpoint.
          items:
            type: object
            required:
            - code
            - order
            - style
            properties:
              code:
                type: string
                description: The group's code. This is the value of `code` you passed when calling `POST /storefront/groups`.
              order:
                type: number
                description: The priority of this offer within its group. Lower values show up earlier.
              style:
                description: How this item should be rendered. Promoted items are displayed more prominently in their group.
                type: string
                default: default
        imageFileName:
          description: The file name of this offer's image. This is the value of `fileName` you passed in when calling `POST /assets/inventory-images`.
          type:
          - string
          - 'null'
          example: gem-24x24.png
        backgroundImageFileName:
          description: The file name of this offer's background image. This is the value of `fileName` you passed in when calling `POST /assets/inventory-images`.
          type:
          - string
          - 'null'
          example: gem-background.png
        items:
          type: array
          description: The items included in this offer. Items can be created by calling `POST /storefront/items`, and must be created prior to calling this endpoint.
          items:
            type: object
            required:
            - code
            - quantity
            - text
            properties:
              code:
                type: string
                description: The item's code. This is the value of `code` you passed when calling `POST /storefront/items`.
              quantity:
                type: number
                description: The number of this item to be included in this offer.
              originalQuantity:
                type:
                - number
                - 'null'
                description: The number of this item to be included in this offer excluding any bonus amounts (i.e. `originalQuantity = quantity - web bonus`).
              text:
                type: object
                description: Subtitles for this item within the offer in each language your storefront supports. The keys of this object are IETF BCP 47 locale codes, e.g. `en-US`.
                additionalProperties:
                  $ref: '#/components/schemas/OfferItemText'
        text:
          type: object
          description: Text for this offer in each language your storefront supports. The keys of this object are IETF BCP 47 locale codes, e.g. `en-US`.
          additionalProperties:
            $ref: '#/components/schemas/OfferText'
    PlayerInventory:
      type: array
      items:
        type: object
        required:
        - sku
        - purchased
        properties:
          sku:
            type: string
            description: The offer SKU
          purchased:
            type: number
            minimum: 0
            description: The amount of this offer the user has already purchased
          limit:
            type:
            - number
            - 'null'
            minimum: 0
            description: The total number of this offer the user may purchase. If null, there is no limit. If zero, the limit is 0
          startTime:
            anyOf:
            - type:
              - string
              - 'null'
              description: The time from which this restriction should be made effective, if applicable, expressed as an ISO 8601 string
            - type:
              - number
              - 'null'
              description: The time from which this restriction should be made effective, if applicable, expressed in milliseconds since the start of the epoch
          durationInSeconds:
            type:
            - number
            - 'null'
            minimum: 0
            description: The number of seconds after `startTime` for which this restriction should be effective. If not passed, the restriction is indefinitely effective
    OfferGroupText:
      type: object
      description: A Neon localized text object for an Offer Group. See [here](https://neonpay.readme.io/docs/text-localization) for more details.
      properties:
        label:
          type:
          - string
          - 'null'
          description: The translated label for this offer group, e.g. "Gems".
        description:
          type:
          - string
          - 'null'
          description: A translated description for this offer group.
        headerImageFileName:
          type:
          - string
          - 'null'
          example: currency-banner.png
          description: The inventory image file name for this offer group's header image. This image will appear in a storefront as a banner above the offer group.
        subheaderImageFileName:
          type:
          - string
          - 'null'
          example: currency-banner-subheader.png
          description: The inventory image file name for this offer group's subheader image. This image will appear in a storefront as a subheader banner above the offer group.
    Item:
      description: Items are the base unit of any offer, like gems or gold. Offers are made up of items with quantities (e.g. 500 gold).
      type: object
      required:
      - code
      - imageFileName
      - text
      properties:
        code:
          type: string
          description: A unique code for this item. This code is used for all API operations, like adding this item to an offer.
          example: gem
        imageFileName:
          type: string
          description: The file name of this item's image. This is the value of `fileName` you passed in when calling `POST /assets/inventory-images`.
          example: gem-24x24.png
        text:
          description: Names and descriptions for this offer group in each language your storefront supports. The keys of this object are IETF BCP 47 locale codes, e.g. `en-US`.
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ItemText'
    OfferGroup:
 

# --- truncated at 32 KB (45 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/neon-commerce/refs/heads/main/openapi/neon-commerce-storefront-api-openapi.yml