Settings

Settings control how your Flint integration behaves across checkout, tipping, tax, receipts, inventory, branding, legal, subscriptions, promotions, customer accounts, and customer email delivery. The public surface is merchant-scoped for raw reads and writes, while effective settings resolve the full inheritance chain (organization, merchant, location, and device) into the values a given surface uses. Pass location_id or device_id to see what applies at that scope; device_id takes precedence and resolves its location automatically.

Settings policies add governance on top: a rule like inherit_only, subset_only, min_bound, or max_bound attached to a scope restricts what descendant scopes can set, never the scope it is attached to. payment_limits is operator-managed and read-only on the public API. What Flint charges to process a payment is not a setting; see the Processing fees guide for how that fee is charged and reported.

Tip preselections#

Use PATCH /v1/settings to update tipping. Omitted fields keep their current values. Percentage presets contain exactly three values from 1 through 100. A preselected percentage must match an effective percentage preset; a preselected fixed tip must match an effective fixed preset's amount and currency.

When changing presets, explicitly replace or clear a preselection that the new presets exclude:

JSON
{
  "tipping": {
    "tip_percent_options": [10, 15, 25],
    "default_tip_percent": null
  }
}

Send null for default_tip_percent or default_smart_tip_money to clear the merchant override. Raw settings return the cleared field as null. Effective settings can still inherit a preselection from the organization; read GET /v1/settings/effective to see the result. Preset arrays and tipping booleans do not accept null. default_tip_percent and every tip_percent_options value must be between 1 and 100 with at most four decimal places.

Catalog settings#

Use catalog.default_delivery_profile_id to choose the active delivery profile that new physical products inherit. Read it from GET /v1/settings and change it with PATCH /v1/settings:

JSON
{
  "catalog": {
    "default_delivery_profile_id": "dprof_...",
    "expected_version": 4
  }
}

Use the catalog version returned by GET /v1/settings as expected_version. Use 0 only when catalog settings do not exist yet. Send a catalog change in its own PATCH /v1/settings request. Do not combine it with other settings sections.

This changes the default for new catalog items. It does not replace an existing variant or bundle-component assignment. To fill only unconfigured physical items, call POST /v1/delivery-profiles/{delivery_profile_id}/assign-to-unconfigured with the profile's current version as expected_version. If this action is based on the current default, also send the catalog version as expected_catalog_default_version so a later default change cannot apply the old profile.

Note:

Settings like checkout.enabled_payment_options, checkout.default_expires_in_seconds, and checkout.promotion_code_entry_enabled directly shape hosted surfaces; see the Checkout sessions guide and Payment links guide.

Checkout settings#

Use the top-level checkout object for hosted checkout defaults. Checkout sessions and payment links can override some of these values on the object itself.

FieldTypeDescription
enabled_payment_optionsstring arrayPayment options offered by default on hosted checkout, such as card, apple_pay, and google_pay.
require_emailbooleanRequires buyer email by default.
require_phonebooleanRequires buyer phone by default.
require_billing_addressbooleanRequires billing address by default.
default_expires_in_secondsintegerDefault generic checkout session lifetime, between 60 and 86400. Invoice-owned checkout uses the fixed active invoice-link deadline instead.
promotion_code_entry_enabledbooleanMerchant default for hosted checkout promotion-code entry. Object-level promotion_config.codes_enabled can override it for a checkout session or payment link.
recovery_emailobjectCheckout reminder email, off by default. See Checkout reminder emails.
saved_payment_detailsobjectOffers buyers the option to save the card they type, on by default. See Saved payment details.

First-party Connect settings clients use checkout.isPromotionCodeEntryEnabled for the same hosted-checkout default.

Checkout reminder emails#

checkout.recovery_email sends one email to a buyer who enters an email address at hosted checkout and leaves without paying. It lists the cart and total and links back to checkout.

FieldTypeDescription
enabledbooleanSends reminders. Defaults to false.
delay_secondsintegerSeconds to wait after the buyer last changes their email or phone at checkout, from 900 to 86400, in multiples of 60. Defaults to 3600.
JSON
{
  "checkout": {
    "recovery_email": {
      "enabled": true,
      "delay_seconds": 3600
    }
  }
}

