Seal Subscriptions Merchant API Documentation


What is the Seal Subscriptions Merchant API?

The Seal Subscriptions Merchant API is a public REST API for Seal Subscriptions app, which allows merchants to retrieve details about their subscriptions, subscription rules and create webhooks to get notified whenever a specific object changes in the app.
The full documenation of what you can do with the API is listed on this page.

Feel free to use our API client, which was created to save you some valuable time. You can fork it from our Github page: https://github.com/SealSubscriptions/Seal-Subscriptions-php-API-client

Authentication

The API client authenticates itself with the API token which can be found for each shop in the Seal Subscriptions app > Settings > General Settings > API. The token has to be sent as a value for the X-Seal-Token header. Token is unique for each shop and should be protected the same way you protect your usernames and passwords.

Retrieve subscriptions

The subscription retrieval can be done with a simple GET call to a /subscriptions endpoint.
Here is an example of such call:
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscriptions \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'
Please note that if you are sending these sample commands over communication apps (e.g. Slack, Microsoft Teams, etc.) these apps might change quotes and thus breaking this command. To resolve this, simply rewrite the qoutes in the command after pasting it in your terminal.

You can also search for subscriptions by customer's email, first name or last name with the GET parameter: query.
Here is an example on how to find subscriptions that contain a name John:
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscriptions?query=john \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'

Subscriptions are always paginated (50 subscriptions per page) and you can define which page you want with the page GET parameter.
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscriptions?page=2 \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'

Here is a list of available get parameters with description of available values you can use:
  • query: value can be any search string. Default value is an empty string.
  • page: value can be any number and represents the requested page. Default value is 1.
  • active-only: value can be "true" or "false". Default value is "false."
  • paused-only: value can be "true" or "false". Default value is "false."
  • cancelled-only: value can be "true" or "false". Default value is "false."
  • with-items: value can be "true" or "false". Default value is "false." If you set it to "true" then the API will return subscriptions with all items.


Get more info about a specific subscription

You can retrieve a specific subscription and all info related to it with a GET call to a /subscription endpoint.
Here is an example of such call:
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription?id=12345 \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'
Make sure to pass the subscription ID to the GET parameter and not the value from the "internal_id" parameter.

Here is a sample payload for a response of this endpoint:
{
    "success": true,
    "payload": {
        "id": 123123,
        "order_placed": "2024-01-22T09:44:10+00:00",
        "internal_id": 2696,
        "delivery_interval": "1 week",
        "billing_interval": "1 week",
        "order_id": "123123123",
        "email": "john.doe@sealsubscriptions.com",
        "currency": "EUR",
        "first_name": "John",
        "last_name": "Doe",
        "s_first_name": "John",
        "s_last_name": "Doe",
        "s_address1": "Seal Subscription street 5",
        "s_phone": "+3861111111111",
        "s_city": "New York",
        "s_zip": "10031",
        "s_province": "New York",
        "s_country": "United States",
        "s_country_code": "US",
        "s_province_code": "NY",
        "b_first_name": "",
        "b_last_name": "",
        "b_address1": "",
        "b_address2": "",
        "b_phone": "",
        "b_city": "",
        "b_zip": "",
        "b_province": "",
        "b_country": "",
        "b_company": "",
        "b_country_code": "",
        "b_province_code": "",
        "total_value": 33.21,
        "admin_note": "",
        "subscription_type": 2,
        "status": "ACTIVE", /* Possible status values: ACTIVE, PAUSED, CANCELLED, EXPIRED. A subscription is expired if the maximum number of payments was set on it and this limit was already reached. */
        "customer_id": "234234234",
        "billing_min_cycles": "",
        "billing_max_cycles": "",
        "note": "",
        "note_attributes": [],
        "edit_url": "", /* Redacted in documentation, as this URL has to be kept safe */
        "cancelled_on": "",
        "paused_on": "",
        "shopify_graphql_subscription_contract_id": "345345345",
        "card_brand": "mastercard",
        "card_expiry_month": "11",
        "card_expiry_year": "2024",
        "card_last_digits": "4444", /* This is a test credit card for demonstration purposes only. */
		"delivery_method_title": "Delivery method title",
        "delivery_method_presentment_title": "Delivery method presentment title",
        "delivery_price": 24.99,
        "delivery_method_code": "Delivery method code",
        "items": [{
                "id": 3213875,
                "product_id": "4648338653317",
                "variant_id": "39353694158981",
                "title": "Bag of coffee - 2kg",
                "variant_sku": "bag-0f-c0ff34-2-X",
                "quantity": 1,
                "price": "36.9",
                "total_discount": "3.69",
                "discount_per_item": "3.69",
                "taxable": 1,
                "requires_shipping": 1,
                "original_price": "36.9",
                "original_amount": 36.9,
                "discount_value": 3.69,
                "discount_amount": 3.69,
                "final_price": 33.21,
                "final_amount": 33.21,
                "properties": [],
                "is_one_time_item": 0,
                "selling_plan_id": "762773637",
                "cycle_discounts": [],
                "discount_codes": [{
                        "id": "d4d2be91-a032-4e91-b625-1c8add794b32",
                        "code": "Loyalty discount",
                        "amount": "3.69"
                    }
                ]
            }
        ],
        "billing_attempts": [{
                "id": 213615668,
                "date": "2024-01-29T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }, {
                "id": 213615669,
                "date": "2024-02-05T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }, {
                "id": 213615670,
                "date": "2024-02-12T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }, {
                "id": 213615671,
                "date": "2024-02-19T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }, {
                "id": 213615672,
                "date": "2024-02-26T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }, {
                "id": 213615673,
                "date": "2024-03-04T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }, {
                "id": 213615674,
                "date": "2024-03-11T09:00:00+00:00",
                "status": "",
                "order_id": "",
                "error_code": "",
                "error_message": "",
                "triggered_manually": "",
                "customer_authentication_challenge_url": ""
            }
        ],
        "invoices": [],
        "fulfillment_orders": [],
        "tags": [],
        "log": [{
                "content": "Applied loyalty discount: 'Loyalty discount'.",
                "created": "2024-01-22 09:45:02"
            }, {
                "content": "The \"New Subscription\" e-mail was sent to the customer.",
                "created": "2024-01-22 09:44:17"
            }
        ]
    }
}


