Skip to content
2Performant
Ad platforms

2Performant feed for Shopify

2Performant, the Romanian affiliate network whose platform is now branded Business League, lets publishers promote your products for a commission, and the product supply is one CSV file you host at a URL they fetch three to four times a day. Feedflock turns your Shopify catalog into exactly that file: a header row of 2Performant's own field labels so the mapping step is a no-op, prices as bare numbers, availability in their six-value vocabulary, regenerated on your schedule, as often as every hour.

01 · ShopifyProduct in the catalog
Linen shirt SandNordlin · Men's shirtsSKU-2048 · S–XL
Price
259 lei
In stock
0 pcs
When out of stock
02 · twoperformant.csvUpdated just now
Title;Description;Sale price;Old price;Category;Brand;GTIN;Product URL;Images;Product ID;Availability
"Linen shirt Sand M";"Breathable linen shirt with a relaxed regular fit.";259.00;;Men's shirts;Nordlin;8594000123453;https://shop.example.ro/products/linen-shirt-sand?variant=46012345678901;"https://cdn.shop.example.ro/img/linen-shirt-sand.jpg,https://cdn.shop.example.ro/img/linen-shirt-sand-back.jpg";46012345678901;0
−20% off compare-at
ProductOld priceSale price
Linen shirt Sand259.00 lei207.20 lei
Mug Fjord 350 ml79.00 lei63.20 lei
Backpack Ridge 28 l449.00 lei359.20 lei
Soy candle Les95.00 lei76.00 lei
Wool scarf Fjell179.00 lei143.20 lei
212.20 leisaved across these products
5 / 5products with an old price
Sale prices

Old price: only when the discount is real.

2Performant's Sale price is simply the price you charge: mandatory, a bare dot-decimal number, read in the program's currency. Old price is the pre-discount reference, and it stays empty when there is no discount: an always-filled old price invents a permanent markdown that every affiliate repeats. Feedflock maps Old price from your compare-at price, so the pair tells the truth in both directions.

Feed health

Catch feed issues before 2Performant does.

Before every generation Feedflock checks that every field the channel requires is filled, and, on templates verified against the channel's own spec, that the values fit its rules. Most problems are fixed with one click, without editing products in Shopify.

Feed quality · twoperformant.csv
75 / 100
To review: 4
Product ID is not a number on 14 variantsThe spec is explicit: "Internal ID of the product. Must be a number." A SKU like SKU-2048 violates it; the default mapping uses Shopify's numeric variant ID.
Availability outside the six accepted values on 6 productsAvailability knows only 0, 1, In Stock, Backorder, Out Of Stock and Preorder. A value like "available" is not in the vocabulary.
Price with a currency or a thousands separator on 9 productsSale price must be a number with a dot decimal and no thousands separator: "259,00 lei" is not a number. No currency column exists anywhere in the feed.
Title over 255 characters on 3 productsTitle carries the spec's one length limit: 255 characters. Affiliates show it verbatim, and the excess would be lost on import.

Setup

Live in five steps

From a bare Shopify store to a listed offer: the whole setup fits into one coffee break.

  1. Open an advertiser program

    Register your program on 2Performant. The platform is branded Business League. The program and its commissions are what affiliates sign up to. A feed is not mandatory to launch, but affiliates running price-comparison and aggregator sites rely on it.

  2. Install Feedflock

    Add Feedflock from the Shopify App Store. It reads your products, variants, stock and images directly through the Shopify API.

  3. Pick the 2Performant template

    One row per variant, with a header row of their own field labels, identical to their sample CSV. The numeric Shopify variant ID goes out as Product ID, availability as 1/0, and Old price from your compare-at price, empty when there is no discount.

  4. Decide what the spec leaves open

    Category is your own tree. No 2Performant taxonomy is mandated. Description is plain text by default (their whitelist of simple HTML tags is one mapping away), availability can send the worded states instead of 1/0, and Brand, GTIN and up to four custom fields are ready when you need them.

  5. Paste the feed URL

    In your advertiser account: Tools → Product Feeds → New Feed, and paste the hosted URL. 2Performant fetches it 3-4 times a day (the schedule can be adjusted), and with the template's header the column mapping is just confirming each column. Already running a Google Merchant feed? That URL is accepted verbatim too.

    https://feedflock.appfleece.com/f/demo-twoperformant/twoperformant.csv

The feed

What the channel receives

