# Shopwaive REST API

The Shopwaive REST API provides programmatic access to Shopwaive data and functionality, allowing developers to build custom features like automatic credit deposits, orders, subscriptions and more

## Headless commerce

Headless commerce on Shopify is enhanced with the Shopwaive REST API, an industry-leading customer credit accounting platform with programmatic access. Here you'll find all the documentation you need to get up and running with your headless site

## Want to jump right in?

Feeling eager to get started? Jump in to the quick start docs and get making your first request:

{% content-ref url="/pages/DdeOtsYAiXYscR6oKtiu" %}
[Quick Start](/quick-start)
{% endcontent-ref %}

## Want to deep dive?

Dive a little deeper and start exploring our REST API documentation to get an idea of everything that's possible with the Shopwaive REST API:

{% content-ref url="/pages/hgeTn2rsRK9VnlNUyAEF" %}
[REST API documentation](/reference/rest-api-documentation)
{% endcontent-ref %}


# Quick Start

With this Quick Start guide, make your first request in just minutes

{% hint style="info" %}
**Tip:** Shopwaive's quick start guide helps developers setup their first request in minutes. Use this guide to locate your API keys and more.
{% endhint %}

## Get your API keys

Your API requests are authenticated with Shopwaive using API keys and access tokens. Any request that doesn't include an API key will return an error.

Within the Shopwaive app, you can access your API keys from clicking the initial avatar at the top right of the topbar to access the Settings menu, then click **Settings** and scroll down to the Shopwaive REST API.

{% hint style="success" %}
**Good to know:** Access tokens should be handled with care and never exposed in unsecured environments. They should never be shared as they provide access to your stores' data.
{% endhint %}

## Make your first request

To make your first request, send an authenticated request to the get customer endpoint. This will fetch a `customer` by email address. Ensure to include the `X-Shopwaive-Access-Token` and `X-Shopwaive-Platform` headers.

{% openapi src="/files/SxAe8b4pp5MX0TU3Y7gs" path="/api/customer/{customer\_email}" method="get" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-19af57f14ff2e60779ae7fff8b31053b665b4756%2Findex.yaml?alt=media)
{% endopenapi %}

Take a look at how you might call this method using our official libraries, or via `curl`:

{% tabs %}
{% tab title="curl" %}

```curl
curl --location 'https://app.shopwaive.com/api/customer/example@gmail.com' \
--header 'X-Shopwaive-Access-Token: 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0' \
--header 'X-Shopwaive-Platform: shopify' \
--header 'Content-Type: application/json' \
--data ''
```

{% endtab %}

{% tab title="Node Axios" %}

```javascript
var axios = require('axios');
var data = '';

var config = {
  method: 'get',
maxBodyLength: Infinity,
  url: 'https://app.shopwaive.com/api/customer/example@gmail.com',
  headers: { 
    'X-Shopwaive-Access-Token': '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0', 
    'X-Shopwaive-Platform': 'shopify', 
    'Content-Type': 'application/json'
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});
```

{% endtab %}

{% tab title="NPM Package" %}