Create a subscription

To create a new subscription, send a POST request to /subscription endpoint with the subscription data, as described in the sample below..

Here is an example of such call:
curl -X POST \
https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
-H 'Content-Type: application/json' \
-H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
-d '{
		"action": "create_subscription",
		"subscription": {
			"next_billing_date": "2024-03-06T08:00:00+00:00", // The date and time when you want the subscription to renew.
			"billing_min_cycles": 5,
			"billing_max_cycles": 0,
			"interval_type": "month",
			"interval_number": 1,
			"billing_interval_type": "month",
			"billing_interval_number": 1,
			"email": "john@sealsubscriptions.com",
			"currency": "EUR",
			"delivery_method_type": "SubscriptionDeliveryMethodShipping", // Posible values are: 
			// SubscriptionDeliveryMethodShipping 		<- for standard shipping,
			// SubscriptionDeliveryMethodLocalDelivery 	<- for local delivery,
			// SubscriptionDeliveryMethodPickup 		<- for local pickup
			"shipping": { // This object contains the shipping address information. Please note that the data in this sample is made up.
				"first_name": "John",
				"last_name": "Doe",
				"address1": "Seal Subscriptions street 5a",
				"address2": "",
				"phone": "+386 69 841 407",
				"city": "New York",
				"zip": "10022",
				"province": "New York",
				"country": "United States",
				"company": "",
				"country_code": "US",
				"province_code": "NY"
			},
			"billing": { // This object contains the billing address information. Please note that the data in this sample is made up.
				"first_name": "John",
				"last_name": "Doe",
				"address1": "Seal Subscriptions street 5a",
				"address2": "",
				"phone": "+386 69 841 407",
				"city": "New York",
				"zip": "10022",
				"province": "New York",
				"country": "United States",
				"company": "",
				"country_code": "US",
				"province_code": "NY"
			},
			"items": [
				{
					"product_id": "4648340258949",
					"variant_id": "32694645424261",
					"title": "Robusta coffee 1kg",
					"price": "24.00",
					"sku": null,
					"total_discount": 0,
					"taxable": 0,
					"requires_shipping": 1,
					"subsc_discount_percent": 0,
					"quantity": 1,
					"properties": [],
					"one_time": 0
				},
				{
					"product_id": "4648338653317",
					"variant_id": "39353694126213",
					"title": "Bag of coffee - 1kg",
					"price": "24.00",
					"sku": null,
					"total_discount": 0,
					"taxable": 0,
					"requires_shipping": 1,
					"subsc_discount_percent": 0,
					"quantity": 1,
					"properties": [
						// This is an object for a line item property
						{
							"key": "Line item property name",
							"value": "Line item property value"
						}
					],
					"one_time": 0,
					"cycle_discounts": [{
							"base_price": "24.00",
							"after_cycle": 0,
							"computed_price": "24.00"
						}, {
							"base_price": "24.00",
							"after_cycle": 5,
							"computed_price": "19.99"
						}
					]
				}
			],
			"subscription_type": "auto-charging", // You can put in auto-charging or recurring-invoices
			"delivery_price": "9.99",
			"delivery_method_title": "Subscription shipping",
			"delivery_method_presentment_title": "Subscription shipping",
			"delivery_method_code": "Subscription shipping",
			"delivery_method_description": "",
			"customer_id": "3586143715461",
			"payment_method_id": "gid://shopify/CustomerPaymentMethod/dc734beddfd1a374d4fd48a2d8196560", // This value can be passed with entire prefix "gid://shopify/CustomerPaymentMethod/" or you can just pass its alphanumeric string, such as "dc734beddfd1a374d4fd48a2d8196560"
			"note": "Order note",
			"note_attributes": [{
					"name": "Sample attribute name",
					"value": "Sample attribute value"
				}
			]
		}
}'