twoperformant.csv
Title;Description;Sale price;Old price;Category;Brand;GTIN;Product URL;Images;Product ID;Availability
"Linen shirt Sand M";"Breathable linen shirt with a relaxed regular fit.";259.00;;Men's shirts;Nordlin;8594000123453;https://shop.example.ro/products/linen-shirt-sand?variant=46012345678901;"https://cdn.shop.example.ro/img/linen-shirt-sand.jpg,https://cdn.shop.example.ro/img/linen-shirt-sand-back.jpg";46012345678901;1
Live preview
Linen shirt Sand

Nordlin

Linen shirt Sand

259 lei

Feed fields

Title

Linen shirt Sand M

Description

Breathable linen shirt with a relaxed regular fit.

Sale price

259.00

Category

Men's shirts

Brand

Nordlin

GTIN

8594000123453

Product URL

https://shop.example.ro/products/linen-shirt-sand?variant=46012345678901

Product ID

46012345678901

Availability

1

The channel

The region's affiliate network

2Performant was founded in Romania and absorbed Profitshare's Romanian and Bulgarian business in 2025; the Business League leaderboard already lists RO, BG, HU, IE and IT as selling countries. One feed serves affiliates across the whole region.

Your Google feed is already accepted

In their own words: if you already created a feed for Google Merchant, you can use that same feed in their platform. Start in minutes, and switch to the native field set when you want Old price and the six-value availability.

Plain URLs, their tracking

The Product URL stays the plain product page. 2Performant builds the affiliate redirect on its side. No UTM parameters, no tracking glue in your feed, nothing to maintain when campaigns change.

The feed

  • A header row of 2Performant's own field labels, identical to their sample CSV, so the column mapping in their UI is just confirming each column
  • Product ID from Shopify's numeric variant ID; a gid:// URI or a text SKU would violate the spec's "must be a number"
  • Sale price as a bare dot-decimal number with no thousands separator; no currency column exists, so the number is read in the program's currency
  • Old price mapped from the compare-at price and left empty when the product is not on sale, because an always-filled reference price invents a permanent discount
  • Availability as 1/0 by default, with the worded states (In Stock, Backorder, Out Of Stock, Preorder) one mapping away
  • The spec's validations checked at generation (Title ≤ 255, numeric prices and Product ID, the availability enum, custom fields ≤ 254 characters), reported with the affected products, never silently rewritten
  • One row per variant, with titles that pair product and variant so per-variant rows never collide
  • Fetch tracking shows when 2Performant last downloaded the feed and alerts you if the fetches stop

Deep dive

01

A URL they fetch three to four times a day

  • The feed lives at a URL you share; 2Performant fetches it 3-4 times a day and the schedule can be adjusted
  • A one-off CSV file upload (≤ 10 MB) is the fallback
  • The merchant's side of the contract: the file must update automatically whenever a change was made
  • A Google Merchant feed is accepted verbatim, the sibling route in
Technical details

2Performant's own words: the CSV is added through a link to the file. You share a URL and they fetch it three to four times a day, with the schedule adjustable on request. The one-off file upload (their legacy guide caps it at 10 MB) is the fallback, not the norm. And the freshness contract is stated from the merchant's side: the feed must be found at a URL and updated automatically whenever a change was made. That is exactly Feedflock's hosted-URL model.

The cadence cuts both ways: price and stock changes reach affiliates within hours, but a broken URL means stale data until the next fetch succeeds. Feedflock hosts the file on a stable URL, regenerates it as often as every hour and tracks the fetches, alerting you if they stop. And if you already run a Google Merchant feed, 2Performant accepts that URL verbatim; this template exists for the merchant who wants 2Performant's own field set instead.

02

One CSV, their labels

  • One product per line; separator comma, semicolon, tab or pipe; content delimiter double quote, single quote or backtick; UTF-8
  • The header row uses their field labels, so the mapping step in their UI becomes a no-op
  • Embedded quotes are doubled, Enter is the row separator, and stray blank spaces can fail the whole upload
  • RSS and Atom XML are supported too, with all tags present even when empty
Technical details

The spec's file rules, quoted: one product per line; the content delimiter is a double quote, a single quote or a backtick; the field separator a comma, semicolon, tab or pipe; UTF-8. Your feed can carry as much information as you need, mapped to their required and optional fields in their UI. That is why the template's header row uses their field labels, identical to their own sample CSV: the mapping step is just confirming each column.

The legacy blueprint adds the strictness worth knowing: embedded quotes must be doubled, Enter is the row separator, and blank spaces before rows or other small errors can make the whole upload fail. Feedflock's exporter quotes and doubles exactly as prescribed, so a quote inside a description never breaks a row, and a broken row never silently breaks the file. XML is the alternative: RSS and Atom are both supported, with all tags recommended present even when empty.

03