A reminder can count as commercial email, so each one carries an unsubscribe link and the merchant's business address. Turning reminders on therefore requires an address on the merchant with a street, city, postal code, and country; without one, PATCH /v1/settings returns 400 with CHECKOUT_RECOVERY_EMAIL_ADDRESS_REQUIRED. If the address is removed later, no reminders go out until it is back.

Which checkouts send one:

  • A hosted checkout session for an order, including one a one-time payment link opens, after the buyer saves an email as buyer_contact.
  • Never an embedded session, or a checkout for an invoice, a subscription plan, or a return.

When the reminder is due, Flint checks again and sends nothing if reminders were turned off, the buyer cleared their email, the checkout was paid, closed, or replaced, or the order was paid or closed or has nothing left to pay. A reminder that sends nothing doesn't block a later one: the next time the buyer saves an email while reminders are on, a new reminder is scheduled. While a payment on the order is still in progress, such as a card waiting on 3D Secure or a bank debit that takes days to settle, the reminder waits, including when the payment starts just before the email goes out. It goes out if that payment fails, is canceled, or is abandoned, and not at all once the order is paid. An expired order checkout still gets its reminder, because the link can open a new checkout for the same order. An expired payment link checkout does not.

Each checkout session sends at most one reminder, and a buyer gets at most one from the same merchant per UTC day. The unsubscribe link, and the one-click unsubscribe header mail clients show, stop checkout reminders from that merchant only. Receipts and other emails keep arriving.

The link in the email works for 7 days and resolves when the buyer opens it:

When openedThe buyer sees
The checkout is still openThat checkout
The checkout expired and the order is still unpaidA new checkout for the same order. Opening the link again returns that checkout while it's open. Payment link checkouts can't be reopened this way.
The order was paidA page saying it's already paid
Anything else, including after 7 daysA page saying the link no longer works

The reminder goes to the email saved at checkout, which nobody confirmed, so a checkout opened from the link doesn't use the saved cards or details of a customer whose email the buyer confirmed with a code earlier. The buyer confirms their email again to use them. A customer you created the session for is unaffected.

Saved payment details#

checkout.saved_payment_details controls the unchecked option hosted checkout shows under the card fields: "Save my details for faster checkout at {business name}".

FieldTypeDescription
enabledbooleanOffers the option. Defaults to true. A merchant setting that locations and devices can't override.
JSON
{
  "checkout": {
    "saved_payment_details": {
      "enabled": false
    }
  }
}

Nothing is saved unless the buyer checks the option and the payment succeeds. The card is then saved for the customer the checkout acts for, as a payment method with usage: "on_session": the customer you created the session for or, for a guest, the customer whose email the buyer confirmed with a code Flint emailed them. Flint charges such a card only in checkouts the buyer completes. It can't pay a subscription or an automatic invoice or become a customer's default, so it never pays for something without the buyer. See Cards buyers save in checkout.

Checkout never offers the option:

  • When customer_account.mode is merchant_hosted, because your own accounts own the buyer's saved cards.
  • On a checkout for an invoice, a subscription plan, or a return.
  • For Apple Pay, Google Pay, ACH debit, or Affirm. Only a card the buyer types can be saved this way.
  • On a checkout created for no customer, until Flint can email codes for your account.

A checkout session read with its checkout credential reports the result as save_payment_method_offered.

Inventory settings#

Use the top-level inventory object to decide what happens when stock cannot be honored. It does not hold quantities; those live on inventory levels.

FieldTypeDescription
low_stock_thresholdintegerThe available quantity your team treats as low stock. Flint stores it and surfaces it in the dashboard; it does not change allocation, and the API does not filter or alert on it for you.
origin_policiesobjectFailure handling keyed by order source.

origin_policies is keyed by where the order came from: checkout, payment_link, api, subscription, virtual_terminal, or default. Flint uses the entry matching the order's source and falls back to default. Each entry holds:

