Yandex Direct — PPC Audit & Management (API v5 / v501)
Authors: Nick Serebrov & Kobe 🐍 Version: 2.0.2 — актуально на октябрь 2026
Full-cycle Yandex Direct management: account audits, campaign CRUD, keyword management, reporting, optimization, and budget analysis.
Quick Reference
| Command | What it does |
|---|---|
/direct audit | Full account audit (all campaigns), scoring 0-100 |
/direct campaigns | List campaigns with type, strategy, weekly budget and stats |
/direct create | Create a Unified Performance Campaign with groups, keywords, combinatorial ads |
/direct keywords | Keywords and autotargeting (list, add, bids, categories, pause) |
/direct report | Performance stats by priority Metrika goals (CTR, CPC, CPA, spend) |
/direct optimize | Optimization recommendations (pause losers, adjust bids and limits) |
/direct budget | Weekly budget spend analysis and forecasting |
/direct negative | Negative keywords (campaign, group, shared sets) from search queries |
What changed in Direct (know this before acting)
| Date | Change | Consequence for the agent |
|---|---|---|
| 2023-11 → 2024 | Unified Performance Campaign (UNIFIED_CAMPAIGN, ЕПК) replaced text-image, dynamic and smart-banner campaigns | Read UnifiedCampaignFieldNames; search and YAN live in one campaign — split stats by AdNetworkType |
| 2024-07-01 | Manual bids in YAN disabled | Manual strategy (HIGHEST_POSITION) is search-only |
| 2025-06, 2025-09 | New strategies: AVERAGE_CPA_MULTIPLE_GOALS, PAY_FOR_CONVERSION_MULTIPLE_GOALS, MAX_PROFIT | See references/bidding-strategies.md |
| 2025-11-13 | bidmodifiers.toggle removed | Use set (100 = off) or delete |
| 2026-03-20 | Combinatorial ads (RESPONSIVE_AD): up to 7 titles, 3 texts, 5 images, 6 videos | Request ResponsiveAdFieldNames, otherwise the API returns them as TextAd with only the first title/text/image |
| 2026-06-30 / 07-14 | Text-image ads in ЕПК are edit-only; existing ones converted to combinatorial | ads.add with TextAd creates RESPONSIVE_AD; Title2 is merged into the title (≤ 56 chars) or lost |
| 2026-06-22 / 07-06 | Weekly budgets for manual-bid campaigns and shared account; up to 30% of unspent budget rolls over | Analyse WeeklySpendLimit, not a daily budget |
| 2026-03-01 | Russian language rules for consumer information | Flag foreign words without Russian equivalents in ads (references/compliance.md) |
API Configuration
Credentials: ~/.secrets/yandex-direct.json (chmod 600)
json{ "client_id": "...", "client_secret": "...", "oauth_token": "...", "client_login": "optional-for-agency" }
- Endpoint:
https://api.direct.yandex.com/json/v5/<service>; Unified-campaign structures (UnifiedCampaign,UnifiedAdGroup,ShoppingAd,ListingAd) inadd/updatego to/json/v501/—scripts/yd-api.shroutes them automatically. - Read campaigns and ad groups from v501 too: v5 shows a Unified campaign as
TEXT_CAMPAIGN(groups asTEXT_AD_GROUP) withoutUnifiedCampaignsettings such as searchPlacementTypes.yd-api.shroutesgetrequests withUnifiedCampaign*/UnifiedAdGroup*field names to v501; otherwise setYD_API_VERSION=v501. - Auth:
Authorization: Bearer {oauth_token}; agency or representative access:Client-Login: {client_login}. - Sandbox:
YD_SANDBOX=1. Env overrides:YD_TOKEN,YD_CLIENT_LOGIN,YD_API_VERSION,YD_SECRETS. - Money in API requests and responses is in micro-units (× 1 000 000). Reports use rubles
(
returnMoneyInMicros: false).
API limits that break naive requests:
adgroups.get,keywords.get,ads.get,bidmodifiers.get:CampaignIds≤ 10 per request,AdGroupIds≤ 1000.- Every
getreturns ≤ 10 000 objects; continue withPage.Offset=LimitedBy. negativekeywordsharedsets.get:Ids≤ 30; omitSelectionCriteriato get all sets. Same forsitelinks.get.sitelinks.get:FieldNames: ["Id"]plusSitelinkFieldNames—"Sitelinks"inFieldNamestogether withSitelinkFieldNamesis error 4004.ads.get:TextAdFieldNameshasAdExtensions, notAdExtensionIds(that is a filter / anaddfield).- Reports:
Goals≤ 10;AttributionModelsonlyAUTO,LSCCD,FCCD,LC; ≤ 5 offline reports in queue; one request per 10 s (error 56, HTTP 400) —yd-report.shpolls every ≥ 10 s and retries error 56. TheCampaignTypereport column shows a Unified campaign asTEXT_CAMPAIGN— take the type fromcampaigns.getv501. ads.get:AutogeneratedErirAdDescriptionexists only inTextAdFieldNames; combinatorial ads have no such field (error 8000) — check the auto description in the web interface.keywords.get:Productivityis alwaysnull;AutotargetingCategoriesis deprecated — useAutotargetingSettings(AutotargetingSettingsCategoriesFieldNames,AutotargetingSettingsBrandOptionsFieldNames).
Troubleshooting:
- Empty HTTP 204 to every request, even with a wrong token → the Direct API is turned off on Yandex's side (e.g. the special mode after the October 2026 data-center incident: only the web interface and the mobile app work, see https://yandex.ru/support/direct/ru/special-mode). Not a token, IP or script problem — wait, and meanwhile use the web interface for read-only checks.
yd-audit.shsays «no campaigns found» → all campaigns may be archived; rerun with--include-archived(the script prints the archived count when it can).- The campaigns grid labels strategies «Оптимизация кликов» / «Оптимизация конверсий»; the API type is in
BiddingStrategyType(seereferences/bidding-strategies.md).
Safety rule for changes
Every write call (add, update, delete, suspend, resume, archive, moderate, bids, set)
is made only after the user approved that exact change: show the request JSON (or a readable diff of
what changes) and wait for an explicit yes. Audit, report and optimize are read-only.
Orchestration Logic
/direct audit
- Run
scripts/yd-audit.sh <dir>— collects all objects (chunked by 10 campaigns, paginated) and 4 reports for the last 30 days using the campaigns' priority goals (--goalsto override). - Read
<dir>/summary.json: errors, campaign and ad types, goals used. - Hand the directory to
agents/audit-yandex.md(or run its steps): 55 checks fromreferences/yandex-audit.md, scoring fromreferences/scoring-system.md. - Report in Russian: grade (A–F), findings, Quick Wins, prioritized action plan.
/direct campaigns
campaigns.get(v501):FieldNamesId, Name, Type, State, Status, StatusClarification, Statistics;UnifiedCampaignFieldNamesandTextCampaignFieldNames: BiddingStrategy, PriorityGoals, CounterIds.- Table: type, state, search/network strategy, weekly limit (
WeeklySpendLimit/ 1 000 000), goals. - Spend and conversions — from
scripts/yd-report.sh campaign --by-network --goals <priority goals>.
/direct create
- Gather: name, geo, weekly budget, strategy and goal, landing URL, keywords, 3–7 titles, 2–3 texts, images.
adimages.add(base64,Type: AUTO) → image hashes; seereferences/image-specs.md.campaigns.addwithUnifiedCampaign(v501):BiddingStrategy.Search/Network,CounterIds,PriorityGoals,Settings(ADD_METRICA_TAG,ENABLE_SITE_MONITORING),TrackingParamswith UTM.adgroups.addwithUnifiedAdGroup(v501):RegionIds, negatives.keywords.add: phrases and/or---autotargetingwithAutotargetingSettings(categories, brand options).sitelinks.add(up to 8 per set) andadextensions.add(CALLOUT).ads.addwithResponsiveAd:Titles,Texts,Href,AdImageHashes,SitelinkSetId,AdExtensionIds,BusinessIdif there is a Yandex Business profile. Do not useTextImageAdfor this — it is an image-only banner.ads.moderate— only after the user reviewed the drafts.
/direct keywords
keywords.getbyAdGroupIdsor ≤ 10CampaignIds; includeServingStatusand autotargeting settings.- Operations: add, suspend, resume, delete, bids (
keywordbids.setwith manual strategy), autotargeting categories. - Performance —
scripts/yd-report.sh criteria(Criterion,CriterionType), not the deprecatedProductivity.
/direct report
scripts/yd-report.sh <preset>: account, campaign, adgroup, ad, criteria, search_query, placement, custom.- Always pass
--goalswith priority goals (fromcampaigns.get→PriorityGoals): without it conversions are summed over ALL Metrika goals, including micro-goals. - For Unified campaigns add
--by-networkto separate search and YAN. - Dates:
--from/--to(default: 30 days ending yesterday) or--period LAST_7_DAYS. Offline reports are polled automatically (retryInheader).
/direct optimize
- Reports for 30 days with goals: criteria, search_query, placement, campaign
--by-network. - Find: conditions and queries with spend > 2× target CPA and no conversions; YAN placements to exclude;
network vs search CPA gap inside one campaign; groups with
RARELY_SERVED; rejected ad elements. - Compare with the account's own medians first, then
references/benchmarks.md. - Recommendations sorted by impact; 3× Kill Rule: flag anything with CPA > 3× target.
- Do not touch strategy, its spend-limit type or payment model during learning (
references/bidding-strategies.md).
/direct budget
- Weekly limits from
BiddingStrategy.*.WeeklySpendLimit(orCustomPeriodBudgetfor flights). - Spend by day —
yd-report.sh campaign --daily --from <Monday>; run rate and weekly forecast. - Flag: limit hit before the end of the week; spend < 70% of the limit; pay-per-conversion budget < 10 × CPA; weekly budget < 300 ₽. Unspent budget of CPC campaigns rolls over (up to 30%) since 06.07.2026.
/direct negative
- Campaign and group negatives (
NegativeKeywords) and shared sets (negativekeywordsharedsets.get, all sets). yd-report.sh search_query --goals …→ irrelevant queries with spend and no conversions.- Propose negatives (campaign level or shared set); apply via
campaigns.update/negativekeywordsharedsets.updateafter approval.
Quality Gates
- Write operations only after explicit approval of the exact change.
- Conversion analysis only on priority goals; never on the all-goals sum.
- 3× Kill Rule: flag keywords/groups/placements with CPA > 3× target for pause.
- Strategy learning: goal ≥ 10 conversions a week; don't change strategy, spend-limit type or payment model in the first 2–3 weeks; a pause > 7 days restarts learning.
- Budget: weekly budget ≥ 300 ₽; pay-per-conversion ≥ 10 × CPA.
- Moderation: check
Status/StatusClarificationof ads and of each combinatorial element before optimizing. - Tracking:
ADD_METRICA_TAGon, UTM viaTrackingParams(campaign or group) or inHref.
Reference Files
Load on-demand, NOT at startup:
references/yandex-audit.md— 55 audit checks (YD01-YD55) with data sourcesreferences/scoring-system.md— Weighted scoring (0-100, grades A-F)references/benchmarks.md— How to compare metrics; rough Russian market referencesreferences/bidding-strategies.md— ЕПК strategies ↔ API, weekly budgets, learning, bid modifiersreferences/compliance.md— Yandex moderation rules, ad marking, Russian language rulesreferences/image-specs.md— Images and video for combinatorial ads
Scripts
scripts/yd-api.sh— Generic API call wrapper (v5/v501 routing, Client-Login, item-level error detection)scripts/yd-report.sh— Reports wrapper (presets, goals, attribution, offline polling)scripts/yd-audit.sh— Automated audit data collection (all objects + 4 reports)
Requirements: bash, curl, jq.
Subagents
agents/audit-yandex.md— Audit subagent for parallel campaign analysis


