Salla Merchant API

RESTful endpoints purpose-built for secure, fast, and easy access to Merchant data. Covers products, orders, customers, branches, brands, categories, coupons, currencies, languages, taxes, shipping zones, shipments, abandoned carts, marketing, and store configuration. All requests use the base URL https://api.salla.dev/admin/v2 and are authenticated with an OAuth 2.0 bearer token issued via Salla Partners.

Salla Merchant API is one of 5 APIs that Salla publishes on the APIs.io network, described by a machine-readable OpenAPI specification.

This API exposes 6 machine-runnable capabilities that can be deployed as REST, MCP, or Agent Skill surfaces via Naftiko and 3 JSON Schema definitions.

Tagged areas include E-Commerce, Merchant, Orders, Products, and Customers. The published artifact set on APIs.io includes API documentation, an OpenAPI specification, a JSON-LD context, sample payloads, 6 Naftiko capability specs, and 3 JSON Schemas.

Documentation

Specifications

Examples

Schemas & Data

Other Resources

OpenAPI Specification

salla-merchant-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Salla Merchant API
  description: |
    RESTful endpoints purpose-built for secure, fast, and easy access to Salla
    Merchant store data. Covers products, orders, customers, branches, brands,
    categories, currencies, languages, coupons, taxes, abandoned carts,
    shipping, shipments, and store configuration.

    All requests use the base URL `https://api.salla.dev/admin/v2` and are
    authenticated with an OAuth 2.0 bearer token issued via the Salla Partners
    Portal.
  version: '2'
  contact:
    name: Salla Developers
    url: https://docs.salla.dev/
    email: [email protected]
  license:
    name: Proprietary
    url: https://salla.com/terms
servers:
- url: https://api.salla.dev/admin/v2
  description: Salla Merchant API production
