Backend API

Some models have an optional property called secondary_field that determines whether a model can be referenced with a value in the URL other than primary_field (which is always id). All models have a primary_field (id) while only the following models feature a secondary_field :

Modelsecondary_field value
Carts modelnumber
Categories modelslug
Customers modelemail
Gift Card modelcode
Invoices modelnumber
Orders modelnumber
Pages modelslug
Payments modelnumber
Products modelslug
Purchase Links modelname
Returns modelnumber
Shipments modelnumber

When making an API request, a configuration object with query parameters is passed to customize the request.

Fields

where

object

An object containing criteria to filter results by.

fields

string

Fields to include in the result, as a comma-separated string or an array. Supports dot-notation for nested fields.

sort

string

A string expression used to sort results.

limit

int

A number indicating the max number of results to return up to 1000.

limit_count

int

Limits how many records are examined when counting a large collection. Values below 1000 are ignored.

page

int

A number indicating which page of results to return.

skip

int

Number of records to skip, overriding the offset normally computed from page and limit.

window

int

Number of entries in the pages map of a paginated result. Defaults to the total page count.

search

string

A string to search and filter results by.

expand

string

A string or array of fields to expand in the result.

include

object

An object with additional queries to include as fields in the result.

group

object

Simplified aggregation with accumulator and date operators. See the Aggregation article.

aggregate

array of object

Complete MongoDB aggregation pipeline. See the Aggregation article.

Use the where parameter to filter results by field values. Swell offers native support for many MongoDB Query Operators, and you can combine multiple fields and operators together.

Top-level query parameters that aren't reserved are treated as filters automatically—?active=true is equivalent to where[active]=true.

These operators are used to filter results based on the values of certain fields, with matching based on existence, data type, regex evaluation, equality, and greater/less than comparisons.

NameDescription
$eqMatches values that are equal to a specified value.
$neMatches values that are not equal to a specified value.
$gtMatches values that are greater than a specified value.
$gteMatches values that are greater than or equal to a specified value.
$ltMatches values that are less than a specified value.
$lteMatches values that are less than or equal to a specified value.
$inMatches any of the values specified in an array.
$ninMatches none of the values specified in an array.
$regexSelects records where values match a specified regular expression.
$typeMatches records if a field is of a specified type.
$existsMatches records that have a specified field defined.
Comparison and evaluation operator examples
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

// Find products on sale
await swell.get('/products', {
  where: { 
    sale: true
  }
});

// Find products with price above $10
await swell.get('/products', {
  where: { 
    price: { $gt: 10 }
  }
});

// Find products with price of $10 or above
await swell.get('/products', {
  where: { 
    price: { $gte: 10 }
  }
});

// Find products with price below $50
await swell.get('/products', {
  where: { 
    price: { $lt: 50 }
  }
});

// Find products with price of $50 or less
await swell.get('/products', {
  where: { 
    price: { $lte: 50 }
  }
});

// Find products with price between $10 and $50
await swell.get('/products', {
  where: { 
    price: { $gte: 10, $lte: 20 }
  }
});

// Find products with a material attribute of 'Silver', 'Gold', or 'Titanium'
await swell.get('/products', {
  where: { 
    'attributes.material': { $in: ['Silver', 'Gold', 'Titanium'] }
  }
});

// Find products without a material attribute of 'Polyester' or 'Nylon'
await swell.get('/products', {
  where: { 
    'attributes.material': { $nin: ['Polyester', 'Nylon'] }
  }
});

// Find products that contain the word 'chair' in the name, ignoring case
await swell.get('/products', {
  where: {
    name: { $regex: 'chair', $options: 'i' }
  }
});

// Find products with a subscription purchase option
await swell.get('/products', {
  where: {
    'purchase_options.subscription': { $exists: true }
  }
});

// Find products with a SKU string defined
await swell.get('/products', {
  where: {
    sku: { $type: 'string' }
  }
});

Logical operators are used to define multiple conditions in a query with logical evaluations. By default, Swell parses multiple attributes in a where object with the $and operator, so you don’t need to explicitly use this unless your query also requires another type of logical operator.