FieldValuesDescription
post_payment_inventory_failure_actionexception_state, auto_refundWhat happens when payment succeeds but stock cannot be committed. exception_state leaves the order at inventory_exception_status: "paid_inventory_failed" for an operator to resolve; auto_refund refunds the payment without asking.
subscription_inventory_block_actioninventory_blocked_open_invoice, past_dueWhat happens when a subscription renewal cannot get stock. The first leaves the invoice open and uncollectible; the second moves the subscription to past due.
JSON
{
  "inventory": {
    "low_stock_threshold": 5,
    "origin_policies": {
      "default": { "post_payment_inventory_failure_action": "exception_state" },
      "checkout": { "post_payment_inventory_failure_action": "auto_refund" }
    }
  }
}

Promotion settings#

Use the top-level promotions object to control promotion evaluation.

FieldTypeDescription
automatic_enabledbooleanEnables automatic promotion evaluation.
codes_enabledbooleanMerchant promotion-code redemption policy. Explicit false rejects promotion-code application even if a checkout session or payment link asks to show code entry.
max_promotions_per_orderintegerCaps pricing-active promotion discounts per order. Must be between 1 and 10.

Branding settings#

Use the top-level branding object to style the pages Flint hosts for your buyers: checkout, including payment link pages, and the customer account. A checkout session's or payment link's theme can override primary_color and accent_color; the other fields always come from these settings. Flint adjusts or replaces a color that wouldn't be readable, such as text too close to the background color.

FieldTypeDescription
primary_colorstringSix-digit hex, such as #1B4D3E. Used for primary actions.
accent_colorstringSix-digit hex. Used for links, focus rings, and selected options. Defaults to the primary color.
background_colorstringSix-digit hex. Page background.
text_colorstringSix-digit hex. Body text.
font_familystringOne of instrument_sans, system_sans, system_serif, monospace.
corner_radiusintegerBorder radius in pixels, between 0 and 32.

Subscription settings#

Use the top-level subscriptions object to choose the default schedule owner and failed-payment policy. Read effective settings when you need the inherited values that a new subscription or billing workflow will use.

FieldValuesDescription
default_billing_schedule_ownerflint, externalSchedule owner used when create omits billing_schedule. Defaults to flint.
dunning_end_actioncancel, pause, notify_onlyAction after automatic retries for Flint-owned subscriptions. Defaults to cancel.
external_dunning_end_actioncancel, pause, notify_onlyAction after automatic retries for external schedules. If unset, effective settings use notify_only; the global action does not override that owner-specific default.
dunning_retry_daysintegerRetry window from 1 to 90 days. Defaults to 16.
JSON
{
  "subscriptions": {
    "default_billing_schedule_owner": "external",
    "external_dunning_end_action": "notify_only",
    "dunning_retry_days": 16
  }
}

notify_only leaves an exhausted subscription past_due so your integration can update the payment method and create a manual payment retry. See Subscription billing.

Invoice settings#

Use the top-level invoices object for the defaults an invoice inherits at create time and the follow-up Flint runs after you issue it. The values that drive follow-up are frozen onto the invoice at issue, so editing them changes new invoices and leaves the ones already collecting alone.

FieldTypeDescription
reminder_policyobjectrules is a list of days_from_due offsets. A reminder fires at each offset while a balance remains; negative offsets fire before the due date. Empty means no automatic reminders.
autopay_retry_policyobjectretry_day_offsets is a list of days from a failed charge at which Flint retries the saved card on an automatic invoice.
timezonestringIANA zone used to count reminder and late fee days, so an offset lands at the same local time year-round. Invoices inherit it at issue.
default_collection_modebuyer_initiated, automatic, externalCollection mode used when a draft passes merchant_default.
default_invoice_payment_term_idstringPayment term used when a draft passes merchant_default for payment_due. The term carries the due-date calculation and the late fee policy.
payment_policyobjectPayment options offered on the hosted invoice page by default.
invoice_number_prefixstringPrefix on assigned invoice numbers.
credit_note_number_prefixstringPrefix on assigned credit note numbers. Defaults to CN-.
reply_to_emailstringWhere customer replies to invoice email go.
remit_to_addressobjectThe address printed on the invoice and its PDF.
default_memo, default_footerstringMemo and fine print used when a draft does not set its own.
JSON
{
  "invoices": {
    "reminder_policy": {"rules": [{"days_from_due": -3}, {"days_from_due": 7}]},
    "autopay_retry_policy": {"retry_day_offsets": [1, 3, 7]},
    "timezone": "America/New_York",
    "credit_note_number_prefix": "CN-"
  }
}

