> ## Documentation Index
> Fetch the complete documentation index at: https://docs.supercycle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Automation overview

> Automate with triggers and actions using Shopify Flow

Supercycle adds triggers and actions to  **[Shopify Flow](https://admin.shopify.com/apps/flow)**, so an event in Supercycle can start a workflow and a workflow can change a cycle, item, membership, or charge. A trigger starts the workflow, conditions decide what happens, and an action does the work.

[Automating Supercycle with Shopify Flow](https://fast.wistia.net/embed/iframe/8nrc2cxjqh)

How Supercycle triggers and actions fit together in Shopify Flow.

What merchants build with it:

* Pause a subscription when the customer starts a return.
* Create a charge for a late fee, a damage fee, or a conversion to purchase.
* Notify the team when a return is approved or received.
* Re-allocate an item when a cycle has an item conflict.
* Update an item's condition, processing status, visibility, serial, or pick location when a cycle completes.
* Retry payment collection after a failed subscription payment.

To build your first one, see [Create a workflow](https://docs.supercycle.com/documentation/manage/automation/create-workflow.md).

***

## Available triggers

Supercycle includes several triggers you can use to start an automation. Every trigger payload also includes a `customer` reference (the Shopify customer) you can use in conditions and downstream actions.

> **Return created**
>
> Runs when a return is created inside Supercycle.
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `returnOrder.formattedId` | Display ID, for example `#1001` |
> | `returnOrder.sequentialId` | Sequential numeric ID |
> | `returnOrder.receivalStatus` | Status: `pending`, `received`, or `overdue` |
> | `returnOrder.createdAt` | ISO 8601 date the return was created |
> | `returnOrder.requestedAt` | ISO 8601 date the return was requested |
> | `returnOrder.tags` | Tags on the return order |
> | `returnOrder.rentals` | Array of cycles in the return (see Cycle properties below) |

> **Return updated**
>
> Runs when a return is updated inside Supercycle.
>
> Payload is identical to **Return created**.

> **Cycle created**
>
> Runs when a cycle is created inside Supercycle.
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `rental.id` | Cycle global ID, for example `gid://supercycle/Rental/12345` |
> | `rental.formattedId` | Display ID, for example `#1001` |
> | `rental.sequentialId` | Sequential numeric ID |
> | `rental.status` | Status: `scheduled`, `unfulfilled`, `fulfilled`, `unreceived`, `received`, or `cancelled` |
> | `rental.fulfillmentStatus` | Fulfillment status: `pending`, `scheduled`, `in_progress`, `overdue`, `complete`, or `cancelled` (canceled before the item went out) |
> | `rental.receivalStatus` | Receival status: `pending`, `scheduled`, `in_progress`, `overdue`, `complete`, or `cancelled` (canceled before the item came back) |
> | `rental.packingStatus` | Packing status: `pending`, `printed`, or `packed` |
> | `rental.methodType` | Method type: `calendar`, `subscription`, `membership`, or `resale` |
> | `rental.conflictLevel` | Item allocation conflict: `none`, `item`, or `variant` |
> | `rental.lineItemId` | Shopify line item ID |
> | `rental.orderId` | Shopify order ID |
> | `rental.shopifyOrderName` | Shopify order name, for example `#1001` |
> | `rental.subscriptionId` | Supercycle subscription ID (if exists) |
> | `rental.returnOrderId` | Return order ID (if exists) |
> | `rental.itemId` | Allocated item ID |
> | `rental.fulfillAt` | ISO 8601 dispatch date |
> | `rental.fulfilledAt` | ISO 8601 date the cycle was fulfilled |
> | `rental.receiveAt` | ISO 8601 planned return date |
> | `rental.receivedAt` | ISO 8601 date the cycle was received |
> | `rental.rentalStart` | ISO 8601 cycle period start |
> | `rental.rentalEnd` | ISO 8601 cycle period end |
> | `rental.minimumRentalEnd` | ISO 8601 end of minimum cycle term |
> | `rental.restockBy` | ISO 8601 date the item should be restocked by |
> | `rental.restockedAt` | ISO 8601 date the item was restocked |
> | `rental.cancelledAt` | ISO 8601 cancellation date |
> | `rental.createdAt` | ISO 8601 creation date |
> | `rental.updatedAt` | ISO 8601 last updated date |
> | `rental.tags` | Tags on the cycle |
> | `rental.customFields` | Array of `{ key, value }` custom fields |
> | `rental.item` | Allocated item details (see Item properties below) |

> **Cycle updated**
>
> Runs when a cycle is updated inside Supercycle.
>
> Payload is identical to **Cycle created**.

> **Cycle canceled**
>
> Runs when a cycle is canceled inside Supercycle.
>
> Payload is identical to **Cycle created**.

> **Membership created**
>
> Runs when a membership is created inside Supercycle.
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `membership.id` | Membership global ID |
> | `membership.customerId` | Shopify customer GID |
> | `membership.status` | Status: `active`, `paused`, `cancelled`, or `expired` |
> | `membership.planTitle` | Plan or product title |
> | `membership.priceCents` | Membership price in cents |
> | `membership.creditAllowance` | Total credits allowed |
> | `membership.creditsUsed` | Credits currently used |
> | `membership.remainingCredits` | Credits remaining |
> | `membership.orderAllowance` | Maximum orders allowed (`null` if unlimited) |
> | `membership.ordersUsed` | Orders used in current period |
> | `membership.remainingOrders` | Orders remaining (`null` if unlimited) |
> | `membership.returnAllowance` | Maximum returns allowed (`null` if unlimited) |
> | `membership.returnsUsed` | Returns used in current period |
> | `membership.remainingReturns` | Returns remaining (`null` if unlimited) |
> | `membership.renewalDate` | ISO 8601 next renewal date |
> | `membership.minimumTermStart` | ISO 8601 minimum term start date |
> | `membership.minimumTermEnd` | ISO 8601 minimum term end date |
> | `membership.cancelAt` | ISO 8601 scheduled cancellation date |

> **Membership updated**
>
> Runs when a membership is updated inside Supercycle.
>
> Payload is identical to **Membership created**.

> **Membership canceled**
>
> Runs when a membership is canceled inside Supercycle.
>
> Payload is identical to **Membership created**.

> **Contract status updated**
>
> Runs when a [contract's](https://docs.supercycle.com/documentation/configuration/risk/e-signatures.md) status changes inside Supercycle (for example, when a customer signs an unsigned contract).
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `contract.id` | Contract global ID, for example `gid://supercycle/Contract/12345` |
> | `contract.status` | Current status: `unsigned` or `signed` |
> | `contract.templateName` | Name of the contract template |
> | `contract.signedAt` | ISO 8601 date the contract was signed |
> | `contract.createdAt` | ISO 8601 creation date |
> | `contract.updatedAt` | ISO 8601 last updated date |

> **Identity verification status updated**
>
> Runs when an [identity verification's](https://docs.supercycle.com/documentation/configuration/risk/identity-verification.md) status changes inside Supercycle, including when a verification is first uploaded.
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `identityVerification.id` | Identity verification global ID, for example `gid://supercycle/IdentityVerification/12345` |
> | `identityVerification.status` | Current status: `pending`, `submitted`, `in_review`, `completed`, `on_hold`, or `expired` |
> | `identityVerification.result` | Verification result: `approved`, `rejected`, or `inconclusive` |
> | `identityVerification.createdAt` | ISO 8601 creation date |
> | `identityVerification.updatedAt` | ISO 8601 last updated date |

> **Charge failed**
>
> Runs when a single charge payment attempt fails. Use this to react to individual payment failures (for example, on a damage charge).
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `charge.id` | Charge global ID, for example `gid://supercycle/Charge/12345` |
> | `charge.formattedId` | Display ID, for example `#1001` |
> | `payment.errorCode` | Error code from the failed payment attempt |
> | `payment.errorMessage` | Customer-friendly error message |
> | `payment.subtotal` | Amount due, in cents |
> | `payment.paid` | Amount paid, in cents |

> **Payment collection failed**
>
> Runs when a payment collection process completes without successfully capturing payment. Use this for dunning-style automations that react to repeated failures over time.
>
> | Property | Description |
> | - | - |
> | `customer.id` | Shopify customer ID |
> | `paymentCollector.id` | Payment collector global ID |
> | `paymentCollector.status` | Current status of the payment collector |
> | `paymentCollector.summary` | Summary text |
> | `paymentCollector.chargeableId` | Object being charged, for example `gid://supercycle/Rental/12345` |
> | `paymentCollector.subscriptionContractId` | Shopify subscription contract ID |
> | `paymentCollector.failedPaymentCount` | Number of failed payment attempts |
> | `paymentCollector.lastFailedPayment` | Last failed payment (`errorCode`, `errorMessage`, `subtotal`, `paid`) |
> | `paymentCollector.payments` | Array of all payment attempts |

### Shared sub-objects

Several triggers expose nested objects you can drill into:

> **Item**
>
> Available on `rental.item` (Cycle triggers) and on each entry in `returnOrder.rentals[].item`.
>
> | Property | Description |
> | - | - |
> | `item.id` | Item global ID |
> | `item.productTitle` | Product title |
> | `item.variantTitle` | Variant title |
> | `item.serial` | Serial number |
> | `item.sequentialId` | Sequential numeric ID |
> | `item.status` | Processing status: `processed` or `unprocessed` |
> | `item.visibility` | Visibility: `available`, `unavailable`, `sold`, or `retired` |
> | `item.pickLocation` | Physical warehouse location |
> | `item.conditionTitle` | Condition name, for a Flow condition |
> | `item.conditionId` | Condition GID for the **Update item** action, for example `gid://supercycle/Condition/456` |
> | `item.completedCycles` | Number of completed cycles on this item (fulfilled and received, not canceled) |
> | `item.shopifyVariantId` | Shopify variant GID |
> | `item.shopifyProductId` | Shopify product GID |
> | `item.imageUrl` | Image URL |
> | `item.tags` | Tags on the item |
> | `item.createdAt` | ISO 8601 creation date |
>
> Compare **Condition title** with the **Name** under **Item conditions** on  **[Custom data](https://admin.shopify.com/apps/supercycle/settings/custom_data)**.
>
> ```text Condition theme={null}
> rental.item.conditionTitle is equal to Unused
> ```
>
> On a return, compare `rentals.foreachitem.item.conditionTitle` inside a **For each** loop over `returnOrder.rentals`.
>
> An item with no condition has an empty **Condition title**. When more than one condition shares a **Name**, **Condition title** matches an item in any of them.
>
> > [!NOTE]
> >
> > Pass `item.conditionId` to **Update item**, for example `{{rental.item.conditionId}}`. A Flow condition on **Condition ID** shows Invalid Id format. That field only accepts a Shopify ID.

> **Customer**
>
> Available as `customer` on every trigger.
>
> | Property | Description |
> | - | - |
> | `customer.identityVerified` | Whether the customer has an approved [identity verification](https://docs.supercycle.com/documentation/configuration/risk/identity-verification.md) |
> | `customer.numberOfOutstandingCharges` | Count of unpaid charges |
> | `customer.outstandingBalance` | Total outstanding balance, in cents |
> | `customer.totalSpent` | Lifetime spend, in cents |
> | `customer.deposit.balance` | Current deposit account balance |
> | `customer.membership` | Customer's membership (see Membership properties) |

***

## Available actions

Supercycle provides the following actions for use in Shopify Flow workflows.

> **Create charge**
>
> Create a charge for a chargeable object in Supercycle, such as a cycle or membership.
>
> | Property | Description |
> | - | - |
> | `customer` | Shopify customer reference (required) |
> | `chargeableId` | The ID of the object to charge, for example `gid://supercycle/Rental/1234567890` |
> | `description` | The message included in the charge |
> | `amountCents` | The charge amount in cents, for example `1234` for \$12.34 |
> | `taxable` | Whether Shopify applies your shop tax rates. On by default. Turn it off for a tax-exempt charge such as a damage claim |
>
> Returns a `Charge` object you can reference in subsequent steps.
>
> Flow charges are always custom lines. To bill against a named [charge type](https://docs.supercycle.com/documentation/manage/charges/charge-types.md), create the charge from the cycle instead.

> **Update subscription**
>
> Update a subscription's status, recurring price, or billing start date.
>
> | Property | Description |
> | - | - |
> | `subscriptionId` | The ID of the subscription, for example `gid://supercycle/Subscription/1234567890` |
> | `status` | The status to set: `active`, `paused`, `cancelled`, or `expired` |
> | `recurringPriceCents` | New recurring price in cents, for example `1500` for \$15.00 |
> | `billingStartDate` | New billing schedule start date. Supports Liquid date variables. |
>
> Only `subscriptionId` is required. Provide any combination of the other fields to update.

> **Update membership**
>
> Update the status of a membership.
>
> | Property | Description |
> | - | - |
> | `membershipId` | The ID of the membership, for example `gid://supercycle/MembershipRental::Membership/1234567890` |
> | `status` | The status to set: `active`, `paused`, `cancelled`, or `expired` |

> **Get cycle data**
>
> Get data about a cycle in Supercycle. Use this to retrieve cycle information for use in conditional logic.
>
> | Property | Description |
> | - | - |
> | `rentalId` | The ID of the cycle, for example `gid://supercycle/Rental/1234567890` |
>
> Returns a `Rental` object with all cycle properties (see the **Cycle created** trigger for the full list).
>
> To check whether a cycle has a subscription before acting on it, add **Get cycle data** with **Cycle ID** set to `{{rental.id}}`. Later steps can then read:
>
> * `{{getRental.subscriptionId}}`, the subscription ID if there is one
> * `{{getRental.orderId}}`, the Shopify order ID
> * `{{getRental.fulfilledAt}}`, the fulfillment date
> * `{{getRental.receivedAt}}`, the received date
>
> ```text Condition theme={null}
> getRental.subscriptionId is not empty
> ```

> **Get cycles**
>
> Get the cycles on a Shopify order. Use this when a workflow starts from an order and needs each cycle on it.
>
> | Property | Description |
> | - | - |
> | `orderId` | The Shopify order ID, for example `gid://shopify/Order/1234567890` |
>
> Returns a `Cycles` object. Each entry in `cycles` is a `Rental` with the same properties as **Get cycle data**. The **Cycle created** trigger lists those properties.
>
> Add **Get cycles** with **Order ID** set to `{{order.id}}`. Then add a **For each** loop over `getCycles.cycles`. Inside the loop, you can use:
>
> * `{{cycles.foreachitem.id}}`, the cycle ID
> * `{{cycles.foreachitem.subscriptionId}}`, the subscription ID if there is one
> * `{{cycles.foreachitem.fulfillmentStatus}}`, the fulfillment status
> * `{{cycles.foreachitem.receivalStatus}}`, the receival status
>
> ```text Condition theme={null}
> cycles.foreachitem.subscriptionId is not empty
> ```
>
> > [!NOTE]
> >
> > Supercycle adds an order's cycles after it saves the order. Get cycles returns an empty list until Supercycle has added the order's cycles. An order with no cycles stays empty.

> **Update cycle**
>
> Update properties of a cycle.
>
> | Property | Description |
> | - | - |
> | `rentalId` | The ID of the cycle, for example `gid://supercycle/Rental/1234567890` |
> | `itemId` | The item ID to assign to the cycle |
> | `fulfilledAt` | ISO 8601 datetime when the cycle was fulfilled, for example `2024-01-15T10:30:00Z` |
> | `receivedAt` | ISO 8601 datetime when the cycle was received |
> | `rentalStart` | ISO 8601 date when the cycle period starts |
> | `rentalEnd` | ISO 8601 date when the cycle period ends |
> | `prepareFrom` | ISO 8601 date the outbound preparation buffer starts. Pass an empty value to revert to the automatic date computed from the shop's [preparation buffer](https://docs.supercycle.com/documentation/configuration/logistics/buffers.md). |
> | `restockBy` | ISO 8601 date the inbound restock buffer ends. Pass an empty value to revert to the automatic date computed from the shop's [restock buffer](https://docs.supercycle.com/documentation/configuration/logistics/buffers.md). |
> | `packingStatus` | The packing status: `pending`, `printed`, or `packed` |
>
> Only `rentalId` is required. Provide any combination of the other fields to update.

> **Update item**
>
> Update an item's [condition](https://docs.supercycle.com/documentation/manage/inventory/item-conditions.md), processing status, visibility, serial number, or pick location.
>
> | Property | Description |
> | - | - |
> | `itemId` | The ID of the item, for example `gid://supercycle/Item/1234567890`. Use `rental.item.id` from any cycle trigger. |
> | `conditionId` | The GID of the new condition, for example `gid://supercycle/Condition/456` |
> | `status` | Processing status: `processed` or `unprocessed` |
> | `serial` | Serial number |
> | `visibility` | One of: `available`, `unavailable`, `sold`, `retired` |
> | `pickLocation` | Warehouse pick location label |
>
> Only `itemId` is required. Provide any combination of the other fields to update, and blank optional fields are ignored.
>
> `conditionId` sets the new condition. To check the condition an item already has, compare `item.conditionTitle` in a Flow condition.
>
> Returns an `Item` object you can reference in subsequent steps (see the **Item** sub-object for the full list).

> **Add cycle tags**
>
> Add tags to a cycle.
>
> | Property | Description |
> | - | - |
> | `rentalId` | The ID of the cycle, for example `gid://supercycle/Rental/1234567890` |
> | `tags` | Comma-separated list of tag titles to add, for example `damaged, follow-up, vip` |

> **Create payment attempt**
>
> Trigger a payment attempt on a charge's payment collector. This mirrors the **Retry billing** button on the charge detail page and is a natural companion to the **Payment collection failed** trigger. Use it to retry collection after a delay, or once another system tells you the customer has updated their payment method.
>
> | Property | Description |
> | - | - |
> | `charge_id` | The ID of the charge, for example `gid://supercycle/Charge/1234567890` |
>
> Returns a `Payment` object you can reference in subsequent steps:
>
> | Property | Description |
> | - | - |
> | `errorCode` | Error code from the payment attempt (if any) |
> | `errorMessage` | Customer-friendly error message (if any) |
> | `subtotal` | Amount due, in cents |
> | `paid` | Amount paid, in cents |
>
> The action fails (and the workflow step errors) if:
>
> * The charge cannot be found (`404`).
> * The charge has no payment collector (`400`), for example a one-off charge that was never tied to a subscription billing flow.
> * The charge is canceled or already paid in full (`400`).

> **Re-allocate item**
>
> Re-allocate an available item to a cycle. Useful when the currently allocated item has a conflict (`rental.conflictLevel` of `item` or `variant`) and you want Supercycle to pick a fresh available item automatically.
>
> | Property | Description |
> | - | - |
> | `rentalId` | The ID of the cycle, for example `gid://supercycle/Rental/1234567890` |
>
> Returns the updated `Rental`. Pair this with the **Cycle updated** trigger and a condition on `rental.conflictLevel` to automatically resolve item conflicts as soon as they appear.

***

## Related documentation

> **[Create a workflow](https://docs.supercycle.com/documentation/manage/automation/create-workflow.md)**
>
> Build a workflow from a Supercycle trigger, with worked examples.

> **[Shopify Flow](https://help.shopify.com/en/manual/shopify-flow)**
>
> Read Shopify's guide to building and managing workflows.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.