NameDescription
$andJoins query clauses with a logical AND operation.
$orJoins query clauses with a logical OR operation.
$norJoins query clauses with a logical NOR returns all records that fail to match both clauses.
$notInverts the effect of an operator expression on a single field.
Logical operator examples
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

// Find orders created between July 1st, 2022 and June 30th, 2023
await swell.get('/orders', {
  where: {
    $and: [
      { date_created: { $gt: '2022-07-01T00:00:00Z' }},
      { date_created: { $lt: '2023-06-30T00:00:00Z' }}
    ]
  }
});

// This shorthand syntax also works
await swell.get('/orders', {
  where: {
    date_created: { $gt: '2022-07-01T00:00:00Z', $lt: '2023-06-30T00:00:00Z' }
  }
});

// Find active products with a stock level below 10
await swell.get('/products', {
  where: {
    $and: [
      { stock_level: { $lt: 10 }},
      { active: true},
    ]
  },
});

// This shorthand syntax also works
await swell.get('/products', {
  where: {
    stock_level: { $lt: 10 },
    active: true,
  },
});

// Find products with a material attribute of 'Silver' and a price under $100.
await swell.get('/products', {
  where: {
    $and: [
      { 'attributes.material': 'Silver' },
      { price: { $lt: 100 }}
    ] 
  }
});

// Find products that are on sale or have a price under $50.
await swell.get('/products', {
  where: {
    $or: [
      { sale: true }, 
      { price: { $lt: 50 }}
    ]
  }
});

// Find orders which are not delivered, not paid, and not cancelled
await swell.get('/orders', {
  where: {
    $nor: [
      { delivered: true },
      { paid: true },
      { status: 'cancelled' }
    ]
  }
});

Array operators are used to query and update records based on items in an array field.

NameDescription
$allMatches arrays that contain all elements specified in the query.
$elemMatchSelects records if element in the array field matches all the specified $elemMatch conditions.
$sizeSelects records if the array field is a specified size.
Array operator examples
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

// Find products with the tags "consumable" and "organic"
await swell.get('/products', {
  where: {
    tags: { $all: ['consumable', 'organic'] }
  }
});

// Find orders that have a specific coupon applied
await swell.get('/orders', {
  where: {
    discounts: {
      $elemMatch: {
        source_id: '634701a8d394db00135df1bc'
      }
    }
  }
});

// Find orders that have a specific promotion applied
await swell.get('/orders', {
  where: {
    discounts: {
      $elemMatch: {
        type: 'promo-62bc63e193cb7c0019423b6e'
      }
    }
  }
});

// Find orders that include two particular products
await swell.get('/orders', {
  where: {
    items: {
      $all: [
        { $elemMatch: { product_id: '628ba6011869c10019b41f70' }},
        { $elemMatch: { product_id: '628ba442499bba0019b1a96d' }}
      ]
    }
  }
});

// Find orders that include either of two particular products as a subscription
await swell.get('/orders', {
  where: {
    items: {
      $elemMatch: {
        product_id: {
          $in: [ '62b1e30767145000197b2bbf', '62b1dfc4d9dce40019a65797' ]
        },
        'purchase_option.type': 'subscription'
      }
    }
  }
});

// Find orders that only have one item
await swell.get('/orders', {
  where: {
    items: { $size: 1 }
  }
});

Use the sort parameter to sort results. The format consists of <field> <direction>. Direction is recognized as a case-insensitive word like ascending and descending, or as abbreviated asc and desc.

You can combine multiple sort fields in a single comma-separated string, with the first taking precedence in order. The sort value must be a string—array values are ignored.

By default, list results are sorted by id desc (newest first). Any direction word that doesn't start with desc is treated as ascending.

Example query using sort
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/products', {
  sort: 'name asc', // or desc
});

Use the limit parameter to determine how many records should be returned in a result, up to 1000. Defaults to 15. Optionally use in combination with page to perform pagination.

Example query using limit
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/products', {
  limit: 100,
});