Late fees come from the payment term rather than from settings. When the term carries a late fee policy, Flint emits invoice.late_fee_due after the grace period with the computed amount. Charging it is a separate call that adds the fee to the invoice balance. See Late fees.

Customer account settings#

Use the top-level customer_account object to choose where buyers manage their orders, subscriptions, and Returns, and what that surface looks like. Flint sends every account link in transactional email to whatever this object currently says, resolved when the buyer clicks. See the customer accounts guide.

customer_account and customer_email_delivery are merchant settings. Locations and devices can't override them.

Send "customer_account": null to remove the account configuration. Flint then serves the default Flint-hosted account, and GET /v1/settings omits customer_account. If the configuration had a presentation.custom_domain, removing it starts the same redirect window as removing the hostname.

FieldTypeDescription
modeflint_hosted, merchant_hostedWho serves the account. Defaults to flint_hosted.
merchant_account_urlstringRequired when mode is merchant_hosted. HTTPS URL on a verified payment method domain or a subdomain of one.
route_templatesobjectOptional per-resource paths for merchant_hosted. Keys are order, subscription, and return; each value uses {resource_id} once.
presentationobjectBranding of Flint's hosted account. Only valid when mode is flint_hosted.
buyer_capabilitiesobjectWhat buyers may do to their own subscriptions, in either mode. Written as a whole: each update replaces it, and fields it omits take their defaults.

presentation holds:

FieldTypeDescription
account_namestringName shown in the account. Defaults to your business name.
custom_domainstringExact ASCII/Punycode subdomain to serve the account from, such as account.example.com. Apex and wildcard hostnames are not supported. Register the hostname as an active payment method domain first. Flint verifies DNS control before activating it.

The two modes are mutually exclusive about which fields they accept. Sending presentation with merchant_hosted, or merchant_account_url or route_templates with flint_hosted, returns CUSTOMER_ACCOUNT_MODE_CONFLICT.

JSON
{
  "customer_account": {
    "mode": "flint_hosted",
    "presentation": {
      "account_name": "Cedar & Stone",
      "custom_domain": "account.cedarandstone.com"
    }
  }
}

buyer_capabilities holds:

FieldTypeDescription
cancellation_timingend_of_period, buyer_choosesWhen a buyer's cancellation ends. buyer_chooses also lets the buyer end it right away. Defaults to end_of_period.
pause.enabledbooleanWhether buyers may pause. Defaults to true.
pause.max_cyclesintegerThe longest pause a buyer may choose, 1 to 12 billing periods. Omit it for no limit.
cancellation_reasonsarrayUp to 8 of too_expensive, missing_features, switched_service, unused, customer_service, too_complex, low_quality, and other, each once, in the order buyers see them. Empty asks no reason.
retention_offer.kindnone, pause_insteadThe offer a buyer sees before canceling. Defaults to none. pause_instead needs pause.enabled.
retention_offer.pause_cyclesintegerBilling periods the offered pause lasts, 1 to 12 and at most pause.max_cycles. Required with pause_instead.

Buyers can always cancel. Requests made with your API key aren't limited by buyer_capabilities. See What buyers can do to their subscriptions.

customer_account_domain_status#

Read-only. Present once a custom_domain is set, and the only place the DNS records come from.

FieldTypeDescription
hostnamestringThe hostname being provisioned.
domain_statusprovisioning, active, attention_requiredattention_required means the hostname needs a DNS or certificate correction.
dns_recordsarrayRecords to publish. Exact subdomains currently return one cname record with name and value.
last_checked_atstringRFC3339 instant of the last health check.

While the hostname is anything other than active, account links keep working on Flint's own domain. Buyers are never sent to a hostname that does not resolve.

Customer email delivery settings#

Use the top-level customer_email_delivery object to decide, per family of buyer email, whether Flint sends it or you do. Each field takes flint_sends (the default) or merchant_sends.

FieldCovers
order_receiptsPurchase receipts
fulfillment_updatesShipment and delivery notices
subscription_lifecycleRenewals, pauses, cancellations, trial endings
dunningFailed payment and past-due notices
returnsReturn approvals, labels, and resolutions
invoicesInvoice delivery and reminders