Add items to the subscription

To add items to a specific subscription, send a PUT request to /subscription endpoint.

Here is an example of such call:
curl -X PUT \
https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
-H 'Content-Type: application/json' \
-H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
-d '{
"id" : 568185, // Subscription ID
"action": "add_items", 
"add_items": [
	{
		"product_id" 		: "4648340258949",			// Product ID
		"variant_id" 		: "32694645424261",			// Product variant ID
		"quantity"	 		: "2",						// Quantity of the item
		"title" 	 		: "Bag of coffee - 1 kg",	// Title of the product and variant
		"sku" 		 		: "B4G-0F-C0FF3-SKU",		// SKU code of the item 
		"price" 	 		: 14.99,					// Price of the item in the currency of the subscription
		"taxable" 			: 1,						// 1 if the item is taxable and 0 if it is not
		"requires_shipping" : 1,						// 1 if the item requires shipping and 0 if it is not
		"one_time" 			: 0,						// 1 if the item should be removed after the next renewal 
														// and 0 if it is a subscription item and 
														// should remain in the subscription after the renewal
	},
	{
		"product_id" 		: "4648340258947",
		"variant_id" 		: "32694645424262",
		"quantity"	 		: "2",
		"title" 	 		: "Bag of coffee - 2 kg",
		"sku" 		 		: "B4G-0F-C0FF3-SKU",
		"price" 	 		: 25.99,
		"taxable" 			: 1,
		"requires_shipping" : 1,
		"one_time" 			: 0,
	},
],
}'


Remove items from the subscription

To remove items from a specific subscription, send a PUT request to /subscription endpoint.

Here is an example of such call:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id" : 568185, // Subscription ID
    "action": "remove_items", 
    "remove_items": [ // Array of item IDs you want to remove
        1014923,
        1014921
    ],
}'


Edit subscription

To edit a subscription, send a PUT request to /subscription endpoint. Currently, you can only change the min/max number of required payments, adjust the note attributes on the subscription and update delivery method properties such as title, presentment title, price and delivery method code. If you want to edit the items in the subscription (including editing the price), then simply add the new item to the subscription and remove the old one.

Here is an example of such call:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id" : 568185, // Subscription ID
    "action": "edit", 
    "edit": {
        "billing_min_cycles": 5,
        "billing_max_cycles": 25,
        "note_attributes": [ // Array of note_attributes. If you want to remove them, simply set this to an empty array.
            {
                "name": "Attribute name",
                "value": "Attribute value"
            },
            {
                "name": "Attribute name 2",
                "value": "Attribute value 2"
            }
        ],
        "delivery_method_title": "Delivery method title",
        "delivery_method_presentment_title": "Delivery method presentment title",
        "delivery_price": 24.99,
        "delivery_method_code": "Delivery method code"
    }
}'