Use the page parameter to determine which page of results to return, relative to the default or specified limit. Defaults to 1.

Use skip to offset results directly—when set, it overrides the offset normally computed as (page - 1) × limit.

Two special values are supported: page=all removes the limit and returns all matching records in one response, and page=false disables pagination entirely, returning a plain array of records without the usual response envelope.

Paginated responses include count (total matching records), results, page, limit, page_count, and a pages map with the start and end record numbers of each page. Use window to control how many entries the pages map contains—it defaults to the total page count.

{
  "count": 42,
  "results": [
    { "...": "..." }
  ],
  "page": 2,
  "limit": 15,
  "page_count": 3,
  "pages": {
    "1": { "start": 1, "end": 15 },
    "2": { "start": 16, "end": 30 },
    "3": { "start": 31, "end": 42 }
  }
}
Example query using page
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/products', {
  page: 2,
});

Use the search parameter to perform a text search on a model's searchable fields. This is a basic implementation using case-insensitive regular expressions: each word in the query matches as a substring, and all words must match within the same field. For example, searching blue shirts matches records where a single searchable field contains both "blue" and "shirt"—including partial words, so "shirt" also matches "t-shirts". Wrap a phrase in double quotes to match it exactly, including spaces.

The models below define dedicated search fields. All other models are searched across every string field, including fields nested in objects and arrays.

For building a user-facing store search experience, we recommend using Algolia, Typesense, or Meilisearch as they provide far more powerful and customizable search features.

ModelSearchable fields
/accountsname, email, phone, vat_number, notes
/productsname, slug, sku
/products:variantsname, sku
/cartsnumber, billing.name, shipping.name
/ordersnumber, billing.name, shipping.name
/categoriesname, slug
/purchaselinksname
/shipmentsid, order_id, tracking_code, packages.tracking_code, destination.name, destination.address1
/returnsid, order_id, tracking_code, origin.name, origin.address1
Example query using search
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/products', {
  search: 'blue shirts',
});

Expanding allows you to include related records as defined by link or collection fields. For example, in the cart model, items are linked to a product with the product field which means they aren't automatically included in the result when retrieving a cart. Since the item product is nested in a list of objects, you would use dot-notation to specify the path to the expandable field.

When the expandable field refers to many records, you may want to specify a limit to include more than the default limit, which is 5. To do that for example, use the format variants:50 with the field name and limit separated by :.

When retrieving a list of results, expand will be performed on all records in the result set.

Expand paths can be at most 5 levels deep—deeper queries return an error.

Example query using expand
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/carts/{id}', {
  id: '5407e0929fe97f9d4c712a5e',
  expand: [
    'items.product',
    'items.variant',
  ],
});
Response
{
  "id": "5407e0929fe97f9d4c712a5e",
  "items": [
    {
      "id": "5407e0929fe97f9d4c712a5f",
      "product_id": "5407e0929fe97f9d4c712a5g",
      "product": {
        "name": "Example product",
        ...
      }
    },
    {...}
  ],
  ...
}

Use the include parameter to include results in a query that may or may not be related to the records being retrieved. For example, when you know there's a need to retrieve two similar records at a time in order to reduce the number of API calls a page would need.

Use include.params to specify relative values to the records returned by the main query. The actual field values will be substituted by the API. Use include.data to specify literal values for filtering the included result.

An include can also define a conditions object evaluated against each parent record—the included query only runs for records that match.

→ See the Advanced queries guide for a worked example using include with params and data.

Example query using `include`
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/orders/{id}', {
  id: '5407e0929fe97f9d4c712a5f',
  include: {
    fulfilled_giftcards: {
      url: '/giftcards',
      params: {
        order_id: 'id',
      },
      data: {
        balance: { $gt: 0 },
      },
    },
  },
});
Response
{
  "id": "5407e0929fe97f9d4c712a5f",
  "fulfilled_giftcards": [
    {
      "id": "5407e0929fe97f9d4c712a5g",
      "balance": 25
    },
    {...}
  ],
  ...
}