The mandatory eight

  • Title (≤ 255 characters), Description (text plus a whitelist of simple HTML tags), Category (your own tree; none is mandated)
  • Sale price: a number, dot decimal, no thousands separator, and no currency column anywhere in the feed
  • Product URL stays plain (they build the redirect), Product ID must be a number, Images is one comma-joined cell
  • Availability: 0, 1, In Stock, Backorder, Out Of Stock, Preorder; sold-out rows stay in the feed, as 0
Technical details

Eight fields are mandatory, with validations quoted straight from the spec page. Title is capped at 255 characters; Description takes text and simple HTML from a whitelist (b, li, ul, ol, dl, dd, i, u, br); Category is a tree with no mandated taxonomy, just your shop's own path. The template's defaults are the honest ones: the title pairs product and variant so per-variant rows never collide, and the description is stripped to plain text.

Three details deserve care. Sale price is a bare number (dot decimal, no thousands separator), and no currency column exists anywhere in their field set: the number is read in the program's currency, so the feed never states one. Product ID must be a number, which is why the default is Shopify's numeric variant ID (a gid:// URI would violate the rule; a SKU works only when it is numeric). And Availability has a six-value vocabulary (0, 1, In Stock, Backorder, Out Of Stock, Preorder), with sold-out rows staying in the feed as 0 rather than disappearing.

04

Old price, GTIN and the custom slots

  • Old price: the price before discount, same number rules, empty when there is none
  • Brand and GTIN are optional; the stated GTIN length rule is self-contradictory, so it is quoted but not enforced
  • Other data takes JSON or YAML; up to four custom fields, ≤ 254 characters each
  • No delivery fields at all: shipping is not part of the 2Performant feed
Technical details

Beyond the mandatory eight, Old price carries the pre-discount reference under the same number rules. The template maps it from your compare-at price and leaves it empty when the product is not on sale, because an always-filled old price invents a permanent discount. Brand and GTIN round out identification. One spec oddity, recorded honestly: GTIN's stated validation (greater than 8, less than 14 characters) would reject a legitimate 14-digit GTIN, so the rule is quoted in the template but deliberately not enforced.

For everything else there is Other data (JSON or YAML) and up to four custom fields of at most 254 characters each. What the field set does not contain is just as notable: no carrier, no shipping cost, no COD element. Delivery is not part of the 2Performant feed at all, and neither is a currency column. The feed describes the products; the program describes the commercial terms.

The takeaway

One URL, fetched three to four times a day, and a CSV whose header row already speaks 2Performant's own field labels: bare-number prices, a numeric Product ID, availability in their six values. Your Shopify catalog stays the single source of truth for every affiliate in the network.

Claude · ChatGPT

Or set up your 2Performant feed in chat

Connect Feedflock to Claude or ChatGPT and ask. It creates the feed as a draft, maps your categories to 2Performant's own tree and tells you what is still missing. You approve every change.

feedflock · mcp

Create a 2Performant feed for my store and map my categories.

I'll create it as a draft and show you each change before I make it.

FAQ

No. 2Performant states a feed is not mandatory to launch a program. But affiliates running price-comparison and aggregator sites rely on it, so without one a large part of the network simply cannot pick up your products.
Yes. In 2Performant's own words, a feed created for Google Merchant can be used in their platform as well. This template exists for the merchant who wants 2Performant's own field set: a numeric Product ID, the Old price reference and the six-value availability, without Google's vocabulary.
Three to four times a day, and the schedule can be adjusted on request. Feedflock regenerates the file on your schedule, as often as every hour, so every fetch reads current prices and stock. A broken URL means stale data until the next fetch succeeds; Feedflock's fetch tracking alerts you if the downloads stop.
Because no currency column exists in 2Performant's field set, the bare number in Sale price is read in the program's currency. The template defaults to RON for the Romanian home market; Bulgaria reads EUR (the lev ended in February 2026) and Hungary HUF. What you must guarantee is only the number format: dot decimal, no thousands separator.
The spec says so verbatim: "Internal ID of the product. Must be a number." Feedflock's default is Shopify's numeric variant ID, guaranteed unique and always a number. A gid:// URI would violate the rule, and a SKU works only when it is numeric and unique per variant.
Six: 0, 1, In Stock, Backorder, Out Of Stock and Preorder. The template maps Shopify's availability to 1/0 by default, and the worded states are one mapping away. Sold-out rows stay in the feed as 0; they are not removed.
Yes. Filter by collection, tag, vendor, price or stock, or leave out individual variants. The CSV is one row per variant, so excluding a size or colour removes exactly that row.

Get on every marketplace that matters this afternoon.

Install free, connect your first feed in minutes, and let Feedflock keep it fresh and validated.

.myshopify.com