Cancel or pause a specific subscription

To cancel or pause a specific subscription, send a PUT request to /subscription endpoint.

Cancelling a subscription:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "action": "cancel"
  }'

Pausing a subscription:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "action": "pause"
  }'


Reactivate or resume a specific subscription

To reactivate or resume a specific subscription, send a PUT request to /subscription endpoint. There is almost no difference in the resume and reactivate actions, except that you generally resume paused subscriptions and reactivate the cancelled subscriptions. But you can use any of these two actions when you want to reactivate or resume a subscription, as the effect will be the same.

Reactivate a subscription:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "action": "reactivate"
  }'

Resume a subscription:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "action": "resume"
  }'


Reschedule, delete, skip or unskip a billing attempt

To reschedule a specific billing attempt, send a PUT request to /subscription-billing-attempt endpoint. You can only reschedule billing attempts that weren't yet processed.
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-billing-attempt \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "subscription_id": 123123,
    "date": "2022-01-05",
    "time": "14:30",
    "timezone": "-04:00",
    "action": "reschedule",
    "reset_schedule": "true" // Optional parameter, which allows you to reset the rest of the schedule after this billing attempt.
  }'

To reschedule a billing attempt, you have to add payload data to the PUT request, which contains:
  • ID of the billing attempt you want to reschedule in parameter "id"
  • ID of the subscription to which the billing attempt is bound in parameter "subscription_id"
  • desired date to which you want to reschedule the attempt in parameter "date"
  • desired time to which you want to reschedule the attempt in parameter "time"
  • timezone in which the supplied date and time were provided in parameter "timezone"
  • "reschedule" as a value of the "action" parameter to let the API know that you want to reschedule the attempt.
  • (optional) "reset_schedule" parameter with value of "true" (as a string), to let the API know that you want to reset the rest of the schedule after the rescheduled billing attempt. The app will then recreate the rest of the schedule based on the date and time of this billing attempt.

And this is how you can delete a specific billing attempt
curl -X DELETE \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-billing-attempt?id=12345\&subscription_id=12345 \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'

To DELETE a billing attempt, you have to provide the billing attempt ID in the "id" GET parameter and the subscription ID to which the attempt is bound in the "subscription_id" GET parameter. You can only delete the billing attempts that weren't yet processed.

Note: The system will always try to keep billing attempts scheduled for the next 65 days, so even if you delete all biling attempts, they will get rescheduled again in a few hours. The usage of this endpoint is recommended if you want to move the next billing attempt to a specific day and then remove other billing attempts so that the system will schedule other billing attempts from your last billing attempt.

SKIP a specific billing attempt
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-billing-attempt \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "subscription_id": 123123,
    "action": "skip"
  }'

UNSKIP a specific billing attempt
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-billing-attempt \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "subscription_id": 123123,
    "action": "unskip"
  }'



Reschedule a fulfillment order

To reschedule a specific fulfillment order (for prepaid subscriptions), send a PUT request to /subscription-fulfillment-order endpoint.
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-fulfillment-order \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "subscription_id": 123123,
    "date": "2022-01-05",
    "time": "14:30",
    "timezone": "-04:00",
    "action": "reschedule"
  }'

To reschedule a fulfillment order, you have to add payload data to the PUT request, which contains:
  • ID of the fulfillment order you want to reschedule in parameter "id"
  • ID of the subscription to which the fulfillment order is bound in parameter "subscription_id"
  • desired date to which you want to reschedule the fulfillment order in parameter "date"
  • desired time to which you want to reschedule the fulfillment order in parameter "time"
  • timezone in which the supplied date and time were provided in parameter "timezone"
  • "reschedule" as a value of the "action" parameter to let the API know that you want to reschedule the fulfillment order.


Apply a discount code

To apply a discount code on a subscirption send a PUT request to /subscription-discount-code endpoint.
curl -X PUT \
                  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-discount-code \
                  -H 'Content-Type: application/json' \
                  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
                  -d '{
                    "subscription_id": 123123, 
                    "action": "apply",
                    "discount_code": "DISCOUNT-20-OFF"
                  }'