Setting a family to merchant_sends stops Flint's email for that family only. The webhook events behind it keep firing, which is how you send your own.

Get merchant settings#

GET/v1/settings

Requires scope settings.read or settings.write

Returns the raw merchant-scoped settings record for the authenticated merchant. No inheritance is applied.

Response · 200

dataobjectRequired
metaobject
request_idstring
curl https://api.withflintpay.com/v1/settings \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY"
JSON
{
  "data": {
    "branding": {
      "accent_color": "#f59e0b",
      "primary_color": "#0f766e"
    },
    "catalog": {
      "default_delivery_profile_id": "dprof_01J9K7M6N5P4Q3R2S1T0UVWXYZ",
      "updated_at": "2026-03-17T14:30:00Z",
      "version": 4
    },
    "checkout": {
      "default_expires_in_seconds": 3600,
      "enabled_payment_options": [
        "card",
        "apple_pay",
        "google_pay"
      ],
      "promotion_code_entry_enabled": true,
      "require_email": true
    },
    "created_at": "2026-03-17T14:30:00Z",
    "inventory": {
      "low_stock_threshold": 5,
      "origin_policies": {
        "default": {
          "post_payment_inventory_failure_action": "exception_state"
        },
        "subscription": {
          "subscription_inventory_block_action": "inventory_blocked_open_invoice"
        }
      }
    },
    "legal": {
      "require_terms_of_service": true,
      "terms_of_service_url": "https://example.com/terms"
    },
    "merchant_id": "mer_123",
    "metadata": {
      "channel": "retail"
    },
    "payment_limits": {
      "max_amounts": {
        "default": {
          "amount": 100000,
          "currency": "USD"
        },
        "payment_link": {
          "amount": 250000,
          "currency": "USD"
        }
      },
      "min_amounts": {
        "default": {
          "amount": 50,
          "currency": "USD"
        },
        "payment_link.donation": {
          "amount": 100,
          "currency": "USD"
        }
      }
    },
    "promotions": {
      "automatic_enabled": true,
      "codes_enabled": true,
      "max_promotions_per_order": 2
    },
    "receipts": {
      "header_text": "Thanks for your purchase",
      "is_auto_email_enabled": true
    },
    "settings_id": "set_123",
    "settings_scope": "merchant",
    "subscriptions": {
      "dunning_end_action": "cancel",
      "dunning_retry_days": 16
    },
    "tax": {
      "default_enabled": true
    },
    "tax_identity": null,
    "tipping": {
      "default_enabled": true,
      "default_smart_tip_money": null,
      "default_tip_percent": 18,
      "is_custom_tip_enabled": true,
      "tip_percent_options": [
        15,
        18,
        20
      ]
    },
    "updated_at": "2026-03-17T14:30:00Z",
    "version": 0
  },
  "request_id": "bce56cba-0827-44aa-bb56-4f200ba15ee6"
}

Update merchant settings#

PATCH/v1/settingsIdempotent

Requires scope settings.write

Applies a sparse patch to merchant-scoped settings. Send catalog by itself because it has its own version fence. Fee and payment limit controls remain internal-only.

Request body

brandingobject
catalogobject
checkoutobject
customer_accountobject or null

Send null to remove the account configuration. Flint then serves the default Flint-hosted account, and GET /v1/settings omits customer_account.

customer_email_deliveryobject
expected_versioninteger

Required when replacing tax_ids or clearing tax_identity. Stale versions return a conflict.

fulfillmentobject
inventoryobject
invoicesobject or null
legalobject
metadatamap of string or null

Caller-owned metadata. Omit this field to leave metadata unchanged. Send an object to merge by key, set a key to null to remove it, or set metadata to null to clear all metadata. An empty object makes no change. Empty strings are stored. Keys starting with flint_ are reserved and cannot be written through the public API.

promotionsobject
receiptsobject
subscriptionsobject
taxobject
tax_identityobject or null

Merchant-provided legal identity displayed on invoices and credit notes. Does not verify IDs or change tax treatment. Tax IDs are an owned collection in display order; replacing the array requires the parent's expected_version. Existing entries retain their document_tax_id; omit an entry to remove it, or omit its ID to add one.

