Create and update products

Create and edit products. If you are creating products in bulk, you can add up to 300 at a time.

{
  "products": [
    {
      "product": "product-one",
// Required. Must be a valid product path/ID: alphanumeric, all lower-case, no special characters except dash "-", must be greater than two characters in length
      "display": {
// Required at least in English
        "en": "String"                                                          
      },
      "description": {
        "summary": {
          "en": "String"
// This field also supports Markdown.
        },
        "action": {
          "en": "String"                                                        
        },
        "full": {
          "en": "String"
// This field also supports Markdown.
        }
      },
      "fulfillment": {
        "instructions":{
// Optional Post Order Instructions (e.g., for a 'thank you message' and directions on how to register the product)
          "en":"String",
// This field also supports Markdown.
          "es":"String"
// This field also supports Markdown.
        } 
      },
      "fulfillments": [ 
            { 
               "type":"file",
// Required.                                   
               "url":"http://somedomain.net/files/8675309/filename.exe"",
// Required when uploading a new fulfillment file; specify external file URL for FastSpring to retrieve 
               "display":"filename.exe",
// Required fulfillment file name; extension must match file specified in URL
               "applicability":"ALWAYS",
// Or "BASE", "CONFIGURATION", "REBILL_ONLY", "NON_REBILL_ONLY", 
               "behavior":"CURRENT"
// Or "PREFER_EXPLICIT"; 
            } 
         ], 
      "image": "http://somedomain.net/images/8675309/filename.jpg"",
// Product icon image
      "format": "digital",
// Or "physical" or "digital-and-physical"
      "sku": "string", 
      "taxcode": "DC020502",
// Optional SKU ID string
      "attributes": {
// Strings. Custom key / value attributes that will be passed back once this product is purchased (aggregate limit of approximately 4,000 characters total).
        "key1": "value1",
        "key2": "value2",
        ...
      }, 
      "pricing": {
        "trial": 2,
// Days, only needed if you are creating a subscription
        "interval": "month",
// Or "adhoc", "day", "week", "year", only needed if you are creating a subscription
        "intervalLength": 1,
// Required if "interval" is specified and is not "adhoc"
        "quantityBehavior": "allow",
// Or "lock" or "hide"
        "quantityDefault": 1,
        "price": {
          "USD": 14.95,
// Currency must be enabled in the Store Settings
          "EUR": 10.99
        },
        "setupFee": {
// Optional one-time setup fee for subscriptions; if set, this cannot be removed from the order. The amount will not be included in future rebills.
          "title":{"en":"Setup fee title"},
// Optional description of the one-time setup fee, format "language code":"string"
          "price":{"USD":10}
// Amount of the one-time setup fee, format "currency":amount
        },
        "quantityDiscounts": {
// "Volume Discounts". Support percentage or "amount off". Mixed values are not supported. 
          10: 25.00,
// Quantity: percentage off. Everything more than 10 units will be discounted by 25%.
          30: {"USD": 25.00, "EUR": 15}
// Quantity: amount off in each supported currency. This value will be subtracted from the product price.
        },
        "discountReason": {
          "en": "The Reason"
        },
        "discountDuration": 1,
        "dateLimitsEnabled": true,
// Pass "true" if you want to limit product discount availability by date range (for subscriptions, this only applies to the initial order).
		"dateLimits": {
          "start": "2020-06-05 12:00",
// Beginning date for the discount availability. YYYY-MM-DD 00:00 GMT, or pass the date in milliseconds.
		  "end": "2020-07-04 19:33"
// Expiration date for the discount. YYYY-MM-DD 00:00 GMT, or pass the date in milliseconds.
		}
      }
    },
    {
      ...next product definition...
    }
  ]
}
{
  "errors": [
    {
      "product": "product-id",
      "error": {
        "product": "product is required",
// "product" is required when creating a new product
        "display": "display is required",
// "display" is required when creating a new product
        "interval": "intervalLength must be specified",
// "intervalLength" is required if "interval" is specified
        "intervalLength": "interval must be specified",
// "interval" is required if "intervalLength" is specified
        "renew": "interval must be specified",
// or "intervalLength must be specified" or "interval and intervalLength must be specified"
        "trial": "interval must be specified",
// or "intervalLength must be specified" or "interval and intervalLength must be specified"
        "discountDuration": "interval must be specified",
// or "intervalLength must be specified" or "interval and intervalLength must be specified"
        "discountDuration": "quantityDiscounts must be specified",
        "discountReason": "quantityDiscounts must be specified"
      }
    }
  ]
}