To apply a discount code on a subscription, you have to add payload data to the PUT request, which contains:
  • ID of the subscription to which the billing attempt is bound in parameter "subscription_id"
  • desired discount code in parameter "discount_code"
  • "apply" as a value of the "action" parameter to let the API know that you want to apply the discount code.


Remove a discount code

To remove a discount code from the subscription send a DELETE request to /subscription-discount-code endpoint.
curl -X DELETE \
https://app.sealsubscriptions.com/shopify/merchant/api/subscription-discount-code?discount_code_id=asda-4sdf2-asddsfs3-sdf2sd-f2323\&subscription_id=12345 \
-H 'Content-Type: application/json' \
-H 'X-Seal-Token: YOUR_SEAL_TOKEN'

To remove a discount code from a subscription, you have to provide the following values in the GET parameters of the DELETE request:
  • ID of the subscription to which the discount code is bound in parameter "subscription_id"
  • the ID of the discount code in parameter "discount_code_id"


You can retrieve a magic link for a customer by their email with a GET call to a /customer-magic-link endpoint. The endpoint will return a magic link only if the customer has at least one subscription in the shop. This magic link allows the customer to access and edit all of their subscriptions, so make sure you handle it with special care.

Here is an example of such call:
curl -X GET \
https://app.sealsubscriptions.com/shopify/merchant/api/customer-magic-link?email=john@sealsubscriptions.com \
-H 'Content-Type: application/json' \
-H 'X-Seal-Token: YOUR_SEAL_TOKEN'


Send the payment method update email to the customer

To send the email, which allows customers to update the payment method, send a PUT request to /subscription endpoint with action parameter set to send_payment_method_update_email.
Here is a sample of such request:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "id": 123123, 
    "action": "send_payment_method_update_email"
  }'


Retrieve subscription rules

You can also get list of subscription ruls with a GET call to a /subscription-rules endpoint.
Here is an example of such call:
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-rules?page=1 \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'


Retrieve specific subscription rule

You can retrieve a specific subscription rule with a GET call to a /subscription-rule endpoint, where you add the ID of the rule as a GET parameter.
Here is an example of such call:
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-rule?id=12345 \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'


Edit subscription rule

To edit a specific subscription rule, send a PUT request to /subscription-rule endpoint.
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-rule \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{"id": 1234,"product_variants": [{"product_id": "4315124891700","variant_id": null}, {"product_id":4315121156148, "variant_id": 39418377830452}]}'

Currently, you can edit the following parts of the subscription rule
  • name, which represents a name of the subscription rule
  • options, which represent the label for the plan selector such as Deliver every
  • product_variants, which represents the product variants linked to the auto-charging subscription rule,
  • append_product_variants, which represents the product variants which should be appended to the auto-charging subscription rule.