```javascript
var config = {
    headers: {
        "X-Shopwaive-Access-Token": "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6",
        "X-Shopwaive-Platform": "shopify",
        "Content-Type":"application/json"
    }
};

const Shopwaive = require('@shopwaive/credit');
const email = "support@shopwaive.com";

async function getCustomer() {
    return new Promise((resolve, reject) => {
        let data = Shopwaive.getCustomer(config, email);
        resolve(data)
    });
}

getCustomer().then(res => {
    let data = res.data;
    if (data) {
        console.log(res.data);
    }
    console.log(res.status)
    console.log(res.statusText)

})
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("app.shopwaive.com")
payload = ''
headers = {
  'X-Shopwaive-Access-Token': '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0',
  'X-Shopwaive-Platform': 'shopify',
  'Content-Type': 'application/json'
}
conn.request("GET", "/api/customer/example@gmail.com", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}
{% endtabs %}


# REST API documentation

Dive into the specifics of each REST API endpoint, example snippets, and version release notes to setup a sandbox and make your first requests

## 2024-11 Release Notes

### What's new in 2024-11 <a href="#whats-new-in-2024-04" id="whats-new-in-2024-04"></a>

The 2024-11 version of Shopwaive's APIs includes the following highlights:

### Action API <a href="#storefront-api" id="storefront-api"></a>

The <mark style="color:blue;">`GET`</mark> Actions <mark style="color:blue;">`/api/actions`</mark> endpoint is now part of the [Action API](/reference/rest-api-documentation/action-api), a new endpoint that allows developers to search and filter actions beyond the existing single action endpoint /api/action/{action id}. With the new endpoint, search actions by including any combination of query key value pairs `id`,`email`,`created_at_min`, or `created_at_max` appended to the /api/actions request. A maximum of 250 records per request are returned in the response body. [Learn more](/reference/rest-api-documentation/action-api#get-actions-endpoint)

## 2024-05 Release Notes

### What's new in 2024-05 <a href="#whats-new-in-2024-04" id="whats-new-in-2024-04"></a>

The 2024-05 version of Shopwaive's APIs includes the following highlights:

### Customer API <a href="#storefront-api" id="storefront-api"></a>

Response body of Customer API `GET` requests now include an option for returning a customer's orders through the <mark style="color:blue;">`orders`</mark> array by appending <mark style="color:blue;">**?orders=true**</mark> to the request url.

Response body of Customer API `GET` requests now return an abridged version of the customer's full account meta data, and do not include <mark style="color:blue;">`activity`</mark> or <mark style="color:blue;">`orders`</mark> arrays by default. To include these additional arrays in the response body, append optional query parameters <mark style="color:blue;">**?activity=true**</mark> or <mark style="color:blue;">**?orders=true**</mark> to the request url.

The <mark style="color:blue;">`transaction`</mark> field included in the <mark style="color:blue;">`activity`</mark> array and <mark style="color:blue;">`action`</mark> object is deprecated and has been sunset beginning April 1, 2024. Requests to the Customer API should not depend on the field being included in the response body.

<mark style="color:blue;">`expirationdate`</mark> and <mark style="color:blue;">`expires`</mark> fields can now be included in the request body to the Customer API PUT and POST endpoints. Enable multiple expiry dates to create powerful promotional offers that expire on different dates and with their own eligibility rules and requirements.

<mark style="color:blue;">`referralurl`</mark> is now returned if your Referral program is enabled. Learn more about Shopwaive's powerful [Referral program](https://docs.shopwaive.com/shopify/referral-program) for customers and affiliates. If new customers sign up using the referral link, you can choose to reward one or both the referrer and new customer

### Action API <a href="#storefront-api" id="storefront-api"></a>

The [Action API](/reference/rest-api-documentation/action-api) is a new resource available with the 2024-05 release of Shopwaive's REST API. Developers can issue segments of credit with independent expiration and eligibility, and include these offers at Checkout with Shopwaive's Checkout Extension for Shopify Plus. The top-level account balance expiration date, if set, overrides any segment-level credit expiration.

## Overview

The Shopwaive REST API includes the Customer, Order, and Action APIs

## Customer API

Customer API provides developers ability to query, increment, and set customer balances.

{% content-ref url="/pages/jxHQxmtKxdciiLxDXjY5" %}
[Customer API](/reference/rest-api-documentation/customer-api)
{% endcontent-ref %}

## Action API

Action API provides developers ability to query, update expirations and meta data, and delete action properties.

{% content-ref url="/pages/y8ShXE6jJ0ql9YZxKgue" %}
[Action API](/reference/rest-api-documentation/action-api)
{% endcontent-ref %}

## Order API

Create a checkout url link you can direct your customers to with credit applied, and optionally include combined line item discounts.

{% content-ref url="/pages/6LNav5FoIuElrkQq5BDb" %}
[Order API](/reference/rest-api-documentation/order-api)
{% endcontent-ref %}

{% hint style="info" %}
**Good to know:** Developers use the [Order API](/reference/rest-api-documentation/order-api) to create a fully custom checkout experience. With Shopwaive's [Order API](/reference/rest-api-documentation/order-api), you can apply credit to an order, set line items and quantities, and apply discounts to each line item (optional). Use cases include automation of custom invoice creation based on customer credit accounts balances, promos, and account activation requests that include checkout preview links with credit automatically applied.
{% endhint %}


# Customer API

Get customer credit balances; make adjustments based on their actions with the Shopwaive Customer API

## `GET` customer endpoint

Fetch customer account details, including account balance, a ledger of account transactions, and customer orders.

{% openapi src="/files/iyVlr9YZyVLoEURXSiBZ" path="/api/customer/{customer\_email}" method="get" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-8e876e694dc2fc667398f8008d482957721c06f2%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

<table><thead><tr><th width="328.3333333333333">key</th><th>value</th></tr></thead><tbody><tr><td>X-Shopwaive-Access-Token</td><td>Store's platform API key for store (required)</td></tr><tr><td>X-Shopwaive-Platform</td><td>Store's platform (required)</td></tr><tr><td>Content-Type</td><td>Content type</td></tr></tbody></table>

### Response Body

| key            | value                                          |
| -------------- | ---------------------------------------------- |
| status         | Status message                                 |
| customerid     | Customer id associated with store's platform   |
| email          | Customer email address                         |
| balance        | Customer's available balance                   |
| expirationdate | Date of balance expiration                     |
| expires        | True or false boolean string                   |
| activity       | If requested, array of account action objects  |
| orders         | If requested, array of account order objects   |
| offers         | If requested, object of sum and list of offers |
| referralurl    | If available, referral link to earn rewards    |

{% hint style="info" %}
Customer <mark style="color:blue;">`orders`</mark> array is only included in the response body if you append <mark style="color:blue;">**?orders=true**</mark> as a query parameter on the request route url
{% endhint %}

{% hint style="info" %}
The <mark style="color:blue;">`referralurl`</mark> is only returned if your Referral program is enabled. Learn more about Shopwaive's powerful [Referral program](https://docs.shopwaive.com/shopify/referral-program) for customers and affiliates. If new customers sign up using the referral link, you can choose to reward one or both the referrer and new customer
{% endhint %}

### offers {} object

| key   | value                      |
| ----- | -------------------------- |
| total | Sum of all eligible offers |
| items | Array of eligible offers   |

{% hint style="info" %}
Customer <mark style="color:blue;">`offers`</mark> object is only included in the response body if you append <mark style="color:blue;">**?offers=true**</mark> as a query parameter on the request route url
{% endhint %}

### offers.items \[] object

| key             | value                                                                                         |
| --------------- | --------------------------------------------------------------------------------------------- |
| segment\_query  | If defined, customer segment query string i.e. customer\_tags CONTAINS 'FALL2023'             |
| collectionids   | If defined, collection ids available for redemption                                           |
| productids      | If defined, product ids available for redemption                                              |
| media           | If defined, url of media associated with offer                                                |
| amount          | Amount of original offer                                                                      |
| date            | Date item is created or updated                                                               |
| note            | Title of offer                                                                                |
| id              | Action id                                                                                     |
| type            | Type of transaction                                                                           |
| transaction[^1] | Customer's available balance after action                                                     |
| expirationdate  | Date the action amount or balance expires                                                     |
| expires         | True or false boolean string                                                                  |
| orderid         | If defined, reference order id associated with last redemption                                |
| remaining       | If defined, remaining available offer amount (i.e. constrained by previous order transaction) |
| status          | If defined, status of offer (i.e. redeemed, expired, partial)                                 |
| partial\_amount | If defined, remaining available offer amount (i.e. constrained by current available balance)  |
| validity        | Description of time left until expiration                                                     |

{% hint style="info" %} <mark style="color:blue;">`partial_amount`</mark> and <mark style="color:blue;">`remaining`</mark> can be equivalent in value. The edge case when <mark style="color:blue;">`partial_amount`</mark> is less than <mark style="color:blue;">`remaining`</mark> is when a previous order partially reduces the original offer available redemption amount at the same time that a customers available balance is less than <mark style="color:blue;">`remaining`</mark> because of a manual adjustment made to <mark style="color:blue;">`balance`</mark> for example. This means even though a <mark style="color:blue;">`remaining`</mark> amount is still attached to that offer, the customers <mark style="color:blue;">`balance`</mark> is not enough to cover the full remaining offer amount
{% endhint %}

{% hint style="info" %}
The <mark style="color:blue;">`offers`</mark> object conveniently filters the actions array and only returns eligible offers. A comprehensive list of all <mark style="color:blue;">`offers`</mark> including expired and redeemed can be found with other actions in the <mark style="color:blue;">`activity`</mark> array
{% endhint %}

### activity\[] object

| key             | value                                             |
| --------------- | ------------------------------------------------- |
| expirationdate  | Date the action amount or balance expires         |
| expires         | True or false boolean string                      |
| date            | Date of transaction                               |
| id              | Action id                                         |
| note            | Transaction note                                  |
| type            | Type of transaction                               |
| transaction[^1] | Customer's available balance after action         |
| status          | If defined, status string (i.e. expire&#x64;**)** |
| amount          | If defined, amount the balance is incremented     |
| media           | If defined, url of media associated with offer    |

{% hint style="info" %}
Customer <mark style="color:blue;">`activity`</mark> array is only included in the response body if you append <mark style="color:blue;">**?activity=true**</mark> as a query parameter on the request route url
{% endhint %}

{% hint style="info" %}
The <mark style="color:blue;">**expirationdate**</mark> field is only applicable if the <mark style="color:blue;">**expires**</mark> field is equal to <mark style="color:blue;">**true**</mark>. If multiple expiry dates are enabled in Settings, the <mark style="color:blue;">**expirationdate**</mark> may apply to the <mark style="color:blue;">**action**</mark> object defined in the <mark style="color:blue;">**activity**</mark> array if a corresponding <mark style="color:blue;">**amount**</mark> field is defined. See <mark style="color:blue;">**Action API**</mark> for more details
{% endhint %}

## `POST` customer endpoint

Set a customer balance equal to value defined by <mark style="color:blue;">`balance`</mark>

{% openapi src="/files/iyVlr9YZyVLoEURXSiBZ" path="/api/customer" method="post" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-8e876e694dc2fc667398f8008d482957721c06f2%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

| key                      | value                                         |
| ------------------------ | --------------------------------------------- |
| X-Shopwaive-Access-Token | Store's platform API key for store (required) |
| X-Shopwaive-Platform     | Store's platform (required)                   |
| Content-Type             | Content type                                  |

### Request Body

| key               | value                                                                                                                                                                     |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| customer\_email\* | Customer email address                                                                                                                                                    |
| balance\*         | Value to assign to customer available balance                                                                                                                             |
| note              | Description of transaction                                                                                                                                                |
| expirationdate    | Date of balance expiration. Accepted formats include <mark style="color:blue;">`April 21, 2028`</mark> or <mark style="color:blue;">`2028-04-21`</mark> (i.e. YYYY-mm-dd) |
| expires           | True or false boolean string                                                                                                                                              |

### Response Body

| key            | value                                        |
| -------------- | -------------------------------------------- |
| id             | Action id created by request                 |
| status         | Status message                               |
| customerid     | Customer id associated with store's platform |
| email          | Customer email address                       |
| note           | Description of transaction                   |
| previous       | Customer's balance prior to request          |
| balance        | Customer's balance after successful request  |
| expirationdate | Date of balance expiration                   |
| expires        | True or false boolean string                 |

{% hint style="info" %}
**Good to know:** This API method sets customer balance to a predefined decimal value (i.e. independent of locale or currency). Currency is chosen within the store platform.
{% endhint %}

## `PUT` customer endpoint

Increment a customer's existing balance by value defined by <mark style="color:blue;">`amount`</mark> debits are created by negative <mark style="color:blue;">`amount`</mark> values and deposits by positive values.

{% openapi src="/files/iyVlr9YZyVLoEURXSiBZ" path="/api/customer" method="put" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-8e876e694dc2fc667398f8008d482957721c06f2%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

| key                      | value                                         |
| ------------------------ | --------------------------------------------- |
| X-Shopwaive-Access-Token | Store's platform API key for store (required) |
| X-Shopwaive-Platform     | Store's platform (required)                   |
| Content-Type             | Content type                                  |

### Request Body

| key               | value                                                                                                                                                                                                                                                                                                                                |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| customer\_email\* | Customer email address                                                                                                                                                                                                                                                                                                               |
| amount\*          | Value to increment (add or subtract) to customer available balance                                                                                                                                                                                                                                                                   |
| note              | Description of transaction                                                                                                                                                                                                                                                                                                           |
| expirationdate    | Date the incremented amount expires if multiple expiration dates are enabled in Settings. If only single expiration dates are enabled, this date defines the total balance expiration. Accepted formats include <mark style="color:blue;">`April 21, 2028`</mark> or <mark style="color:blue;">`2028-04-21`</mark> (i.e. YYYY-mm-dd) |
| expires           | True or false boolean string                                                                                                                                                                                                                                                                                                         |
| media             | If defined, url of media associated with offer                                                                                                                                                                                                                                                                                       |
| segment\_query    | If defined, customer\_email should be left blank. i.e. customer\_tags CONTAINS 'FALL2023'                                                                                                                                                                                                                                            |
| collectionids     | If defined, collection ids available for redemption                                                                                                                                                                                                                                                                                  |
| productids        | If defined, product ids available for redemption                                                                                                                                                                                                                                                                                     |

### Request Response

| key            | value                                          |
| -------------- | ---------------------------------------------- |
| id             | Action id created by request                   |
| status         | Status message                                 |
| customerid     | Customer id associated with store's platform   |
| email          | Customer email address                         |
| note           | Description of transaction                     |
| previous       | Customer's balance prior to request            |
| transaction    | Value of transaction delta                     |
| balance        | Customer's balance after successful request    |
| expirationdate | Date of balance expiration                     |
| expires        | True or false boolean string                   |
| media          | If defined, url of media associated with offer |

{% hint style="info" %}
**Tip:** `amount` is defined as the total amount to add or subtract to the existing customer balance. Customers that do not yet have a Shopify account are automatically created. To set customer balance to a predefined amount, instead use Customer API [`POST`](#api-customer)
{% endhint %}

## `PUT` bulk customer endpoint

Create bulk offers, vouchers, promotions, or increment a customer's existing balance by value defined by <mark style="color:blue;">`amount`</mark> debits are created by negative <mark style="color:blue;">`amount`</mark> values and deposits by positive values. Use field <mark style="color:blue;">`scheduled`</mark> to schedule a transaction. If you desire to process the transaction imminently, do not include optional field <mark style="color:blue;">`scheduled`</mark> or assign it a string date in the past.

<mark style="color:blue;">`transactions`</mark> is an array of objects that define actions, offers, debits, or credits. Max <mark style="color:blue;">`transactions`</mark> length per request is limited to 1,000. <mark style="color:blue;">`ref_id`</mark> is a convenient optional reference field id for tracking of the offer transaction as needed by other 3rd party CRM, CDP, backend servers, or other integrations. If used in conjunction with [Offers](https://docs.shopwaive.com/shopify/offers), <mark style="color:blue;">`ref_id`</mark> will be attached to the order attributes associated with redemption, viewable in the Shopify admin or via Shopify Orders API requests.

{% hint style="info" %}
To use the bulk endpoint, you must first contact <support@shopwaive.com> to notify us of your interest and we can enable bulk operations on your store
{% endhint %}

{% openapi src="/files/GZJCA4zE3Rl5lnPgUu8q" path="/api/customer/bulk" method="put" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-4e4756d69db16f998ef4daafa4b9bb096244f1ef%2Findex.yaml?alt=media)
{% endopenapi %}

The response body includes <mark style="color:blue;">`scheduled`</mark>, which is the number of transactions scheduled imminently or in the future as defined by the request body. Response body field <mark style="color:blue;">`id`</mark> is the bulk import id to reference status of a pending offer scheduled.

[^1]: deprecated, unstable


# Action API

Get, edit, or delete account actions by id; make updates to expiration dates and meta data for existing actions with the Shopwaive Action API

{% hint style="success" %}
Create multiple promotional credits for the same customer with independent expiration dates or promotional periods with the [Customer API PUT endpoint](/reference/rest-api-documentation/customer-api#increment-customer-endpoint) and then edit, delete, or update expirations and meta data with the [Action API](/reference/rest-api-documentation/action-api)
{% endhint %}

{% hint style="info" %}
When you make debits or deposits to a customers account using the [Customer API PUT endpoint](/reference/rest-api-documentation/customer-api#increment-customer-endpoint) or via [bulk increment import ](https://docs.shopwaive.com/shopify/accounts/import-accounts#increment-balances-using-the-increment-column)in the app, an <mark style="color:blue;">`amount`</mark> field is created for that action. The <mark style="color:blue;">`amount`</mark> field is only created for debits and deposits created using the bulk increment import in the app or the Customer API PUT endpoint
{% endhint %}

{% hint style="info" %}
To create multiple promotional credits for the same customer, enable multiple expiration dates in [Settings](https://docs.shopwaive.com/product-tour/dashboard#settings) and use this guide to get started
{% endhint %}

{% hint style="success" %}
When multiple expirations are enabled from [Settings](https://docs.shopwaive.com/product-tour/dashboard#settings), and if a promotional credit associated with an action expires, then a debit is created on the customer account balance automatically at the time defined by <mark style="color:blue;">`expirationdate`</mark>. The debit transacted on the account balance is equal to the value of the <mark style="color:blue;">`amount`</mark> field of the promotional credit action object. If the account has insufficient funds to transact a debit of <mark style="color:blue;">`amount`</mark> (i.e. customer's available <mark style="color:blue;">`balance`</mark> is less than the previous credited <mark style="color:blue;">`amount`</mark> at the time the action is deleted), then the customer's balance is set equal to 0.00. Customer account balances cannot be negative
{% endhint %}

## `GET` action endpoint

Fetch an action by <mark style="color:blue;">`id`</mark>. When you make a [PUT](/reference/rest-api-documentation/customer-api#adjust-customer-balance) or [POST](/reference/rest-api-documentation/customer-api#set-customer-balance) request to the [Customer API](/reference/rest-api-documentation/customer-api), a reference <mark style="color:blue;">`id`</mark> is provided in the response body, this is equivalent to the url parameter <mark style="color:blue;">`actionid`</mark> required for the [Action API](/reference/rest-api-documentation/action-api) [GET](#get-action) endpoint

{% hint style="info" %}
When you make a [GET](/reference/rest-api-documentation/customer-api#get-customer-account-balance-and-transactions) request to the [Customer API](/reference/rest-api-documentation/customer-api), a reference action <mark style="color:blue;">`id`</mark> is provided for each action in the activity array. If a [GET](#get-action) request to the [Action API](/reference/rest-api-documentation/action-api) returns an <mark style="color:blue;">`amount`</mark> field in the response body, this indicates the action was created using the Customer API [PUT](/reference/rest-api-documentation/customer-api#adjust-customer-balance) or through an [increment bulk import](https://docs.shopwaive.com/shopify/accounts/import-accounts#increment-balances-using-the-increment-column) action in the app
{% endhint %}

{% openapi src="/files/mxvlhEUDXjsAh3H8cIZi" path="/api/action/{actionid}" method="get" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-0354fa630752e18551f1efd51dfe23ccdbad845d%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

<table><thead><tr><th width="328.3333333333333">key</th><th>value</th></tr></thead><tbody><tr><td>X-Shopwaive-Access-Token</td><td>Store's platform API key for store (required)</td></tr><tr><td>X-Shopwaive-Platform</td><td>Store's platform (required)</td></tr><tr><td>Content-Type</td><td>Content type</td></tr></tbody></table>

### Response Body

| key      | value                                            |
| -------- | ------------------------------------------------ |
| status   | Status message                                   |
| validity | Description of time left until expiration        |
| action   | Object of action requested                       |
| email    | Customer email address                           |
| message  | If exists, a tip or hint for developer reference |

### action\[] object

| key             | value                                                                                         |
| --------------- | --------------------------------------------------------------------------------------------- |
| expirationdate  | Date the action amount or balance expires                                                     |
| expires         | True or false boolean string                                                                  |
| date            | Date action was created or last updated                                                       |
| id              | Action id. This is set to the order id if created by an order or line item of an order        |
| note            | Transaction note                                                                              |
| type            | Type of transaction (i.e. *rest\_api*)                                                        |
| transaction[^1] | Customer's available balance after action                                                     |
| lineitemid      | If defined, line item id associated or resulted in creation of action amount                  |
| orderid         | If defined, order id associated with the latest redemption event of action amount             |
| status          | If defined, status string (i.e. expired)                                                      |
| amount          | If defined, amount the balance is incremented                                                 |
| media           | If defined, url of media associated with offer                                                |
| segment\_query  | If defined, customer segment query string i.e. customer\_tags CONTAINS 'FALL2023'             |
| collectionids   | If defined, collection ids available for redemption                                           |
| productids      | If defined, product ids available for redemption                                              |
| partial\_amount | If defined, remaining available offer amount (i.e. constrained by current available balance)  |
| remaining       | If defined, remaining available offer amount (i.e. constrained by previous order transaction) |
| validity        | Description of time left until expiration                                                     |

{% hint style="success" %} <mark style="color:blue;">`partial_amount`</mark> and <mark style="color:blue;">`remaining`</mark>can be equivalent in value. The edge case when <mark style="color:blue;">`partial_amount`</mark> is less than <mark style="color:blue;">`remaining`</mark> is when a previous order partially reduces the original offer available redemption amount at the same time that a customers available <mark style="color:blue;">`balance`</mark> is less than <mark style="color:blue;">`remaining`</mark> because of a manual adjustment made to <mark style="color:blue;">`balance`</mark> for example. This means even though a <mark style="color:blue;">`remaining`</mark> amount is still attached to that offer, the customers <mark style="color:blue;">`balance`</mark> is not enough to cover the full remaining offer amount
{% endhint %}

{% hint style="info" %}
The <mark style="color:blue;">`expirationdate`</mark> field is only applicable if the <mark style="color:blue;">`expires`</mark> field is equal to <mark style="color:blue;">**true**</mark>. If multiple expiry dates are enabled in [Settings](https://docs.shopwaive.com/product-tour/dashboard#settings), the <mark style="color:blue;">`expirationdate`</mark> applies to the <mark style="color:blue;">`action`</mark> object defined in the <mark style="color:blue;">`activity`</mark> array if a corresponding <mark style="color:blue;">`amount`</mark> field is defined (i.e. the action was created using the [Customer API PUT](/reference/rest-api-documentation/customer-api#adjust-customer-balance) request or through an [increment bulk import](https://docs.shopwaive.com/shopify/accounts/import-accounts#increment-balances-using-the-increment-column) action using the drag-and-drop editor in the app)
{% endhint %}

{% hint style="info" %}
If single expiry dates is enabled in [Settings](https://docs.shopwaive.com/product-tour/dashboard#settings), then<mark style="color:blue;">`expirationdate`</mark> field represents the date that was used to define the top-level account balance expiration at the time the action was created if <mark style="color:blue;">`expires`</mark> was also equal to <mark style="color:blue;">**true**</mark>
{% endhint %}

## `GET` actions endpoint

Search actions by including any combination of query key value pairs <mark style="color:blue;">`id`</mark>,<mark style="color:blue;">`email`</mark>,<mark style="color:blue;">`created_at_min`</mark>, or <mark style="color:blue;">`created_at_max`</mark> appended to the /api/actions endpoint. A maximum of 250 records per request are returned in the response body. Dates should use ISOString format when appended as a query string, for example, new Date().toISOString().

{% code overflow="wrap" %}

```javascript
// Example date and email constrained request

