PerformanceSeptember 5, 202611 min

Feed for Yandex Direct 2026: required elements, categoryId and validation errors

Product campaigns are driven by the quality of the feed, not the campaign setup. Based on the official information, I’m reviewing the required elements of an offer, the categoryId role, two levels of segmentation, and errors that cause offers to silently drop out.

Article cover:Feed for Yandex Direct 2026: required elements, categoryId and validation errors

What makes product campaigns and smart banners successful is not the campaign setup, but the quality of the file that is fed into it. Half of the problems “there are few impressions” and “products are not unscrewed” are solved not in the Direct interface, but in XML.

Below are the required elements according to the official help, the categoryId role, segmentation principles and an analysis of errors due to which offers are silently ignored.

A feed is not an upload of goods. This is a description of the display that a person will see. Everything that is not in it will not appear, and everything that is incorrect in it will appear incorrect.

1. File structure

YML format, based on XML. Root element - yml_catalog, it has a required attribute date in the format YYYY-MM-DD hh:mm, and it must correspond to the real time of file generation on your side.

Inside is an element shop, in it currencies and categories, and only after them the list offers. The order here is not cosmetic: if categories are announced after offers, some products will remain without a category.

File restrictions from Direct requirements: one directory per file, URL length up to 2048 characters, standard XML encoding.

2. Required elements of the offer

elementWhen requiredWhat will happen without him
categoryIdAlwaysOffer outside of segmentation, campaign cannot be set up
urlAlwaysThere is nowhere to lead, the offer does not work
nameSimplified offer typeOffer is ignored
vendor and modelType vendor.modelThe offer is ignored, the ad is not generated
currencyIdIf specified pricePrice without currency - error
attribute availableIf you filter by availabilityAvailability filter will not work

The keyword in the right column is “ignored.” An offer without a required element does not generate a validation error for the entire file, it simply drops out silently. Therefore, the discrepancy between the number of products in the catalog and the number of offers in the campaign must be checked manually: it will not communicate itself.

3. categoryId: all control rests on it

Technically, it's a positive integer up to 18 characters long, and each offer belongs to exactly one category. In practice, this is the only lever with which you control a product campaign.

Through categoryId, products are divided into campaigns, and different goals for DRR are set for each campaign. Without this, the entire catalog lives in one heap: a product with a margin of 8% and a product with a margin of 45% are unscrewed for the same purpose, and the first eats up the budget of the second.

Hence the rule: the structure of categories in the feed is built not according to the logic of the site, but according to the logic of the economy. If the website “Accessories” has one category, and within it there are products with a two-fold difference in margin, these should be two categories in the feed.

4. Segmentation: two levels

LevelWhy do we divide?Why
FirstcategoryIdDifferent margins - different goals for DRR
SecondProduct priceCheap and expensive items behave differently
Third, optionalAvailability and turnoverDon't spend your budget on something that's about to run out

The second level is often skipped, but in vain. In one campaign, a product for 1,500 ₽ and a product for 40,000 ₽ are averaged: the system optimizes for overall conversion, and a cheap product with a high conversion attracts impressions, while an expensive product, which brings in money, receives less traffic.

5. Errors that cause the feed to not work

Floating product identifier. IDs must be unique and the same across feeds. If the id is reassembled every time it is unloaded, the system sees a new product and re-enters statistics on it - learning never accumulates.

Divergence from landing. Price in the feed is 3,900 ₽, on the website 4,200 ₽. The validator will let it through, the moderation will not. It is checked only by hand, ten random products after each major edit of the catalog.

Zero price and wrong oldprice. A price equal to zero and an old price that does not exceed the current one are typical reasons for an offer to be rejected.

Constant in the generation date. The date attribute, which does not change from upload to upload, is a sign that the feed is not being collected correctly and is a cause for problems with the relevance of the data.

Categories after offers. Formally, the file is valid, but in fact, some products lose their category, and along with it, their inclusion in the desired campaign.

6. Product campaign and smart banners: not the same thing

The question comes up all the time, so I'll keep it short. A product campaign is a separate type of campaign that itself collects ads from the feed and displays them both in search and in networks. Smart banners are a dynamic format within networks.

They have one thing in common: they both eat feed. And for both, the quality of the file is more important than the campaign settings - you cannot fix in the interface what is not in the XML. How the campaigns themselves are set up - in analysis of product campaigns and smart banners, this article is about the file itself.

7. Checklist before launch

CheckHow to check
Generation date is realCompare date attribute with last upload time
Categories announced before offersOpen XML, see block order
The number of offers matches the catalogCheck the quantity in the feed and in the CMS
IDs are stableCompare two consecutive uploads
Prices are the same as on the websiteCheck 10 random products manually
No zero pricesFilter price = 0
Categories reflect marginCheck unit economics, not site structure

8. Summary

Mandatory minimum in each offer: categoryId and url always, name for a simplified type, vendor and model for vendor.model, currencyId if there is a price. Categories are announced before offers, identifiers are stable, and the generation date is real.

Then management begins: categoryId is built according to the economy, and not according to the structure of the site, and a division by price is added within the categories. It is at this level that a product campaign ceases to be a black box.

Related materials: product campaigns and smart banners, guide to Yandex Direct, what's happening with CPC, ROAS calculator.

If the feed is collected, but the products are not unscrewed, send a link to the file to Telegram, I’ll see what silently falls out there.

More on the topic