The product_variants parameter has to be an array of products, where each element contains product_id and variant_id field. For example:
{
    id: 123123, 				// An ID of the subscription rule
    name: "Subscribe & save",	// Name of the subscription rule
    options: "Delive every",	// Label for the plan selector in auto-charging widgets
    product_variants: [			// List of product variants included in auto-charging subscription rule
        {
            product_id: 1231241,
            variant_id: 122423	// We are adding a specific variant to the subscription rule
        },
        {
            product_id: 1231242,
            variant_id: null 	// We are adding all variants from this product to the subscription rule
        }
    ]

To remove a variant/product from the rule, just remove it from the product_variants array. To add it to the rule, just add it to the product_variants array. Mind that the array of products and variants you send to the API will overwrite the existing product variants linked to the subscription rule. It won't just add them to the rule. If you want to add a specific product or variant to the subscription rule, then use the append_product_variants key (see below).

Add variants to the subscription rule
To only add specific product or variant to the subscription rule and not overwrite every other product/variant which is already in the subscription rule, send a request to /subscription-rule/append-product-variants endpoint.
For example:
{
    id: 123123, 		// An ID of the subscription rule
    product_variants: [	// List of product variants which you want to add to the auto-charging subscription rule
        {
            product_id: 7777777,
            variant_id: null 	// We are adding all variants from this product to the subscription rule and NOT overwriting 
                                // all the other products and variants which are already in the subscription rule
        }
    ]

And the full request:
curl -X PUT \
  https://app.sealsubscriptions.com/shopify/merchant/api/subscription-rule/append-product-variants \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{"id": 123123,"product_variants": [{"product_id": "7777777","variant_id": null}]}'


Create a webhook

To create a webhook which will be executed whenever a subscription is created, send a POST request to /webhooks endpoint.
curl -X POST \
  https://app.sealsubscriptions.com/shopify/merchant/api/webhooks \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "topic": "subscription/created", 
    "address": "YOUR_HTTPS_WEBHOOK_ADDRESS"
  }'

When the specified action happens (e.g. subscription is created), our system will send a request with the subscription details to the webhook address you specified in your webhook configuration. Our system will try to deliver the webhook for up to 20 times until your server responds with a HTTP code of 200 OK within 5 seconds. If the webhook can't be delivered after 20 tries, then the whole webhook configuration will be removed.

The payload of each webhook request (and other API responses) will be signed with a HMAC code which will be sent as the value of the X-Seal-Hmac-Sha256 header. The HMAC code will be computed with the JSON encoded webhook payload and the Seal API secret. You can get the Seal API secret of the shop you are making requests for in Seal Subscriptions app > Settings > General Settings > API. It is highly recommended to verify the HMAC signature and reject the content if the signatures don't match. HMAC signature allows you to verify the integrity and authenticity of the message.
You can see how you can verify the signature in our PHP Library available on Github.
https://github.com/SealSubscriptions/Seal-Subscriptions-php-API-client

The currently available webhook topics are:
  • subscription/created
  • subscription/updated
  • subscription/paused
  • subscription/resumed
  • subscription/reactivated
  • subscription/expired
  • subscription/cancelled
  • subscription_rule/created
  • subscription_rule/updated
  • billing_attempt/succeeded
  • billing_attempt/failed
  • billing_attempt/upcoming_email_sent <-- The webhook will be sent as per your configuration in the Seal Subscriptions > Settings > Notifications & Emails for the "Reminder about the upcoming billing" notification (e.g. 1 day before the charge).

This is how you can get your current webhooks:
curl -X GET \
  https://app.sealsubscriptions.com/shopify/merchant/api/webhooks \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'

And this is how you delete a specific webhook:
curl -X DELETE \
  https://app.sealsubscriptions.com/shopify/merchant/api/webhooks?id=12345 \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN'

This is a sample payload of the subscription_rule/created webhook:
{
    "id": 123124,
    "name": "Monthly subscription",
    "option": "Deliver every",
    "payment_type": "auto-charge",
    "product_variants": [{
            "product_id": "431512499999999",
            "variant_id": null
        }, {
            "product_id": "43151299999999",
            "variant_id": null
        }
    ],
    "selling_plans": [{
            "name": "Monthly subscription",
            "option": "month",
            "delivery_interval": "month",
            "delivery_interval_count": 1,
            "billing_interval": "month",
            "billing_interval_count": 1,
            "pricing_policy_fixed_adjustment_type": "",
            "pricing_policy_fixed_adjustment_value": "",
            "pricing_policy_recurring_adjustment_type": "",
            "pricing_policy_recurring_adjustment_value": "",
            "pricing_policy_recurring_after_cycle": 1,
            "pricing_policy_recurring_active": 0,
            "selling_plan_id": "123123123",
            "billing_min_cycles": 0, /* 0 represents an unset value*/
            "billing_max_cycles": 0, /* 0 represents an unset value*/
            "description": "Subscribe"
        }
    ]
}

This is a sample payload of the webhooks for subscription and billing_attempt topics:
{
    "id": 123123,
    "order_placed": "2021-05-25T05:17:59-04:00",
    "internal_id": 1038,
    "delivery_interval": "2 week",
    "billing_interval": "2 week",
    "order_id": "12312312313",
    "email": "test@sealsubscriptions.com",
    "currency": "USD",
    "first_name": "John",
    "last_name": "Doe",
    "s_first_name": "John",
    "s_last_name": "Doe",
    "s_address1": "Seal Subscriptions street 5",
    "s_address2": "",
    "s_phone": "132313",
    "s_city": "New York",
    "s_zip": "10001",
    "s_province": "New York",
    "s_country": "United States",
    "s_company": "",
    "s_country_code": "US",
    "s_province_code": "NY",
    "b_first_name": "",
    "b_last_name": "",
    "b_address1": "",
    "b_address2": "",
    "b_phone": "",
    "b_city": "",
    "b_zip": "",
    "b_province": "",
    "b_country": "",
    "b_company": "",
    "b_country_code": "",
    "b_province_code": "",
    "total_value": 1776,
    "admin_note": "",
    "subscription_type": 2,
    "status": "ACTIVE", /* Possible status values: ACTIVE, PAUSED, CANCELLED, EXPIRED. A subscription is expired if the maximum number of payments was set on it and this limit was already reached. */
    "customer_id": "15512324",
    "billing_min_cycles": 3,
    "billing_max_cycles": 15,
    "note": "",
    "note_attributes": [],
    "edit_url": "", /* Redacted in documentation, as this URL has to be kept safe */
    "items": [{
            "id": 1234,
            "product_id": "",
            "variant_id": "",
            "title": "Two teddy bears",
            "variant_sku": "2BEARS-MEDIUM",
            "quantity": 1,
            "price": "1776.0",
            "total_discount": "0",
            "discount_per_item": "",
            "taxable": 1,
            "requires_shipping": 1,
            "original_price": "1776.0",
            "original_amount": 1776,
            "discount_value": 0,
            "discount_amount": 0,
            "final_price": "1776.0",
            "final_amount": 1776,
            "properties": [],
            "cycle_discounts": []
        }
    ],
    /* Billing attempts were modified before adding them to the API documentation, so the dates in this sample are not correct according to the desired delivery schedule */
    "billing_attempts": [{
            "id": 2343421,
            "date": "2021-10-12T09:00:00+00:00",
            "status": "completed",
            "order_id": "564564121223",
            "error_code": "",
            "error_message": "",
            "triggered_manually": ""
        }, {
            "id": 234234,
            "date": "2021-11-26T09:00:00+00:00",
            "status": "",
            "order_id": "",
            "error_code": "",
            "error_message": "",
            "triggered_manually": ""
        }
    ],
    "invoices": [],
    "fulfillment_orders": [],
    "tags": [],
    "log": []
}



Create Quick Checkout URL

You can create the Quick Checkout URL by sending a POST request to a /quick-checkout-url endpoint. The selling_plan parameter can be found in the subscription rule configuration.

Here is an example of such call:
curl -X POST \
  https://app.sealsubscriptions.com/shopify/merchant/api/quick-checkout-url \
  -H 'Content-Type: application/json' \
  -H 'X-Seal-Token: YOUR_SEAL_TOKEN' \
  -d '{
    "action": "create", 
    "items": [
        {
            "variant_id": "39353694126213",
            "quantity": "2",
            "selling_plan": "470712453"
        },
        {
            "variant_id": "39353694126213",
            "quantity": "1",
            "selling_plan": "390299781"
        }
    ],
    "attributes": {
        "checkout[email]": "john.doe@sealsubscriptions.com",
        "checkout[shipping_address][first_name]": "John",
        "checkout[shipping_address][last_name]": "Doe",
        "checkout[shipping_address][address1]": "Seal Subscriptions street 5a",
        "checkout[shipping_address][phone]": "0011231342",
        "checkout[shipping_address][zip]": "10002",
        "checkout[shipping_address][city]": "New York",
        "checkout[shipping_address][province]": "New York",
        "checkout[shipping_address][country]": "US"
    }
}'


Common issues


After pasting the command in terminal, terminal says "zsh: command not found" Why?
This usually means that there is a syntax error in the command your put in the terminal. This can happen if you received the command from your coworker over your favourite messaging tool (e.g. Slack, Microsoft Teams, etc.) and copied the command from there.
These messaging tools ofter change single quotes to some strange quotes which look similar to single quotes and this causses this issue.
To resolve this, simply rewrite the quotes in the command manually and run the command.
To prevent this from happening, try to avoid sending the command over the messaging tools (e.g. Slack, Microsoft Teams) and only copy them from our documentation directly.


API limits

The Seal Subscriptions REST API has a rate limiter, which is currently set to allow 10 requests per API key at a time. This means that if your current requests haven't yet finished processing and you already send another request, the API will return a 503 HTTP error code, with a message in the body, explaining that you hit the limit and how to prevent this from happening in the future.
Because of this, it is recommended that if you hit an API limit, you retry your request at a later time, when the rest of your requests have finished processing.