https://app.shopwaive.com/api/actions?email=support@shopwaive.com&created_at_min=2024-09-22T04:51:20.144Z&created_at_max=2024-09-22T19:14:22.688Z
```

{% endcode %}

{% openapi src="/files/KJIqWVyKnJ6L2olxNisi" path="/api/actions" method="get" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-55832ab970eedcf599807ac960e4a9fda432d8e4%2Findex.yaml?alt=media)
{% endopenapi %}

## `POST` action endpoint

Update an actions <mark style="color:blue;">`expirationdate`</mark>, <mark style="color:blue;">`expires`</mark>, <mark style="color:blue;">`media`</mark> or <mark style="color:blue;">`note`</mark> field(s). This route is useful when updating the validity of an existing promotional credit thats dynamic in nature, for example, when events or customer actions trigger a customers eligibility or access to the promotional credit.

{% openapi src="/files/mxvlhEUDXjsAh3H8cIZi" path="/api/action/{actionid}" method="post" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-0354fa630752e18551f1efd51dfe23ccdbad845d%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

| key                      | value                                         |
| ------------------------ | --------------------------------------------- |
| X-Shopwaive-Access-Token | Store's platform API key for store (required) |
| X-Shopwaive-Platform     | Store's platform (required)                   |
| Content-Type             | Content type                                  |

### Request Body

| key              | value                                                                                                                                                                                 |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| note\*           | If defined, description of transaction                                                                                                                                                |
| expirationdate\* | If defined, date of balance expiration. Accepted formats include <mark style="color:blue;">`April 21, 2028`</mark> or <mark style="color:blue;">`2028-04-21`</mark> (i.e. YYYY-mm-dd) |
| expires\*        | If defined, true or false boolean string                                                                                                                                              |
| media\*          | If defined, url of media associated with offer                                                                                                                                        |

{% hint style="info" %}
Define the <mark style="color:blue;">`note`</mark> or <mark style="color:blue;">`media`</mark> fields in the request body (optional) if you desire to change the note string or media url, respectively, these field can be defined in the request body without any other required fields. If you desire to update the <mark style="color:blue;">`expires`</mark> or <mark style="color:blue;">`expirationdate`</mark> field values, then both <mark style="color:blue;">`expires`</mark> and <mark style="color:blue;">`expirationdate`</mark>fields are required in the request body. All request body fields can be updated simultaneously, however, at a minimum either <mark style="color:blue;">`note`</mark> or both <mark style="color:blue;">`expires`</mark> and <mark style="color:blue;">`expirationdate`</mark>or <mark style="color:blue;">`media`</mark> fields are required in the request body
{% endhint %}

### Response Body

| key    | value                         |
| ------ | ----------------------------- |
| status | Status message (i.e. success) |

{% hint style="success" %}
Debits made using the Customer API[`PUT`](/reference/rest-api-documentation/customer-api#adjust-customer-balance)are not eligible for Action API [POST](#set-action-properties) updates or expiration, only deposits (i.e. <mark style="color:blue;">`amount`</mark> values greater than 0)
{% endhint %}

{% hint style="info" %}
Only the <mark style="color:blue;">`expirationdate`</mark>, <mark style="color:blue;">`expires`</mark>, and <mark style="color:blue;">`note`</mark> field values can be updated on a previously created action; updates to <mark style="color:blue;">`amount`</mark> are not allowed. If changes to <mark style="color:blue;">`amount`</mark> are required, use the [DELETE](#delete-action) Action API, which triggers the same process as if the action expired; at the time the delete request is made if <mark style="color:blue;">`status`</mark> is not equal to <mark style="color:blue;">**expired**</mark>, a debit is created on the customer account balance equal to the value of the <mark style="color:blue;">`amount`</mark> field of the promotional credit action object
{% endhint %}

## `DELETE` action endpoint

Use this endpoint to delete an action. If an <mark style="color:blue;">`amount`</mark> field is defined for the action, deleting the action will automatically reverse the increment the action imposed on the balance by triggering either a debit or deposit to the customer account balance equal to the negated value of <mark style="color:blue;">`amount`</mark> in the <mark style="color:blue;">`action`</mark> object.

{% hint style="info" %}
If <mark style="color:blue;">`amount`</mark> is defined for the action, requests to this endpoint will automatically reverse the credit deposited or amount debited when the action was created. If the account has insufficient funds to transact a debit of <mark style="color:blue;">`amount`</mark> (i.e. customer's available <mark style="color:blue;">`balance`</mark> is less than the previous credited <mark style="color:blue;">`amount`</mark> at the time the action is deleted), then the customer's balance is set equal to 0.00. Customer account balances cannot be negative

**Note:** Debiting the original <mark style="color:blue;">`amount`</mark> of the action is useful in most cases when earned cash or points were a result of an order created that was later cancelled or refunded. Even if the earned cash or points were already spent, deleting the action will attempt to debit any existing balance to recoup the earned credit

If an action amount has been redeemed or partially redeemed already, and you wish to only debit the remaining amount, append <mark style="color:blue;">**?remaining=true**</mark> query to your request. Otherwise, the original <mark style="color:blue;">`amount`</mark> will be used for the debit transaction
{% endhint %}

{% hint style="success" %}
Deleting actions of type <mark style="color:blue;">`rest_api`</mark> that do not have an <mark style="color:blue;">`amount`</mark> field are allowed (actions created by the Customer API [<mark style="color:blue;">POST</mark>](/reference/rest-api-documentation/customer-api#set-customer-endpoint) endpoint or via a [bulk assign import](https://docs.shopwaive.com/shopify/accounts/import-accounts#assign-balances-using-the-balance-column) action in the app), however, no automatic adjustments to an account balance are triggered as a result of deleting the action, and if required, balance adjustments must be created by your integration with an additional request to the [Customer API PUT](/reference/rest-api-documentation/customer-api#increment-customer-endpoint) or [POST](/reference/rest-api-documentation/customer-api#set-customer-endpoint) endpoints
{% endhint %}

{% hint style="success" %}
If an order triggers the creation of the action (i.e. via Shopify Flow and the Increment balance action), then the action <mark style="color:blue;">**`id`**</mark> is automatically set equal to the order id that created it. Therefore, if multiple deposits occur on the same order, to uniquely define the action object send the <mark style="color:blue;">**Increment balance**</mark> Shopify Flow action the Line Item ID by using a <mark style="color:blue;">**For each**</mark> loop action in the Shopify Flow to make the deposits on a line item level. Then you can use the [<mark style="color:blue;">DELETE</mark>](#delete-action-endpoint), [<mark style="color:blue;">POST</mark>](#post-action-endpoint), or [<mark style="color:blue;">GET</mark>](#get-action-endpoint) endpoints using the <mark style="color:blue;">**`lineitemid`**</mark> of the action instead of <mark style="color:blue;">**`id`**</mark> for the<mark style="color:blue;">**`{actionid}`**</mark>path parameter.

Otherwise, if multiple actions are associated with the<mark style="color:blue;">**`{actionid}`**</mark>sent in the endpoint path, then each action associated with the order will be deleted and debited. If this is your intent, use an order id for the<mark style="color:blue;">**`{actionid}`**</mark>path parameter to conveniently delete all actions (i.e. deposits) associated with that order. The deletion of each action will create an associated debit as described above
{% endhint %}

{% openapi src="/files/mxvlhEUDXjsAh3H8cIZi" path="/api/action/{actionid}" method="delete" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-0354fa630752e18551f1efd51dfe23ccdbad845d%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

| key                      | value                                         |
| ------------------------ | --------------------------------------------- |
| X-Shopwaive-Access-Token | Store's platform API key for store (required) |
| X-Shopwaive-Platform     | Store's platform (required)                   |
| Content-Type             | Content type                                  |

### Request Response

| key    | value                           |
| ------ | ------------------------------- |
| status | Status message (i.e. *success*) |

[^1]: deprecated, unstable


# Order API

Create Shopify orders with credit automatically applied with the Shopwaive Order API

{% hint style="info" %}
**Good to know:** This API method provides developers the ability to expedite cart creation with a direct link to checkout with stacked discounts (i.e. line items discounted with promo and credit applied). Gift cards can also be optionally applied at checkout.
{% endhint %}

## GET orders endpoint

Search and filter customer orders by including any combination of query key value pairs <mark style="color:blue;">`id`</mark>,<mark style="color:blue;">`email`</mark>,<mark style="color:blue;">`created_at_min`</mark>, or <mark style="color:blue;">`created_at_max`</mark> appended to the /api/orders endpoint. A maximum of 250 records per request are returned in the response body. Dates should use ISOString format when appended as a query string, for example, new Date().toISOString().

{% code overflow="wrap" %}

```javascript
// Example date and email constrained request