Set a Product's Badge and Rank

The badge is a string that you can assign to a product, making it easier to highlight those that are either the most popular or provide the best value. This can be displayed to customers to help them make informed purchase decisions.

The rank attribute enables you to control the positioning of a product relative to others within the same group or list. By setting the rank value, you can determine the order in which products are presented to customers, allowing you to emphasize certain offerings or tailor their display.

To set the badge and rank attributes, you can use the Products endpoint with a POST request. Below is an example request and response:

POST https://api.fastspring.com/products

{
    "products": [
        {
            "product": "free",
            "rank": 1
        },
        {
            "product": "basic",
            "badge": {
                "en": "Basic"
            },
            "rank": 2,
            "badge": "essential"
        },
        {
            "product": "standard",
            "badge": {
                "en": "best value"
            },
            "rank": 3
        },
        {
            "product": "standard",
            "rank": 4
        },
        {
            "product": "enterprise",
            "rank": 5
        }
    ]
}
{
    "products": [
        {
            "product": "free",
            "action": "product.update",
            "result": "success"
        },
        {
            "product": "basic",
            "action": "product.update",
            "result": "success"
        },
        {
            "product": "standard",
            "action": "product.update",
            "result": "success"
        },
        {
            "product": "standard",
            "action": "product.update",
            "result": "success"
        },
        {
            "product": "enterprise",
            "action": "product.update",
            "result": "success"
        }
    ]
}

Creating a Trial without Payment Method

Use the following fields to create a trial subscription without requiring a payment method:

  • paymentCollected: boolean (optional), true by default if It is not present in the payload. If paidTrial is true this field is ignored.
  • paidTrial : boolean (optional), false by default if it is not present in the payload
  • trialPrice: Map values (mandatory if paidTrial is true), similar to price. "trialPrice": { "USD": 14.95, "EUR": 10.99 } trialPrice must be defined if paidTrial is true. If paidTrial is set false trialPrice values are ignored
{
    "products":[
        {
            "product": "basic-trial-without-payment-method",
            "display": {
                "en": "Basic - no card required" 
            },
            "description": {
                "summary": {
                    "en": "Second product created from the API"
                }
            },
            "pricing": {
                "quantityDefault": 1,
                "interval": "month",
                "intervalLength": 1,
                "trial": 30,
                "paymentCollected": true,
                "paidTrial": true,
                "trialPrice": {
                    "USD": 21.99,
                    "EUR": 19.99
                },
                "price": {
                    "USD": 21.99
                }
            }
        }
    ]
}

Constraint: A setup fee is ignored when creating a trial subscription that does not collect a payment instrument. This is when paymentCollected = false and paidTrial = false. If setupFee object is sent in the request, then the response will contain the following error message:

{
    "products": [
        {
            "product": "basic-trial-without-payment-method",
            "action": "product.create",
            "result": "error",
            "error": {
                "setupFee": "Cannot be applied when a free trial without payment method required is set up"
            }
        }
    ]
}

Constraint: The trial price has to be set when creating a trial subscription. This is when paidTrial is true and trialPrice not defined. When this constraint is violated, then the response will contain the following error message:

{
    "products": [
        {
            "product": "basic-trial-without-payment-method",
            "action": "product.create",
            "result": "error",
            "error": {
                "trialPrice": "price must be defined"
            }
        }
    ]
}

Constraint: The trial price must be greater than zero (trialPrice = 0.0). When this constraint is violated, then the response will contain the following error message:

{
    "products": [
        {
            "product": "no-one-knows-test7",
            "action": "product.update",
            "result": "error",
            "error": {
                "trialPrice": "\"USD\" price may not be zero or less"
            }
        }
    ]
}
Language
Authorization
Basic
base64
:
Click Try It! to start a request and see the response here!