tippingobject

Response · 200

Same response as Get merchant settings.

curl -X PATCH https://api.withflintpay.com/v1/settings \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "checkout": {
      "enabled_payment_options": [
        "card",
        "apple_pay",
        "google_pay"
      ],
      "promotion_code_entry_enabled": true,
      "require_email": true
    },
    "metadata": {
      "channel": "omnichannel"
    },
    "promotions": {
      "codes_enabled": true
    },
    "receipts": {
      "footer_text": "Come back soon"
    }
  }'

Validate a custom domain#

POST/v1/settings/custom-domains/{domain_type}/validateIdempotent

Requires scope settings.write

Rechecks ownership and restarts validation for the configured checkout or customer account hostname. Send no request body or an empty JSON object. Each domain can be checked once every 60 seconds; rate limited responses include Retry-After.

Path parameters

domain_typeenumRequired
  • checkout
  • customer_account

Response · 200

dataobjectRequired
request_idstringRequired
curl -X POST https://api.withflintpay.com/v1/settings/custom-domains/{domain_type}/validate \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY"

Get effective settings#

GET/v1/settings/effective

Requires scope settings.read or settings.write

Returns the fully resolved effective settings for the authenticated merchant. Optional device_id or location_id can be used to resolve inherited overrides.

Query parameters

location_idstring

Optional Flint location ID to resolve effective settings for.

device_idstring

Optional Flint device ID to resolve effective settings for. When set, the device location takes precedence.

Response · 200

Same response as Get merchant settings.

curl https://api.withflintpay.com/v1/settings/effective \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY"
JSON
{
  "data": {
    "branding": {
      "accent_color": "#f59e0b",
      "primary_color": "#0f766e"
    },
    "catalog": {
      "default_delivery_profile_id": "dprof_01J9K7M6N5P4Q3R2S1T0UVWXYZ",
      "updated_at": "2026-03-17T14:30:00Z",
      "version": 4
    },
    "checkout": {
      "default_expires_in_seconds": 3600,
      "enabled_payment_options": [
        "card",
        "apple_pay",
        "google_pay"
      ],
      "promotion_code_entry_enabled": true,
      "require_email": true
    },
    "created_at": "2026-03-17T14:30:00Z",
    "device_id": "dev_123",
    "inventory": {
      "low_stock_threshold": 5,
      "origin_policies": {
        "default": {
          "post_payment_inventory_failure_action": "exception_state"
        },
        "subscription": {
          "subscription_inventory_block_action": "inventory_blocked_open_invoice"
        }
      }
    },
    "legal": {
      "require_terms_of_service": true,
      "terms_of_service_url": "https://example.com/terms"
    },
    "location_id": "loc_123",
    "merchant_id": "mer_123",
    "metadata": {
      "channel": "retail"
    },
    "payment_limits": {
      "max_amounts": {
        "default": {
          "amount": 100000,
          "currency": "USD"
        },
        "payment_link": {
          "amount": 250000,
          "currency": "USD"
        }
      },
      "min_amounts": {
        "default": {
          "amount": 50,
          "currency": "USD"
        },
        "payment_link.donation": {
          "amount": 100,
          "currency": "USD"
        }
      }
    },
    "promotions": {
      "automatic_enabled": true,
      "codes_enabled": true,
      "max_promotions_per_order": 2
    },
    "receipts": {
      "header_text": "Thanks for your purchase",
      "is_auto_email_enabled": true
    },
    "settings_id": "set_123",
    "settings_scope": "device",
    "subscriptions": {
      "dunning_end_action": "cancel",
      "dunning_retry_days": 16
    },
    "tax": {
      "default_enabled": true
    },
    "tax_identity": null,
    "tipping": {
      "default_enabled": true,
      "default_smart_tip_money": null,
      "default_tip_percent": 18,
      "is_custom_tip_enabled": true,
      "tip_percent_options": [
        15,
        18,
        20
      ]
    },
    "updated_at": "2026-03-17T14:30:00Z",
    "version": 0
  },
  "request_id": "bce56cba-0827-44aa-bb56-4f200ba15ee6"
}

Was this helpful?