Skip to main content
When migrating data into Firmhouse, you can import subscriptions and ordered products using CSV files. This guide documents the required fields, formats, and validation rules for each import type.

Overview

Firmhouse supports two types of data imports:
  1. Subscriptions Import - Import customer subscription records with their details, addresses, and billing information
  2. Ordered Products Import - Import products associated with subscriptions (requires subscriptions to be imported first)
Both imports use CSV files with semicolon (;) separators. You can download empty templates directly from the import pages in the Firmhouse Portal.

Subscriptions Import

The subscriptions import allows you to migrate customer subscription data from your previous system. Each row in the CSV represents one subscription.

Identification Fields

FieldRequiredFormatDescription
imported_subscription_idYesStringThe unique subscription identifier from your previous system. This prevents importing the same subscription twice and allows you to track which subscriptions have been migrated. Must be unique across all rows.
imported_customer_idNoStringThe unique customer identifier from your previous system. Used for reference and tracking purposes, but not required for the migration to work.
customer_idNoStringThe customer ID from Mollie payment provider, if you’re using Mollie for payments. This links the subscription to the customer record in Mollie’s system. Only needed if you’re migrating from a Mollie-based system.
shopify_customer_idNoString (gid://shopify/Customer/[digits])The Shopify customer ID if this subscription is linked to a Shopify customer. Used to sync customer data and orders between your subscription system and Shopify.
stripe_customer_idNoStringThe Stripe customer ID if you’re using Stripe for payments. This links the subscription to the customer record in Stripe, allowing you to charge the customer through Stripe.

Customer Details

FieldRequiredFormatDescription
emailYesValid email addressThe customer’s email address. This is used for account access, order confirmations, and all customer communications. Must be a valid email format.
nameYesStringThe customer’s first name. Used for personalization in communications and shipping labels.
last_nameYesStringThe customer’s last name. Used for personalization in communications and shipping labels.
company_nameNoStringThe company name if this is a business subscription. Leave empty for consumer subscriptions.
phone_numberNoStringThe customer’s phone number. Used for shipping notifications and customer support. Include country code if applicable.
localeYesnl, en, de, sv, fr, pl, fi, it, ro, esThe language preference for customer communications, emails, and the self-service portal. Determines which language version of emails and notifications the customer receives.
marketing_opt_inYestrue, falseWhether the customer has consented to receive marketing emails and promotional communications. Set to ‘true’ if they opted in, ‘false’ if they opted out. Required for GDPR compliance.

Shipping Address

FieldRequiredFormatDescription
addressYesStringThe street address where products will be shipped. This is the primary shipping address for the subscription.
house_numberNoStringThe house or building number. Some countries require this to be separate from the street address for proper address validation.
house_number_additionNoStringAdditional information for the address, such as apartment number, floor, or building unit. Examples: ‘A’, ‘2nd floor’, ‘Unit 5’.
cityYesStringThe city where the customer is located. Used for shipping calculations and address validation.
zipcodeYesStringThe postal or ZIP code. Format varies by country (e.g., ‘1234AB’ for Netherlands, ‘12345’ for US). Used for shipping and address validation.
countryYesISO 3166-1 alpha-2 code (e.g., NL, US, DE)The country code where the customer is located. This affects shipping costs, tax calculations, and currency.

Billing Address

All billing address fields are optional. Only fill these if the billing address is different from the shipping address. If left empty, the shipping address will be used for billing.
FieldRequiredFormatDescription
bill_to_company_nameNoStringCompany name for the billing address, if different from shipping address.
bill_to_nameNoStringFirst name for the billing address.
bill_to_last_nameNoStringLast name for the billing address.
bill_to_addressNoStringStreet address for billing.
bill_to_house_numberNoStringHouse number for the billing address.
bill_to_cityNoStringCity for the billing address.
bill_to_zipcodeNoStringPostal code for the billing address.
bill_to_countryNoISO 3166-1 alpha-2 code (e.g., NL, US, DE)Country code for the billing address.

Subscription Status and Dates

FieldRequiredFormatDescription
statusYesinactive, activated, paused, cancelled, stopped, one_time_purchaseThe current state of the subscription. ‘activated’ means the customer is active and being billed. ‘paused’ means temporarily stopped but will resume. ‘cancelled’ or ‘stopped’ means permanently ended. ‘inactive’ means the subscription exists but hasn’t been activated yet. ‘one_time_purchase’ means a single purchase without recurring billing.
signup_completed_atYesYYYY-MM-DD HH:MM[+HH:MM]When the customer completed the signup process. This is the timestamp when they finished registration, not when they first started. Used to track customer journey and calculate subscription age.
activated_atYesYYYY-MM-DD HH:MM[+HH:MM]When the subscription became active and billing started. This is typically when the first payment was successful or when you manually activated the subscription. Used to calculate billing cycles and subscription duration.
cancelled_atNoYYYY-MM-DD HH:MM[+HH:MM]When the subscription was cancelled. Fill this if the status is ‘cancelled’ or ‘stopped’. This date is used to determine when to stop billing and when access should end.
stopped_atNoYYYY-MM-DD HH:MM[+HH:MM]When the subscription was stopped. Fill this if the status is ‘stopped’. Stopped subscriptions are permanently ended and cannot be reactivated, similar to cancelled subscriptions.
paused_atNoYYYY-MM-DD HH:MM[+HH:MM]When the subscription was paused. Only fill this if the status is ‘paused’. Paused subscriptions temporarily stop billing but can be resumed later.
paused_untilNoYYYY-MM-DD HH:MM[+HH:MM]When a paused subscription should automatically resume. If set, the subscription will automatically reactivate on this date. Leave empty if the pause is indefinite.
marked_as_non_paying_atNoYYYY-MM-DD HH:MM[+HH:MM]When the customer was marked as non-paying, typically due to payment failures. This helps track payment issues and may trigger dunning processes or account restrictions.

Plan and Billing

FieldRequiredFormatDescription
next_billing_dateYesYYYY-MM-DDThe date when the next payment will be charged. This is calculated based on the billing cycle, but you can set it manually if needed. After each successful payment, this date automatically advances by the billing cycle interval.
billing_cycle_intervalYesIntegerThe numeric part of the billing frequency. Combined with billing_cycle_interval_unit, this determines how often the customer is charged. Example: if interval is ‘2’ and unit is ‘month’, customer is billed every 2 months.
billing_cycle_interval_unitYesday, week, month, yearThe time unit for the billing cycle. Works together with billing_cycle_interval to define the billing frequency. For example, ‘1’ month means monthly billing, ‘2’ weeks means bi-weekly billing.
shipping_costs_centsNoIntegerShipping costs in cents (not dollars/euros). For example, 500 means $5.00 or €5.00. Only needed if you’re importing Shopify subscriptions with custom shipping costs. Leave empty to use default shipping rates.

Technical and Payment IDs

FieldRequiredFormatDescription
shopify_payment_method_idNogid://shopify/CustomerPaymentMethod/[32 lowercase alphanumeric chars]The Shopify payment method ID (Global ID format). Only needed if this subscription is connected to Shopify and uses Shopify’s payment processing. This links to the saved payment method in Shopify.
stripe_payment_method_idNoString (e.g., pm_1234...)The Stripe payment method ID. This is the saved payment method (card, bank account, etc.) that will be used for recurring charges. Only needed if using Stripe.
stripe_mandate_idNoStringThe Stripe mandate ID for SEPA Direct Debit or other mandate-based payment methods. This is the authorization that allows you to charge the customer’s bank account. Only needed for SEPA or similar payment methods.

Ordered Products Import

The ordered products import allows you to add products to subscriptions that have already been imported. Each row in the CSV represents one product line item on a subscription. Before importing ordered products, you must first import subscriptions using the Subscriptions Import.

Subscription Reference

FieldRequiredFormatDescription
imported_subscription_idYesStringThe ID of the subscription from the original system. Must match a subscription that was previously imported via the Subscriptions import.

Product Identification

You must provide at least one of the following product identifier fields. The system will use the first provided identifier to find the product.
FieldRequiredFormatDescription
shopify_variant_idNogid://shopify/ProductVariant/[digits]The Shopify variant ID (Global ID format) to identify the product. Use this if your product is synced from Shopify.
product_idNoIntegerThe Firmhouse product ID (numeric) to identify the product. Use this if you know the internal product ID in Firmhouse.
skuNoStringThe product SKU (Stock Keeping Unit) to identify the product. Use this if your products are identified by SKU.
imported_product_idNoStringThe product ID from your original system. Use this if you’re migrating products and have mapped them using imported_product_id.

Product Details

FieldRequiredFormatDescription
quantityYesIntegerThe quantity of the product to include in the subscription. This determines how many units of the product will be shipped per order.
shipment_dateNoYYYY-MM-DDThe date when the next shipment should be sent. If not provided, the subscription’s next billing date will be used.
intervalNoIntegerThe numeric part of the shipment interval. Combined with interval_unit_of_measure, this determines how often the product is shipped. Example: if interval is ‘2’ and unit is ‘month’, product ships every 2 months.
interval_unit_of_measureNodefault, day, week, monthThe time unit for the shipment interval. Works together with interval to define shipping frequency. If not provided, defaults to the subscription’s billing cycle.
custom_price_centsNoIntegerA custom price override for this product in cents (not dollars/euros). For example, 500 means $5.00 or €5.00. If not provided, the product’s standard price will be used.

Validation and Import Process

When you upload a CSV file, Firmhouse performs validation before any data is imported:
  1. Format validation - The CSV file is checked for proper formatting and required columns
  2. Field validation - Each row is validated for required fields and correct data formats
  3. Reference validation - For ordered products, the system validates that referenced subscriptions exist
Validation errors are reported for each problematic row, allowing you to fix issues and re-upload the file. No data is imported until you explicitly execute the migration after validation passes.

Tips for Successful Imports

  • Download the empty CSV template from the import page to ensure you have all the correct column headers
  • Use semicolons (;) as field separators
  • Ensure all required fields are filled in for each row
  • Use the correct date and time formats as specified
  • For ordered products, make sure all referenced subscriptions have been imported first
  • Review validation errors carefully and fix all issues before executing the import