https://app.shopwaive.com/api/orders?email=support@shopwaive.com&created_at_min=2024-09-22T04:51:20.144Z&created_at_max=2024-09-22T19:14:22.688Z
```

{% endcode %}

{% openapi src="/files/nXkIasLNtkmXNk5Zk3D2" path="/api/orders" method="get" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-a818df3017872e2c2a06781d4fdc9295507091b8%2Findex.yaml?alt=media)
{% endopenapi %}

## `POST` order endpoint

{% openapi src="/files/SxAe8b4pp5MX0TU3Y7gs" path="/api/order" method="post" %}
[index.yaml](https://2430267771-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR7BwDfJhPObShd4z9nqx%2Fuploads%2Fgit-blob-19af57f14ff2e60779ae7fff8b31053b665b4756%2Findex.yaml?alt=media)
{% endopenapi %}

### Header

<table><thead><tr><th width="313">key</th><th>value</th></tr></thead><tbody><tr><td>X-Shopwaive-Access-Token</td><td>Store's platform API key for store (required)</td></tr><tr><td>X-Shopwaive-Platform</td><td>Store's platform (required)</td></tr><tr><td>Content-Type</td><td>Content type</td></tr></tbody></table>

### Request Body

| key            | value                                                 |
| -------------- | ----------------------------------------------------- |
| customerid     | Customer id associated with store's platform          |
| free\_shipping | Boolean                                               |
| tags           | Tags to apply to order                                |
| order\_notes   | Additional details or notes to apply to order         |
| description    | Description of credit applied (i.e. Shopwaive Credit) |
| amount         | Amount of credit to apply to order                    |
| cart           | Customer cart associated with order                   |

### Response Body

| key           | value                                           |
| ------------- | ----------------------------------------------- |
| status        | Status message                                  |
| checkout\_url | Checkout url to be used by customer for payment |
|               |                                                 |


# Shopwaive API rate limits

Find Shopwaive's general API rate limit protocol below

To ensure our platform remains stable and fair for everyone, some Shopwaive APIs are rate-limited. We use a variety of strategies to enforce rate limits. We ask developers to use [industry standard techniques](#avoiding-rate-limit-errors) for limiting calls, caching results, and re-trying requests responsibly.

***

## Compare rate limits by API

Shopwaive APIs use several different [rate-limiting methods](#rate-limiting-methods). They’re described in more detail below, but these are the key figures in brief:

<table><thead><tr><th width="220">API</th><th width="196">Rate-limiting method</th><th width="164">Standard limit</th><th>Enterprise limit</th></tr></thead><tbody><tr><td>Shopwaive API (REST)</td><td>Request-based limit</td><td>2 requests / s</td><td>20 requests / s</td></tr></tbody></table>

{% hint style="info" %}
**Tip:** Should your application need to request a custom API rate limit plan, contact sales to learn more at <support@shopwaive.com>
{% endhint %}

## Enterprise limit

If you purchase a high thru-put enterprise API throttling limit for the Shopwaive REST API, you will receive an key-value pair from our Sales team to include in your request header.

For enterprise API requests, in addition to the added header you will include the **/v2** suffix to each route defined in the [REST API documentation](/reference/rest-api-documentation) to make requests.

For example, to make requests to the `POST` customer route <mark style="color:blue;">**/api/customer**</mark> using Enterprise rate limits you will use the <mark style="color:blue;">**/v2/api/customer**</mark> route instead, and add the key-value header **x-shopwaive-api-enterprise**.

### Header

<table><thead><tr><th width="313">key</th><th>value</th></tr></thead><tbody><tr><td>X-Shopwaive-API-Enterprise</td><td>Enterprise rate limit API key for store (required)</td></tr></tbody></table>

***

## Rate limiting methods

Shopwaive uses different methods for managing rate limits. Different APIs use different methods depending on use case, so make sure you understand the various types of rate limits your apps will encounter:

### Request-based limits <a href="#request-based-limits" id="request-based-limits"></a>

Apps can make a maximum **number** of requests per second. For example: 2 requests per second. Each request counts equally, regardless of how much or how little data is returned.

This method is used by the [Shopwaive REST API](/).

## Avoiding rate limit errors

Designing your app with best practices in mind is the best way to avoid throttling errors. For example, you can stagger API requests in a queue and do other processing tasks while waiting for the next queued job to run. Consider the following best practices when designing your app:

* Optimize your code to only get the data that your app requires.
* Use caching for data that your app uses often.
* Regulate the rate of your requests for smoother distribution.
* Include code that catches errors. If you ignore these errors and keep trying to make requests, then your app won’t be able to gracefully recover.
* Use metadata about your app’s API usage, included with all API responses, to manage your app’s behavior dynamically.
* Your code should stop making additional API requests until enough time has passed to retry. The recommended backoff time is 1 second.


# Webhooks

Receive HTTP POST payloads when Shopwaive events occur — webhook events, payload fields, delivery headers, and HMAC-SHA256 signature validation

Webhooks let your service receive an HTTP POST payload whenever selected events occur in Shopwaive. They are available for Shopify stores and Shopify headless sites.

{% hint style="info" %}
Webhooks require organization owner status and developer access. Contact <support@shopwaive.com> to enable developer access for your organization.
{% endhint %}

## Creating a webhook

Webhooks are configured from the Shopwaive web interface or the [REST API](https://api.shopwaive.com). In the web interface, open the avatar menu in the upper-right corner, go to the **Webhooks** settings section, and select **Add webhook**. Provide:

* **Payload URL** — the URL where you'd like to receive payloads
* **Event types** — the events to subscribe to (individual webhook actions cannot be subscribed to separately)
* **Secret** (optional, recommended) — a random string with high entropy, used to validate deliveries
* **Active** — enable the webhook immediately

Upon creation, Shopwaive sends a simple `ping` event to confirm the webhook is set up correctly. You can create up to 5 webhooks for each event on each installation target. By default, webhooks are not subscribed to any events. Payloads are capped at 25 MB. IPv6 is not currently supported.

## Events

* `available_balance` — a customer's available balance changes. The `action` field carries the cause: `created`, `adjusted`, `redeemed`, `deleted`, `refund`, `imported`, `rest_api`, or `expired`.
* Order `invoice_url` created with credit applied, and orders placed with credit.
* Customer `email` sent from an action (`campaign_sent` or `manually_sent`).

### `available_balance` payload

| Field                    | Type   | Description                                                                                                                   |
| ------------------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| `action`                 | string | The action performed                                                                                                          |
| `available_balance.pre`  | string | Balance prior to the event                                                                                                    |
| `available_balance.post` | string | Balance after the event                                                                                                       |
| `transaction`            | string | Associated transaction amount                                                                                                 |
| `customer_email`         | string | Customer's email address                                                                                                      |
| `order_id`               | string | Present only when `action` is `redeemed`                                                                                      |
| `organization`           | object | Present when the webhook target is an organization: `id`, `url` (required); `platform`, `currency`, `contactEmail` (optional) |

## Delivery headers

| Header                                      | Description                                                                |
| ------------------------------------------- | -------------------------------------------------------------------------- |
| `X-Shopwaive-Hook-ID`                       | The unique identifier of the webhook                                       |
| `X-Shopwaive-Event`                         | The name of the event that triggered the delivery                          |
| `X-Shopwaive-Delivery`                      | A GUID identifying the delivery                                            |
| `X-Shopwaive-Signature-256`                 | HMAC-SHA256 hex digest of the request body, signed with the webhook secret |
| `X-Shopwaive-Hook-Installation-Target-Type` | The type of resource where the webhook was created                         |
| `X-Shopwaive-Hook-Installation-Target-ID`   | The unique identifier of that resource                                     |

## Validating deliveries

If you set a secret, validate each delivery before processing it:

1. Read the `X-Shopwaive-Signature-256` header. Its value always starts with `sha256=`.
2. Compute an HMAC-SHA256 hex digest of the raw request body using your webhook secret.
3. Compare your digest to the header value with a constant-time comparison — never a plain `==` operator. Use `crypto.timingSafeEqual` (Node.js), `secure_compare` (Ruby), or `crypto.subtle.verify()` (Web Crypto API).

Test vector for verifying your implementation — secret `It's a Secret to Everybody`, payload `Hello, World!`:

```
X-Shopwaive-Signature-256: sha256=757107ea0eb2509fc211221cce984b8a37570b6d7586c22c46f4379c8b043e17
```