security:
- OAuth2: []
paths:
  /products:
    get:
      summary: List Products
      operationId: listProducts
      tags:
      - Products
      parameters:
      - name: page
        in: query
        schema: { type: integer }
      - name: per_page
        in: query
        schema: { type: integer }
      - name: keyword
        in: query
        description: Filter products matching a name or SKU value.
        schema: { type: string }
      - name: status
        in: query
        schema: { type: string, enum: [hidden, sale, out] }
      - name: category
        in: query
        schema: { type: string }
      - name: format
        in: query
        description: Use `light` for simplified product data.
        schema: { type: string, enum: [light] }
      responses:
        '200':
          description: Paginated list of products.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ProductList' }
        '401': { $ref: '#/components/responses/Unauthorized' }
    post:
      summary: Create Product
      operationId: createProduct
      tags:
      - Products
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/ProductCreate' }
      responses:
        '201':
          description: Product created.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ProductResponse' }
        '422': { $ref: '#/components/responses/ValidationError' }
  /products/{product_id}:
    parameters:
    - name: product_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Product
      operationId: getProduct
      tags: [Products]
      responses:
        '200':
          description: Product details.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ProductResponse' }
    put:
      summary: Update Product
      operationId: updateProduct
      tags: [Products]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/ProductCreate' }
      responses:
        '200':
          description: Product updated.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ProductResponse' }
    delete:
      summary: Delete Product
      operationId: deleteProduct
      tags: [Products]
      responses:
        '200': { description: Product deleted. }
  /products/{product_id}/skus:
    parameters:
    - name: product_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: List Product SKUs
      operationId: listProductSkus
      tags: [Products]
      responses:
        '200':
          description: List of SKUs for the product.
          content:
            application/json: { schema: { type: object } }
  /products/options:
    post:
      summary: Create Product Option
      operationId: createProductOption
      tags: [Products]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Option created. }
  /products/quantities:
    put:
      summary: Update Product Quantities
      operationId: updateProductQuantities
      tags: [Products]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '200': { description: Quantities updated. }
  /orders:
    get:
      summary: List Orders
      operationId: listOrders
      tags: [Orders]
      parameters:
      - name: page
        in: query
        schema: { type: integer }
      - name: per_page
        in: query
        schema: { type: integer }
      - name: status
        in: query
        schema: { type: string }
      - name: from_date
        in: query
        schema: { type: string, format: date }
      - name: to_date
        in: query
        schema: { type: string, format: date }
      responses:
        '200':
          description: Paginated list of orders.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/OrderList' }
  /orders/{order_id}:
    parameters:
    - name: order_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Order Details
      operationId: getOrder
      tags: [Orders]
      parameters:
      - name: format
        in: query
        description: Set to `light` to exclude shipments, items, pickup branch, and customer groups.
        schema: { type: string, enum: [light] }
      responses:
        '200':
          description: Order details.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/OrderResponse' }
        '404': { $ref: '#/components/responses/NotFound' }
    put:
      summary: Update Order
      operationId: updateOrder
      tags: [Orders]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '200':
          description: Order updated.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/OrderResponse' }
  /orders/{order_id}/status:
    parameters:
    - name: order_id
      in: path
      required: true
      schema: { type: integer }
    post:
      summary: Update Order Status
      operationId: updateOrderStatus
      tags: [Orders]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [slug]
              properties:
                slug: { type: string, description: Status slug. }
                note: { type: string }
      responses:
        '200': { description: Order status updated. }
  /orders/{order_id}/histories:
    parameters:
    - name: order_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: List Order Histories
      operationId: listOrderHistories
      tags: [Orders]
      responses:
        '200': { description: Order history entries. }
  /orders/{order_id}/invoices:
    parameters:
    - name: order_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: List Order Invoices
      operationId: listOrderInvoices
      tags: [Orders]
      responses:
        '200': { description: Order invoices. }
  /orders/{order_id}/items:
    parameters:
    - name: order_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: List Order Items
      operationId: listOrderItems
      tags: [Orders]
      responses:
        '200': { description: Order items. }
  /abandoned-carts:
    get:
      summary: List Abandoned Carts
      operationId: listAbandonedCarts
      tags: [Carts]
      responses:
        '200': { description: Abandoned cart list. }
  /customers:
    get:
      summary: List Customers
      operationId: listCustomers
      tags: [Customers]
      parameters:
      - name: page
        in: query
        schema: { type: integer }
      - name: per_page
        in: query
        schema: { type: integer }
      responses:
        '200':
          description: Paginated list of customers.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CustomerList' }
    post:
      summary: Create Customer
      operationId: createCustomer
      tags: [Customers]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CustomerCreate' }
      responses:
        '201':
          description: Customer created.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CustomerResponse' }
  /customers/{customer_id}:
    parameters:
    - name: customer_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Customer
      operationId: getCustomer
      tags: [Customers]
      responses:
        '200':
          description: Customer details.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CustomerResponse' }
    put:
      summary: Update Customer
      operationId: updateCustomer
      tags: [Customers]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CustomerCreate' }
      responses:
        '200':
          description: Customer updated.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CustomerResponse' }
  /categories:
    get:
      summary: List Categories
      operationId: listCategories
      tags: [Categories]
      responses:
        '200': { description: Category list. }
    post:
      summary: Create Category
      operationId: createCategory
      tags: [Categories]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Category created. }
  /categories/{category_id}:
    parameters:
    - name: category_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Category
      operationId: getCategory
      tags: [Categories]
      responses:
        '200': { description: Category details. }
    put:
      summary: Update Category
      operationId: updateCategory
      tags: [Categories]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '200': { description: Category updated. }
  /brands:
    get:
      summary: List Brands
      operationId: listBrands
      tags: [Brands]
      responses:
        '200': { description: Brand list. }
    post:
      summary: Create Brand
      operationId: createBrand
      tags: [Brands]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Brand created. }
  /brands/{brand_id}:
    parameters:
    - name: brand_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Brand
      operationId: getBrand
      tags: [Brands]
      responses:
        '200': { description: Brand details. }
    put:
      summary: Update Brand
      operationId: updateBrand
      tags: [Brands]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '200': { description: Brand updated. }
    delete:
      summary: Delete Brand
      operationId: deleteBrand
      tags: [Brands]
      responses:
        '200': { description: Brand deleted. }
  /branches:
    get:
      summary: List Store Branches
      operationId: listBranches
      tags: [Branches]
      responses:
        '200': { description: Branch list. }
    post:
      summary: Create Store Branch
      operationId: createBranch
      tags: [Branches]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Branch created. }
  /branches/{branch_id}:
    parameters:
    - name: branch_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Store Branch
      operationId: getBranch
      tags: [Branches]
      responses:
        '200': { description: Branch details. }
  /coupons:
    get:
      summary: List Coupons
      operationId: listCoupons
      tags: [Coupons]
      responses:
        '200': { description: Coupon list. }
    post:
      summary: Create Coupon
      operationId: createCoupon
      tags: [Coupons]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Coupon created. }
  /currencies:
    get:
      summary: List Currencies
      operationId: listCurrencies
      tags: [Localization]
      responses:
        '200': { description: Currency list. }
  /languages:
    get:
      summary: List Languages
      operationId: listLanguages
      tags: [Localization]
      responses:
        '200': { description: Language list. }
  /countries:
    get:
      summary: List Countries
      operationId: listCountries
      tags: [Localization]
      responses:
        '200': { description: Country list. }
  /countries/{country_id}:
    parameters:
    - name: country_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Country Details
      operationId: getCountry
      tags: [Localization]
      responses:
        '200': { description: Country details. }
  /taxes:
    get:
      summary: List Taxes
      operationId: listTaxes
      tags: [Financial]
      responses:
        '200': { description: Tax list. }
    post:
      summary: Create Tax
      operationId: createTax
      tags: [Financial]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Tax created. }
  /transactions:
    get:
      summary: List Transactions
      operationId: listTransactions
      tags: [Financial]
      responses:
        '200': { description: Transaction list. }
  /shipments:
    get:
      summary: List Shipments
      operationId: listShipments
      tags: [Shipping]
      responses:
        '200': { description: Shipment list. }
    post:
      summary: Create Shipment
      operationId: createShipment
      tags: [Shipping]
      requestBody:
        required: true
        content:
          application/json: { schema: { type: object } }
      responses:
        '201': { description: Shipment created. }
  /shipments/{shipment_id}:
    parameters:
    - name: shipment_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Shipment Details
      operationId: getShipment
      tags: [Shipping]
      responses:
        '200': { description: Shipment details. }
  /shipping/zones:
    get:
      summary: List Shipping Zones
      operationId: listShippingZones
      tags: [Shipping]
      responses:
        '200': { description: Shipping zone list. }
  /shipping/zones/{zone_id}:
    parameters:
    - name: zone_id
      in: path
      required: true
      schema: { type: integer }
    get:
      summary: Get Shipping Zone Details
      operationId: getShippingZone
      tags: [Shipping]
      responses:
        '200': { description: Shipping zone details. }
  /shipping/companies:
    get:
      summary: List Shipping Companies
      operationId: listShippingCompanies
      tags: [Shipping]
      responses:
        '200': { description: Shipping company list. }
  /webhooks/subscribe:
    post:
      summary: Subscribe Webhook
      operationId: subscribeWebhook
      tags: [Webhooks]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, event, url]
              properties:
                name: { type: string }
                event: { type: string, description: Webhook event name (e.g. `order.created`). }
                url: { type: string, format: uri }
                version: { type: integer }
                rule: { type: string, description: Optional conditional rule. }
                headers:
                  type: array
                  items: { type: object }
                security_strategy: { type: string, enum: [signature, token] }
      responses:
        '201': { description: Webhook subscription created. }
  /webhooks/subscriptions:
    get:
      summary: List Webhook Subscriptions
      operationId: listWebhookSubscriptions
      tags: [Webhooks]
      responses:
        '200': { description: Webhook subscriptions. }
  /webhooks/unsubscribe/{subscription_id}:
    parameters:
    - name: subscription_id
      in: path
      required: true
      schema: { type: integer }
    delete:
      summary: Unsubscribe Webhook
      operationId: unsubscribeWebhook
      tags: [Webhooks]
      responses:
        '200': { description: Webhook subscription deleted. }
  /store/info:
    get:
      summary: Get Store Info
      operationId: getStoreInfo
      tags: [Store]
      responses:
        '200': { description: Store information. }
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://accounts.salla.sa/oauth2/auth
          tokenUrl: https://accounts.salla.sa/oauth2/token
          refreshUrl: https://accounts.salla.sa/oauth2/token
          scopes:
            offline_access: Required to receive a refresh token.
            orders.read: Read orders.
            orders.read_write: Read and write orders.
            products.read: Read products.
            products.read_write: Read and write products.
            customers.read: Read customers.
            customers.read_write: Read and write customers.
            settings.read: Read store settings.
            webhooks.read_write: Manage webhook subscriptions.
  responses:
    Unauthorized:
      description: Invalid or missing access token.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    ValidationError:
      description: Request validation failed.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
  schemas:
    Money:
      type: object
      properties:
        amount: { type: number }
        currency: { type: string, example: SAR }
    Pagination:
      type: object
      properties:
        count: { type: integer }
        current: { type: integer }
        next: { type: string, nullable: true }
    Image:
      type: object
      properties:
        id: { type: integer }
        original: { type: string, format: uri }
        thumbnail: { type: string, format: uri }
        alt: { type: string }
        sort: { type: integer }
    Product:
      type: object
      properties:
        id: { type: integer }
        name: { type: string }
        sku: { type: string }
        mpn: { type: string }
        gtin: { type: string }
        type: { type: string, enum: [product, service, group_products, codes, digital, food, booking, donating] }
        status: { type: string, enum: [sale, out, hidden, deleted] }
        price: { $ref: '#/components/schemas/Money' }
        sale_price: { $ref: '#/components/schemas/Money' }
        cost_price: { $ref: '#/components/schemas/Money' }
        quantity: { type: integer }
        description: { type: string }
        url: { type: string, format: uri }
        images:
          type: array
          items: { $ref: '#/components/schemas/Image' }
        categories:
          type: array
          items: { type: integer }
        brand_id: { type: integer }
        tags:
          type: array
          items: { type: string }
        updated_at: { type: string, format: date-time }
    ProductCreate:
      type: object
      required: [name, price, product_type]
      properties:
        name: { type: string }
        price: { type: number }
        product_type: { type: string, enum: [product, service, group_products, codes, digital, food, booking, donating] }
        status: { type: string, enum: [sale, out, hidden, deleted] }
        quantity: { type: integer }
        description: { type: string }
        categories:
          type: array
          items: { type: integer }
        sale_price: { type: number }
        cost_price: { type: number }
        sale_start: { type: string, format: date-time }
        sale_end: { type: string, format: date-time }
        sku: { type: string }
        mpn: { type: string }
        gtin: { type: string }
        brand_id: { type: integer }
        tags:
          type: array
          items: { type: string }
        images:
          type: array
          items: { $ref: '#/components/schemas/Image' }
        options:
          type: array
          items: { type: object }
        metadata_title: { type: string }
        metadata_description: { type: string }
        metadata_url: { type: string }
    ProductResponse:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        data: { $ref: '#/components/schemas/Product' }
    ProductList:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        data:
          type: array
          items: { $ref: '#/components/schemas/Product' }
        pagination: { $ref: '#/components/schemas/Pagination' }
    Customer:
      type: object
      properties:
        id: { type: integer }
        first_name: { type: string }
        last_name: { type: string }
        mobile: { type: string }
        mobile_code: { type: string }
        email: { type: string, format: email }
        gender: { type: string, enum: [male, female] }
        birthday: { type: string, format: date }
        avatar: { type: string, format: uri }
        city: { type: string }
        country: { type: string }
        currency: { type: string }
        updated_at: { type: string, format: date-time }
    CustomerCreate:
      type: object
      required: [first_name, mobile, mobile_code]
      properties:
        first_name: { type: string }
        last_name: { type: string }
        mobile: { type: string }
        mobile_code: { type: string }
        email: { type: string, format: email }
        gender: { type: string, enum: [male, female] }
        birthday: { type: string, format: date }
        city: { type: string }
        country: { type: string }
        groups:
          type: array
          items: { type: integer }
    CustomerResponse:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        data: { $ref: '#/components/schemas/Customer' }
    CustomerList:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        data:
          type: array
          items: { $ref: '#/components/schemas/Customer' }
        pagination: { $ref: '#/components/schemas/Pagination' }
    Order:
      type: object
      properties:
        id: { type: integer }
        reference_id: { type: integer }
        urls: { type: object }
        date:
          type: object
          properties:
            date: { type: string, format: date-time }
            timezone: { type: string }
        source: { type: string }
        status:
          type: object
          properties:
            id: { type: integer }
            name: { type: string }
            slug: { type: string }
            customized: { type: object }
        can_cancel: { type: boolean }
        can_reorder: { type: boolean }
        is_pending_payment: { type: boolean }
        payment_method: { type: string }
        amounts:
          type: object
          properties:
            sub_total: { $ref: '#/components/schemas/Money' }
            shipping_cost: { $ref: '#/components/schemas/Money' }
            tax: { $ref: '#/components/schemas/Money' }
            discounts: { $ref: '#/components/schemas/Money' }
            total: { $ref: '#/components/schemas/Money' }
        shipping: { type: object }
        shipments:
          type: array
          items: { type: object }
        items:
          type: array
          items: { type: object }
        total_weight: { type: number }
        currency: { type: string }
        customer: { $ref: '#/components/schemas/Customer' }
    OrderResponse:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        data: { $ref: '#/components/schemas/Order' }
    OrderList:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        data:
          type: array
          items: { $ref: '#/components/schemas/Order' }
        pagination: { $ref: '#/components/schemas/Pagination' }
    Error:
      type: object
      properties:
        status: { type: integer }
        success: { type: boolean }
        error:
          type: object
          properties:
            code: { type: string }
            message: { type: string }
            fields: { type: object }