direct-cli 0.3.12__tar.gz → 0.3.13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. {direct_cli-0.3.12 → direct_cli-0.3.13}/AGENTS.md +6 -6
  2. {direct_cli-0.3.12 → direct_cli-0.3.13}/CHANGELOG.md +15 -0
  3. {direct_cli-0.3.12 → direct_cli-0.3.13}/PKG-INFO +50 -41
  4. {direct_cli-0.3.12 → direct_cli-0.3.13}/README.md +49 -40
  5. direct_cli-0.3.13/direct_cli/_bidding_strategy.py +5558 -0
  6. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/ads.py +13 -43
  7. direct_cli-0.3.13/direct_cli/commands/campaigns.py +7484 -0
  8. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/changes.py +11 -5
  9. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/utils.py +18 -6
  10. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/v4/money.py +1 -1
  11. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli.egg-info/PKG-INFO +50 -41
  12. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli.egg-info/SOURCES.txt +1 -0
  13. {direct_cli-0.3.12 → direct_cli-0.3.13}/pyproject.toml +1 -1
  14. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/build_api_coverage_report.py +1 -1
  15. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/test_safe_commands.sh +1 -1
  16. direct_cli-0.3.13/tests/WSDL_OPTIONAL_FIELD_AUDIT.md +3292 -0
  17. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/api_coverage_payloads.py +328 -0
  18. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_changes.py +29 -2
  19. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_cli.py +3 -4
  20. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_cli_contract.py +6 -1
  21. direct_cli-0.3.13/tests/test_dry_run.py +21772 -0
  22. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_integration.py +1 -1
  23. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_low_coverage_payloads.py +17 -5
  24. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_wsdl_parity_gate.py +2598 -91
  25. direct_cli-0.3.12/direct_cli/commands/campaigns.py +0 -2678
  26. direct_cli-0.3.12/tests/WSDL_OPTIONAL_FIELD_AUDIT.md +0 -5239
  27. direct_cli-0.3.12/tests/test_dry_run.py +0 -11240
  28. {direct_cli-0.3.12 → direct_cli-0.3.13}/.env.example +0 -0
  29. {direct_cli-0.3.12 → direct_cli-0.3.13}/.github/copilot-instructions.md +0 -0
  30. {direct_cli-0.3.12 → direct_cli-0.3.13}/.github/workflows/api-coverage.yml +0 -0
  31. {direct_cli-0.3.12 → direct_cli-0.3.13}/.github/workflows/claude.yml +0 -0
  32. {direct_cli-0.3.12 → direct_cli-0.3.13}/.github/workflows/quality.yml +0 -0
  33. {direct_cli-0.3.12 → direct_cli-0.3.13}/.gitignore +0 -0
  34. {direct_cli-0.3.12 → direct_cli-0.3.13}/CLAUDE.md +0 -0
  35. {direct_cli-0.3.12 → direct_cli-0.3.13}/MANIFEST.in +0 -0
  36. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/__init__.py +0 -0
  37. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_deprecated.py +0 -0
  38. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_smoke_probes.py +0 -0
  39. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/__init__.py +0 -0
  40. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/__init__.py +0 -0
  41. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/endpoints.py +0 -0
  42. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/exceptions.py +0 -0
  43. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/resource_mapping.py +0 -0
  44. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.py +0 -0
  45. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.pyi +0 -0
  46. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/v4/__init__.py +0 -0
  47. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.py +0 -0
  48. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.pyi +0 -0
  49. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/_vendor/tapi_yandex_direct/v4/resource_mapping.py +0 -0
  50. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/api.py +0 -0
  51. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/auth.py +0 -0
  52. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/cli.py +0 -0
  53. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/__init__.py +0 -0
  54. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/adextensions.py +0 -0
  55. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/adgroups.py +0 -0
  56. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/adimages.py +0 -0
  57. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/advideos.py +0 -0
  58. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/agencyclients.py +0 -0
  59. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/audiencetargets.py +0 -0
  60. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/auth.py +0 -0
  61. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/balance.py +0 -0
  62. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/bidmodifiers.py +0 -0
  63. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/bids.py +0 -0
  64. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/businesses.py +0 -0
  65. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/clients.py +0 -0
  66. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/creatives.py +0 -0
  67. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/dictionaries.py +0 -0
  68. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/dynamicads.py +0 -0
  69. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/dynamicfeedadtargets.py +0 -0
  70. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/feeds.py +0 -0
  71. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/keywordbids.py +0 -0
  72. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/keywords.py +0 -0
  73. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/keywordsresearch.py +0 -0
  74. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/leads.py +0 -0
  75. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/negativekeywordsharedsets.py +0 -0
  76. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/reports.py +0 -0
  77. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/retargeting.py +0 -0
  78. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/sitelinks.py +0 -0
  79. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/smartadtargets.py +0 -0
  80. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/strategies.py +0 -0
  81. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/turbopages.py +0 -0
  82. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4account.py +0 -0
  83. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4events.py +0 -0
  84. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4finance.py +0 -0
  85. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4forecast.py +0 -0
  86. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4goals.py +0 -0
  87. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4shells.py +0 -0
  88. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4tags.py +0 -0
  89. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/v4wordstat.py +0 -0
  90. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/commands/vcards.py +0 -0
  91. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/output.py +0 -0
  92. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/reports_coverage.py +0 -0
  93. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/smoke_matrix.py +0 -0
  94. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/v4/__init__.py +0 -0
  95. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/v4_contracts.py +0 -0
  96. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli/wsdl_coverage.py +0 -0
  97. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli.egg-info/dependency_links.txt +0 -0
  98. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli.egg-info/entry_points.txt +0 -0
  99. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli.egg-info/requires.txt +0 -0
  100. {direct_cli-0.3.12 → direct_cli-0.3.13}/direct_cli.egg-info/top_level.txt +0 -0
  101. {direct_cli-0.3.12 → direct_cli-0.3.13}/docs/audits/issue-198-mutating-wsdl-audit.md +0 -0
  102. {direct_cli-0.3.12 → direct_cli-0.3.13}/docs/superpowers/plans/2026-04-12-issue-32-completion.md +0 -0
  103. {direct_cli-0.3.12 → direct_cli-0.3.13}/docs/superpowers/specs/2026-04-23-vendor-tapi-yandex-direct-design.md +0 -0
  104. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/anonymize_cassettes.py +0 -0
  105. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/build_api_coverage_checklist.py +0 -0
  106. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/build_wsdl_optional_field_audit.py +0 -0
  107. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/check_reports_drift.py +0 -0
  108. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/check_wsdl_drift.py +0 -0
  109. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/patch_vendor_imports.py +0 -0
  110. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/refresh_reports_cache.py +0 -0
  111. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/refresh_wsdl_cache.py +0 -0
  112. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/release_pypi.sh +0 -0
  113. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/sandbox_write_audit.py +0 -0
  114. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/sandbox_write_live.py +0 -0
  115. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/test_dangerous_commands.sh +0 -0
  116. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/test_sandbox_write.sh +0 -0
  117. {direct_cli-0.3.12 → direct_cli-0.3.13}/scripts/update_vendor.sh +0 -0
  118. {direct_cli-0.3.12 → direct_cli-0.3.13}/setup.cfg +0 -0
  119. {direct_cli-0.3.12 → direct_cli-0.3.13}/setup.py +0 -0
  120. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/API_COVERAGE.md +0 -0
  121. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/API_ISSUE_AUDIT.md +0 -0
  122. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/MANUAL_COVERAGE.md +0 -0
  123. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/__init__.py +0 -0
  124. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/_orphan_store.py +0 -0
  125. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteAdExtensions.test_add_delete.yaml +0 -0
  126. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteAdGroups.test_add_update_delete.yaml +0 -0
  127. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteAdImages.test_add_delete.yaml +0 -0
  128. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteAds.test_add_text_ad_update_delete.yaml +0 -0
  129. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteAudienceTargets.test_add_delete.yaml +0 -0
  130. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteBidModifiersAdd.test_add_delete_mobile.yaml +0 -0
  131. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteBidModifiersSet.test_set_without_id_is_rejected.yaml +0 -0
  132. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteBids.test_set_bid.yaml +0 -0
  133. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteBidsRead.test_bids_get.yaml +0 -0
  134. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteBidsRead.test_bids_set_auto.yaml +0 -0
  135. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteCampaignDraftLifecycle.test_draft_create_get_delete.yaml +0 -0
  136. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteCampaigns.test_campaign_lifecycle.yaml +0 -0
  137. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteDynamicAds.test_add_update_delete.yaml +0 -0
  138. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteFeeds.test_add_update_delete.yaml +0 -0
  139. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteKeywordBids.test_set_keyword_bid.yaml +0 -0
  140. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteKeywords.test_add_update_delete.yaml +0 -0
  141. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteNegativeKeywordSharedSets.test_add_update_delete.yaml +0 -0
  142. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteRetargeting.test_add_delete.yaml +0 -0
  143. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteRetargetingUpdate.test_retargeting_update.yaml +0 -0
  144. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteSitelinks.test_add_delete.yaml +0 -0
  145. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteSmartAdTargets.test_add_update_delete.yaml +0 -0
  146. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteStrategies.test_strategies_lifecycle.yaml +0 -0
  147. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_integration_write/TestWriteVCards.test_add_delete.yaml +0 -0
  148. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_adgroups_add_update_delete.yaml +0 -0
  149. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_adimages_add_get_delete.yaml +0 -0
  150. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_ads_add_update_delete.yaml +0 -0
  151. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_ads_suspend_resume_archive_unarchive.yaml +0 -0
  152. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_advideos_add_get.yaml +0 -0
  153. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_audiencetargets_add_delete.yaml +0 -0
  154. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_audiencetargets_suspend_resume.yaml +0 -0
  155. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_bids_set.yaml +0 -0
  156. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_campaign_create_get_delete.yaml +0 -0
  157. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_creatives_chain_advideo_to_creative.yaml +0 -0
  158. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_dynamicads_add_delete.yaml +0 -0
  159. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_dynamicads_suspend_resume.yaml +0 -0
  160. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_keywordbids_set.yaml +0 -0
  161. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_keywords_add_update_delete.yaml +0 -0
  162. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_keywords_suspend_resume.yaml +0 -0
  163. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_sitelinks_add_get_delete.yaml +0 -0
  164. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_smartadtargets_add_update_delete.yaml +0 -0
  165. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/cassettes/test_v5_live_write/test_v5_live_draft_smartadtargets_suspend_resume.yaml +0 -0
  166. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/conftest.py +0 -0
  167. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/fixtures/test-video.mp4 +0 -0
  168. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/reports_cache/raw/fields-list.html +0 -0
  169. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/reports_cache/raw/headers.html +0 -0
  170. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/reports_cache/raw/period.html +0 -0
  171. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/reports_cache/raw/spec.html +0 -0
  172. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/reports_cache/raw/type.html +0 -0
  173. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/reports_cache/spec.json +0 -0
  174. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_api_coverage.py +0 -0
  175. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_auth_bw.py +0 -0
  176. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_auth_oauth.py +0 -0
  177. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_auth_op.py +0 -0
  178. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_auth_write_json.py +0 -0
  179. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_balance.py +0 -0
  180. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_comprehensive.py +0 -0
  181. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_env_loading.py +0 -0
  182. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_integration_write.py +0 -0
  183. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_reports_drift.py +0 -0
  184. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_reports_parsing.py +0 -0
  185. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_sandbox_write_audit.py +0 -0
  186. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_smoke_matrix.py +0 -0
  187. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_transport_contract.py +0 -0
  188. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_unknown_option_hints.py +0 -0
  189. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4_contracts.py +0 -0
  190. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4_exit_codes.py +0 -0
  191. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4_foundation.py +0 -0
  192. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4_live_contracts.py +0 -0
  193. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4_runtime_shape.py +0 -0
  194. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4_safety.py +0 -0
  195. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4account.py +0 -0
  196. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4events.py +0 -0
  197. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4finance_money.py +0 -0
  198. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4finance_read.py +0 -0
  199. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4forecast.py +0 -0
  200. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4goals.py +0 -0
  201. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4tags.py +0 -0
  202. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v4wordstat.py +0 -0
  203. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_v5_live_write.py +0 -0
  204. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/test_vendor_imports.py +0 -0
  205. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/adextensions.xml +0 -0
  206. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/adgroups.xml +0 -0
  207. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/adimages.xml +0 -0
  208. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/ads.xml +0 -0
  209. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/advideos.xml +0 -0
  210. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/agencyclients.xml +0 -0
  211. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/audiencetargets.xml +0 -0
  212. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/bidmodifiers.xml +0 -0
  213. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/bids.xml +0 -0
  214. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/businesses.xml +0 -0
  215. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/campaigns.xml +0 -0
  216. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/changes.xml +0 -0
  217. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/clients.xml +0 -0
  218. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/creatives.xml +0 -0
  219. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/dictionaries.xml +0 -0
  220. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/dynamicfeedadtargets.xml +0 -0
  221. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/dynamictextadtargets.xml +0 -0
  222. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/feeds.xml +0 -0
  223. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/imports/adextensiontypes.xsd +0 -0
  224. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/imports/general.xsd +0 -0
  225. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/imports/generalclients.xsd +0 -0
  226. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/keywordbids.xml +0 -0
  227. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/keywords.xml +0 -0
  228. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/keywordsresearch.xml +0 -0
  229. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/leads.xml +0 -0
  230. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/negativekeywordsharedsets.xml +0 -0
  231. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/retargetinglists.xml +0 -0
  232. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/sitelinks.xml +0 -0
  233. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/smartadtargets.xml +0 -0
  234. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/strategies.xml +0 -0
  235. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/turbopages.xml +0 -0
  236. {direct_cli-0.3.12 → direct_cli-0.3.13}/tests/wsdl_cache/vcards.xml +0 -0
@@ -73,21 +73,22 @@ direct dictionaries get-geo-regions \
73
73
 
74
74
  ### Datetime Rules
75
75
 
76
- - Datetime parameters must be passed in the format `YYYY-MM-DDTHH:MM:SS`.
76
+ - Changes timestamps must match Yandex Direct API format `YYYY-MM-DDTHH:MM:SSZ`.
77
+ - Other datetime parameters use their method-specific documented format.
77
78
  - Datetime values must be passed as a single shell token.
78
- - Canonical examples must not use timezone suffixes like `Z`.
79
+ - Canonical `changes` examples must use the `Z` suffix.
79
80
  - Canonical examples must not use quoted space-separated datetime values.
80
81
 
81
82
  Use:
82
83
 
83
84
  ```bash
84
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
85
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
85
86
  ```
86
87
 
87
88
  Do not use:
88
89
 
89
90
  ```bash
90
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
91
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00
91
92
  direct changes check-campaigns --timestamp "2026-04-14 00:00:00"
92
93
  ```
93
94
 
@@ -104,7 +105,7 @@ Valid canonical examples:
104
105
 
105
106
  ```bash
106
107
  direct campaigns get --ids 1,2,3
107
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
108
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
108
109
  direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
109
110
  direct smartadtargets update --id 456 --priority HIGH
110
111
  direct dynamicads set-bids --id 789 --bid 12.5
@@ -119,7 +120,6 @@ direct dynamicads set-bids --id 789 --bid 12.5 --json '{"StrategyPriority":"HIGH
119
120
  direct dictionaries get-geo-regions \
120
121
  --region-ids 225 \
121
122
  --fields GeoRegionId,GeoRegionName
122
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
123
123
  direct changes check-campaigns --timestamp "2026-04-14 00:00:00"
124
124
  ```
125
125
 
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.13
4
+
5
+ **Breaking changes:**
6
+
7
+ - `direct campaigns add` and `direct campaigns update` now require all
8
+ bidding-strategy money flags to be passed directly in micro-rubles,
9
+ matching the existing `--budget`, `--average-cpa`, `--bid-ceiling`, and
10
+ `--filter-average-cpc` contract. The CLI no longer accepts decimal currency
11
+ values or performs unit conversion for campaign money
12
+ inputs. Closes #399.
13
+ - `direct ads add` and `direct ads update` now apply the same API-native
14
+ micro-ruble contract to `--price-extension-price` and
15
+ `--price-extension-old-price`; price-extension values are no longer parsed
16
+ as decimal currency amounts.
17
+
3
18
  ## 0.3.12
4
19
 
5
20
  **Added:**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: direct-cli
3
- Version: 0.3.12
3
+ Version: 0.3.13
4
4
  Summary: Command-line interface for Yandex Direct API
5
5
  Author: axisrow
6
6
  License: MIT
@@ -337,7 +337,7 @@ lines with `\`.
337
337
  #### Flag Design Rules
338
338
 
339
339
  - List inputs use comma-separated CLI syntax where appropriate.
340
- - Money and bid values are passed in micro-rubles (API-native format). Values below 100,000 trigger a validation hint suggesting the correct scale.
340
+ - Money and bid values are passed only in micro-rubles, exactly as Yandex Direct API long fields define them. The CLI does not accept decimal currency amounts or convert currency units; values below 100,000 trigger a validation hint suggesting the correct scale.
341
341
  - Selector fields remain explicit flags, for example:
342
342
  - `--id`
343
343
  - `--campaign-id`
@@ -347,19 +347,22 @@ lines with `\`.
347
347
 
348
348
  #### Datetime Rules
349
349
 
350
- - Datetime parameters must be passed in the format `YYYY-MM-DDTHH:MM:SS`.
350
+ - Changes timestamps must include an explicit timezone: `YYYY-MM-DDTHH:MM:SSZ`
351
+ or an offset such as `YYYY-MM-DDTHH:MM:SS+03:00`.
352
+ - Other datetime parameters use their method-specific documented format.
351
353
  - Datetime values must be passed as a single shell token.
352
- - Canonical examples must not use timezone suffixes like `Z`.
354
+ - Canonical `changes` examples should use the `Z` suffix; explicit offsets are
355
+ accepted and normalized to UTC.
353
356
  - Canonical examples must not use quoted space-separated datetime values.
354
357
 
355
358
  Use:
356
359
 
357
360
  ```bash
358
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
361
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
359
362
  ```
360
363
 
361
- Do not use: a timestamp with a `Z` suffix, or a quoted timestamp that contains
362
- a space between the date and time.
364
+ Do not use: a `changes` timestamp without a timezone suffix, or a quoted
365
+ timestamp that contains a space between the date and time.
363
366
 
364
367
  #### Documentation Contract
365
368
 
@@ -374,7 +377,7 @@ Valid canonical examples:
374
377
 
375
378
  ```bash
376
379
  direct campaigns get --ids 1,2,3
377
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
380
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
378
381
  direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
379
382
  direct smartadtargets update --id 456 --priority HIGH
380
383
  direct dynamicads set-bids --id 789 --bid 12500000 --context-bid 9000000 --priority HIGH
@@ -382,7 +385,7 @@ direct dictionaries get-geo-regions --name Moscow --region-ids 225,187 --exact-n
382
385
  ```
383
386
 
384
387
  Invalid examples include command lines that pass raw JSON flags, use shell
385
- line continuations, add timezone suffixes to CLI datetimes, or quote
388
+ line continuations, omit the timezone suffix from `changes` datetimes, or quote
386
389
  space-separated datetime values.
387
390
 
388
391
  #### Campaigns
@@ -418,6 +421,7 @@ direct campaigns add --name "Smart Controls" --start-date 2026-06-01 --type SMAR
418
421
  direct campaigns add --name "Smart Package" --start-date 2026-06-01 --type SMART_CAMPAIGN --counter-id 123 --package-strategy-id 700 --package-platform-search YES --package-platform-network NO --dry-run
419
422
  direct campaigns add --name "Mobile App Controls" --start-date 2026-06-01 --type MOBILE_APP_CAMPAIGN --setting ADD_TO_FAVORITES=YES --negative-keyword-shared-set-ids 10,11 --dry-run
420
423
  direct campaigns add --name "CPM Banner Controls" --start-date 2026-06-01 --type CPM_BANNER_CAMPAIGN --setting ADD_METRICA_TAG=YES --counter-ids 111,222 --frequency-cap-impressions 5 --frequency-cap-period-days 7 --video-target VIEWS --dry-run
424
+ direct campaigns add --name "CPM Banner Strategy" --start-date 2026-06-01 --type CPM_BANNER_CAMPAIGN --network-strategy WB_MAXIMUM_IMPRESSIONS --average-cpm 120 --strategy-spend-limit 1000 --dry-run
421
425
  direct campaigns update --id 12345 --type CPM_BANNER_CAMPAIGN --frequency-cap-impressions 5 --frequency-cap-period-all --dry-run
422
426
 
423
427
  # Notification (Sms/Email) and TimeTargeting via typed CLI flags
@@ -467,8 +471,8 @@ direct ads get --campaign-ids 1,2,3
467
471
  direct ads get --adgroup-ids 45678 --format table
468
472
  direct ads add --adgroup-id 12345 --type TEXT_AD --title "Title" --text "Ad text" --href "https://example.com" --dry-run
469
473
  direct ads add --adgroup-id 12345 --type TEXT_AD --title "Title" --text "Ad text" --href "https://example.com" --title2 "Second headline" --display-url-path "deals" --mobile YES --vcard-id 111 --sitelink-set-id 222 --turbo-page-id 333 --ad-extensions "444,555" --dry-run
470
- direct ads add --adgroup-id 12345 --type TEXT_AD --title "Title" --text "Ad text" --href "https://example.com" --final-url "https://final.example.com" --video-extension-creative-id 777 --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --prefer-vcard-over-business NO --erir-ad-description "Text ad object" --dry-run
471
- direct ads add --adgroup-id 12345 --type RESPONSIVE_AD --texts "Text one,Text two" --titles "Title one,Title two" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --erir-ad-description "Responsive ad object" --dry-run
474
+ direct ads add --adgroup-id 12345 --type TEXT_AD --title "Title" --text "Ad text" --href "https://example.com" --final-url "https://final.example.com" --video-extension-creative-id 777 --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --prefer-vcard-over-business NO --erir-ad-description "Text ad object" --dry-run
475
+ direct ads add --adgroup-id 12345 --type RESPONSIVE_AD --texts "Text one,Text two" --titles "Title one,Title two" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --erir-ad-description "Responsive ad object" --dry-run
472
476
  direct ads add --adgroup-id 12345 --type SHOPPING_AD --feed-id 170 --default-texts "Default product text" --sitelink-set-id 222 --ad-extensions "333,444" --business-id 777 --feed-filter-condition "CATEGORY:EQUALS_ANY:shoes|boots" --title-sources NAME,BRAND --text-sources DESCRIPTION --dry-run
473
477
  direct ads add --adgroup-id 12345 --type LISTING_AD --feed-id 171 --default-texts "Default listing text" --feed-filter-condition "CATEGORY:EQUALS_ANY:appliances" --title-sources TITLE --text-sources DESCRIPTION --dry-run
474
478
  direct ads add --adgroup-id 12345 --type TEXT_AD_BUILDER_AD --creative-id 123 --href "https://example.com" --turbo-page-id 456 --erir-ad-description "Builder ad object" --dry-run
@@ -484,11 +488,11 @@ direct ads update --id 99999 --type TEXT_AD --image-hash abcdefghijklmnopqrst
484
488
  direct ads update --id 99999 --type TEXT_AD --title2 "New second headline" --vcard-id 222
485
489
  direct ads update --id 99999 --type TEXT_AD --callouts-add "111,222" --callouts-remove "333"
486
490
  direct ads update --id 99999 --type TEXT_AD --callouts-set "444,555"
487
- direct ads update --id 99999 --type TEXT_AD --video-extension-creative-id 777 --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
491
+ direct ads update --id 99999 --type TEXT_AD --video-extension-creative-id 777 --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
488
492
  direct ads update --id 99999 --type TEXT_AD --final-url "https://final.example.com" --age-label AGE_18 --business-id 777 --prefer-vcard-over-business NO --erir-ad-description "Text ad object"
489
493
  direct ads update --id 99999 --type DYNAMIC_TEXT_AD --text "Updated dynamic text" --callouts-add "111,222"
490
494
  direct ads update --id 99999 --type MOBILE_APP_AD --mobile-app-feature PRICE=YES --mobile-app-feature CUSTOMER_RATING=NO --video-extension-creative-id 777 --erir-ad-description "Mobile app object"
491
- direct ads update --id 99999 --type RESPONSIVE_AD --texts "Text one,Text two" --titles "Title one,Title two" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
495
+ direct ads update --id 99999 --type RESPONSIVE_AD --texts "Text one,Text two" --titles "Title one,Title two" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
492
496
  direct ads update --id 99999 --type TEXT_IMAGE_AD --final-url "https://final.example.com" --erir-ad-description "Image ad object"
493
497
  direct ads update --id 99999 --type SHOPPING_AD --sitelink-set-id 222 --callouts-set "444,555" --business-id 777 --feed-filter-condition "CATEGORY:EQUALS_ANY:shoes|boots" --title-sources NAME,BRAND --text-sources DESCRIPTION --default-texts "Default product text"
494
498
  direct ads update --id 99999 --type MOBILE_APP_IMAGE_AD --image-hash abcdefghijklmnopqrst --tracking-url "https://track.example.com" --erir-ad-description "Mobile image ad"
@@ -510,8 +514,8 @@ when any price-extension flag is used. `ads update` additionally exposes
510
514
  `TextAdUpdateBase.CalloutSetting` (`ext:AdExtensionSetting`) field on an
511
515
  existing ad — `--callouts-set` replaces the whole callout list and is mutually
512
516
  exclusive with the incremental `--callouts-add` / `--callouts-remove` pair.
513
- Price-extension values are human-readable money amounts and are converted to
514
- the Yandex Direct API long-unit format internally. `ads update` also supports
517
+ Price-extension values are passed in micro-rubles, matching the Yandex Direct
518
+ API long-unit format directly. `ads update` also supports
515
519
  `--age-label`.
516
520
  `--mobile` (default `NO`) and `--ad-extensions` are `ads add`-only —
517
521
  `TextAdUpdate` does not contain `Mobile`, and on update ad-extensions are
@@ -577,18 +581,19 @@ direct keywords delete --id 88888
577
581
  direct keywords add --adgroup-id 12345 --from-file keywords.jsonl
578
582
 
579
583
  # Inline JSON array
580
- direct keywords add --keywords-json '[{"Keyword":"buy laptop","Bid":10000000},{"Keyword":"buy desktop"}]'
584
+ direct keywords add --adgroup-id 12345 --keywords-json '[{"Keyword":"buy laptop"},{"Keyword":"buy desktop"}]'
581
585
  ```
582
586
 
583
587
  Example `keywords.jsonl`:
584
588
 
585
589
  ```jsonl
586
- {"Keyword":"buy laptop","Bid":10000000,"UserParam1":"src=ad1"}
587
- {"Keyword":"buy desktop","ContextBid":5000000}
590
+ {"Keyword":"buy laptop","UserParam1":"src=ad1"}
591
+ {"Keyword":"buy desktop","UserParam2":"src=ad2"}
588
592
  {"Keyword":"купить ноутбук","AdGroupId":99999}
589
593
  ```
590
594
 
591
595
  - Row keys use WSDL CamelCase: `Keyword`, `AdGroupId`, `Bid`, `ContextBid`, `UserParam1`, `UserParam2`.
596
+ - `Bid` and `ContextBid` are documented `Keywords.add` fields, but they are strategy-dependent: `Bid` is only for manual strategies, and `ContextBid` is only for manual strategies with independent ad-network bid management. For automatic strategies, Yandex ignores these values and returns warning `10160`, so omit them from JSONL for auto-strategy / ad-network flows.
592
597
  - Autotargeting row fields are intentionally not accepted in batch mode; use single-item typed flags such as `--autotargeting-search-bid-is-auto`, `--priority`, `--autotargeting-category`, `--autotargeting-brand-option`, or `--autotargeting-settings-*`.
593
598
  - `--adgroup-id` provides the default group ID; rows can override it via per-row `AdGroupId`.
594
599
  - Each effective row must resolve `Keyword` and `AdGroupId`; unknown fields are rejected with the row number.
@@ -622,8 +627,8 @@ direct dictionaries get-geo-regions --name Moscow --region-ids 225,187 --exact-n
622
627
  direct clients get --fields ClientId,Login,Currency
623
628
 
624
629
  # Changes
625
- direct changes check --campaign-ids 1,2,3 --timestamp 2026-04-14T00:00:00 --fields CampaignIds,AdGroupIds,AdIds,CampaignsStat
626
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
630
+ direct changes check --campaign-ids 1,2,3 --timestamp 2026-04-14T00:00:00Z --fields CampaignIds,AdGroupIds,AdIds,CampaignsStat
631
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
627
632
  direct changes check-dictionaries
628
633
 
629
634
  # Keyword research and retargeting
@@ -1156,7 +1161,7 @@ lines with `\`.
1156
1161
  #### Flag Design Rules
1157
1162
 
1158
1163
  - List inputs use comma-separated CLI syntax where appropriate.
1159
- - Money and bid values are passed in micro-rubles (API-native format). Values below 100,000 trigger a validation hint suggesting the correct scale.
1164
+ - Money and bid values are passed only in micro-rubles, exactly as Yandex Direct API long fields define them. The CLI does not accept decimal currency amounts or convert currency units; values below 100,000 trigger a validation hint suggesting the correct scale.
1160
1165
  - Selector fields remain explicit flags, for example:
1161
1166
  - `--id`
1162
1167
  - `--campaign-id`
@@ -1166,19 +1171,22 @@ lines with `\`.
1166
1171
 
1167
1172
  #### Datetime Rules
1168
1173
 
1169
- - Datetime parameters must be passed in the format `YYYY-MM-DDTHH:MM:SS`.
1174
+ - Changes timestamps must include an explicit timezone: `YYYY-MM-DDTHH:MM:SSZ`
1175
+ or an offset such as `YYYY-MM-DDTHH:MM:SS+03:00`.
1176
+ - Other datetime parameters use their method-specific documented format.
1170
1177
  - Datetime values must be passed as a single shell token.
1171
- - Canonical examples must not use timezone suffixes like `Z`.
1178
+ - Canonical `changes` examples should use the `Z` suffix; explicit offsets are
1179
+ accepted and normalized to UTC.
1172
1180
  - Canonical examples must not use quoted space-separated datetime values.
1173
1181
 
1174
1182
  Use:
1175
1183
 
1176
1184
  ```bash
1177
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
1185
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
1178
1186
  ```
1179
1187
 
1180
- Do not use: a timestamp with a `Z` suffix, or a quoted timestamp that contains
1181
- a space between the date and time.
1188
+ Do not use: a `changes` timestamp without a timezone suffix, or a quoted
1189
+ timestamp that contains a space between the date and time.
1182
1190
 
1183
1191
  #### Documentation Contract
1184
1192
 
@@ -1193,14 +1201,14 @@ Valid canonical examples:
1193
1201
 
1194
1202
  ```bash
1195
1203
  direct campaigns get --ids 1,2,3
1196
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
1204
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
1197
1205
  direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
1198
1206
  direct dynamicads set-bids --id 789 --bid 12500000
1199
1207
  direct dictionaries get-geo-regions --region-ids 225 --fields GeoRegionId,GeoRegionName
1200
1208
  ```
1201
1209
 
1202
1210
  Invalid examples include command lines that pass raw JSON flags, use shell
1203
- line continuations, add timezone suffixes to CLI datetimes, or quote
1211
+ line continuations, omit the timezone suffix from `changes` datetimes, or quote
1204
1212
  space-separated datetime values.
1205
1213
 
1206
1214
  #### Кампании
@@ -1217,7 +1225,7 @@ direct campaigns add --name "Моя кампания" --start-date 2024-02-01 --
1217
1225
  direct campaigns add --name "Динамическая кампания" --start-date 2024-02-01 --type DYNAMIC_TEXT_CAMPAIGN --setting ADD_METRICA_TAG=NO --search-strategy HIGHEST_POSITION --network-strategy SERVING_OFF --dry-run
1218
1226
  direct campaigns add --name "Смарт-кампания" --start-date 2024-02-01 --type SMART_CAMPAIGN --network-strategy AVERAGE_CPC_PER_FILTER --filter-average-cpc 1000000 --counter-id 123 --dry-run
1219
1227
 
1220
- # CPA-стратегия (одна цель): --goal-id обязателен, --average-cpa/--bid-ceiling — micro-рубли
1228
+ # CPA-стратегия (одна цель): --goal-id обязателен, --average-cpa/--bid-ceiling — micro-rubles
1221
1229
  direct campaigns add --name "CPA-кампания" --start-date 2026-06-01 --type TEXT_CAMPAIGN --search-strategy AVERAGE_CPA --network-strategy SERVING_OFF --goal-id 1234567 --average-cpa 500000000 --bid-ceiling 1000000000 --counter-ids 111,222 --dry-run
1222
1230
 
1223
1231
  # Мульти-целевой CPA через PriorityGoals (пары goal_id:value, WSDL PriorityGoalsItem)
@@ -1236,6 +1244,7 @@ direct campaigns add --name "Смарт-настройки" --start-date 2026-06
1236
1244
  direct campaigns add --name "Смарт-пакетная" --start-date 2026-06-01 --type SMART_CAMPAIGN --counter-id 123 --package-strategy-id 700 --package-platform-search YES --package-platform-network NO --dry-run
1237
1245
  direct campaigns add --name "Мобильные настройки" --start-date 2026-06-01 --type MOBILE_APP_CAMPAIGN --setting ADD_TO_FAVORITES=YES --negative-keyword-shared-set-ids 10,11 --dry-run
1238
1246
  direct campaigns add --name "CPM-настройки" --start-date 2026-06-01 --type CPM_BANNER_CAMPAIGN --setting ADD_METRICA_TAG=YES --counter-ids 111,222 --frequency-cap-impressions 5 --frequency-cap-period-days 7 --video-target VIEWS --dry-run
1247
+ direct campaigns add --name "CPM-стратегия" --start-date 2026-06-01 --type CPM_BANNER_CAMPAIGN --network-strategy WB_MAXIMUM_IMPRESSIONS --average-cpm 120 --strategy-spend-limit 1000 --dry-run
1239
1248
  direct campaigns update --id 12345 --type CPM_BANNER_CAMPAIGN --frequency-cap-impressions 5 --frequency-cap-period-all --dry-run
1240
1249
 
1241
1250
  # Notification (Sms/Email) и TimeTargeting через явные CLI-флаги
@@ -1285,8 +1294,8 @@ direct ads get --campaign-ids 1,2,3
1285
1294
  direct ads get --adgroup-ids 45678 --format table
1286
1295
  direct ads add --adgroup-id 12345 --type TEXT_AD --title "Заголовок" --text "Текст объявления" --href "https://example.com" --dry-run
1287
1296
  direct ads add --adgroup-id 12345 --type TEXT_AD --title "Заголовок" --text "Текст" --href "https://example.com" --title2 "Второй заголовок" --display-url-path "deals" --mobile YES --vcard-id 111 --sitelink-set-id 222 --turbo-page-id 333 --ad-extensions "444,555" --dry-run
1288
- direct ads add --adgroup-id 12345 --type TEXT_AD --title "Заголовок" --text "Текст объявления" --href "https://example.com" --final-url "https://final.example.com" --video-extension-creative-id 777 --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --prefer-vcard-over-business NO --erir-ad-description "Объект текстового объявления" --dry-run
1289
- direct ads add --adgroup-id 12345 --type RESPONSIVE_AD --texts "Текст один,Текст два" --titles "Заголовок один,Заголовок два" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --erir-ad-description "Объект адаптивного объявления" --dry-run
1297
+ direct ads add --adgroup-id 12345 --type TEXT_AD --title "Заголовок" --text "Текст объявления" --href "https://example.com" --final-url "https://final.example.com" --video-extension-creative-id 777 --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --prefer-vcard-over-business NO --erir-ad-description "Объект текстового объявления" --dry-run
1298
+ direct ads add --adgroup-id 12345 --type RESPONSIVE_AD --texts "Текст один,Текст два" --titles "Заголовок один,Заголовок два" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB --business-id 777 --erir-ad-description "Объект адаптивного объявления" --dry-run
1290
1299
  direct ads add --adgroup-id 12345 --type SHOPPING_AD --feed-id 170 --default-texts "Текст по умолчанию" --sitelink-set-id 222 --ad-extensions "333,444" --business-id 777 --feed-filter-condition "CATEGORY:EQUALS_ANY:shoes|boots" --title-sources NAME,BRAND --text-sources DESCRIPTION --dry-run
1291
1300
  direct ads add --adgroup-id 12345 --type LISTING_AD --feed-id 171 --default-texts "Текст листинга по умолчанию" --feed-filter-condition "CATEGORY:EQUALS_ANY:appliances" --title-sources TITLE --text-sources DESCRIPTION --dry-run
1292
1301
  direct ads add --adgroup-id 12345 --type TEXT_AD_BUILDER_AD --creative-id 123 --href "https://example.com" --turbo-page-id 456 --erir-ad-description "Объект объявления из конструктора" --dry-run
@@ -1302,11 +1311,11 @@ direct ads update --id 99999 --type TEXT_AD --image-hash abcdefghijklmnopqrst
1302
1311
  direct ads update --id 99999 --type TEXT_AD --title2 "Новый второй заголовок" --vcard-id 222
1303
1312
  direct ads update --id 99999 --type TEXT_AD --callouts-add "111,222" --callouts-remove "333"
1304
1313
  direct ads update --id 99999 --type TEXT_AD --callouts-set "444,555"
1305
- direct ads update --id 99999 --type TEXT_AD --video-extension-creative-id 777 --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
1314
+ direct ads update --id 99999 --type TEXT_AD --video-extension-creative-id 777 --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
1306
1315
  direct ads update --id 99999 --type TEXT_AD --final-url "https://final.example.com" --age-label AGE_18 --business-id 777 --prefer-vcard-over-business NO --erir-ad-description "Объект текстового объявления"
1307
1316
  direct ads update --id 99999 --type DYNAMIC_TEXT_AD --text "Обновленный динамический текст" --callouts-add "111,222"
1308
1317
  direct ads update --id 99999 --type MOBILE_APP_AD --mobile-app-feature PRICE=YES --mobile-app-feature CUSTOMER_RATING=NO --video-extension-creative-id 777 --erir-ad-description "Объект мобильного объявления"
1309
- direct ads update --id 99999 --type RESPONSIVE_AD --texts "Текст один,Текст два" --titles "Заголовок один,Заголовок два" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123.45 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
1318
+ direct ads update --id 99999 --type RESPONSIVE_AD --texts "Текст один,Текст два" --titles "Заголовок один,Заголовок два" --image-hashes hash1,hash2 --video-extension-ids 111,222 --href "https://example.com" --price-extension-price 123450000 --price-extension-price-qualifier FROM --price-extension-price-currency RUB
1310
1319
  direct ads update --id 99999 --type TEXT_IMAGE_AD --final-url "https://final.example.com" --erir-ad-description "Объект графического объявления"
1311
1320
  direct ads update --id 99999 --type SHOPPING_AD --sitelink-set-id 222 --callouts-set "444,555" --business-id 777 --feed-filter-condition "CATEGORY:EQUALS_ANY:shoes|boots" --title-sources NAME,BRAND --text-sources DESCRIPTION --default-texts "Текст по умолчанию"
1312
1321
  direct ads update --id 99999 --type MOBILE_APP_IMAGE_AD --image-hash abcdefghijklmnopqrst --tracking-url "https://track.example.com" --erir-ad-description "Мобильное графическое объявление"
@@ -1328,9 +1337,8 @@ direct ads delete --id 99999
1328
1337
  `--callouts-set` для управления полем `TextAdUpdateBase.CalloutSetting`
1329
1338
  (`ext:AdExtensionSetting`) у существующего объявления — `--callouts-set`
1330
1339
  заменяет весь список выносок и взаимоисключим с инкрементальной парой
1331
- `--callouts-add` / `--callouts-remove`. Значения price-extension передаются как
1332
- человекочитаемые суммы и внутри CLI конвертируются в long-единицы API Яндекс
1333
- Директа. В `ads update` также поддерживается `--age-label`.
1340
+ `--callouts-add` / `--callouts-remove`. Значения price-extension передаются в micro-rubles напрямую, в том же
1341
+ long-формате, который ожидает API Яндекс Директа. В `ads update` также поддерживается `--age-label`.
1334
1342
  `--mobile` (по умолчанию `NO`) и
1335
1343
  `--ad-extensions` доступны только в `ads add` — WSDL `TextAdUpdate` не
1336
1344
  содержит `Mobile`, а в `ads update` расширения управляются через флаги
@@ -1398,18 +1406,19 @@ direct keywords delete --id 88888
1398
1406
  direct keywords add --adgroup-id 12345 --from-file keywords.jsonl
1399
1407
 
1400
1408
  # Inline JSON-массив
1401
- direct keywords add --keywords-json '[{"Keyword":"купить ноутбук","Bid":10000000},{"Keyword":"купить ПК"}]'
1409
+ direct keywords add --adgroup-id 12345 --keywords-json '[{"Keyword":"купить ноутбук"},{"Keyword":"купить ПК"}]'
1402
1410
  ```
1403
1411
 
1404
1412
  Пример `keywords.jsonl`:
1405
1413
 
1406
1414
  ```jsonl
1407
- {"Keyword":"купить ноутбук","Bid":10000000,"UserParam1":"src=ad1"}
1408
- {"Keyword":"купить ПК","ContextBid":5000000}
1415
+ {"Keyword":"купить ноутбук","UserParam1":"src=ad1"}
1416
+ {"Keyword":"купить ПК","UserParam2":"src=ad2"}
1409
1417
  {"Keyword":"buy laptop","AdGroupId":99999}
1410
1418
  ```
1411
1419
 
1412
1420
  - Ключи строки — WSDL CamelCase: `Keyword`, `AdGroupId`, `Bid`, `ContextBid`, `UserParam1`, `UserParam2`.
1421
+ - `Bid` и `ContextBid` — документированные поля `Keywords.add`, но они зависят от стратегии: `Bid` только для ручных стратегий, `ContextBid` только для ручных стратегий с независимым управлением ставками в сетях. Для автоматических стратегий Яндекс игнорирует эти значения и возвращает предупреждение `10160`, поэтому не передавайте их в JSONL для auto-strategy / РСЯ-сценариев.
1413
1422
  - Поля автотаргетинга намеренно не принимаются в batch-режиме; используйте single-item typed flags: `--autotargeting-search-bid-is-auto`, `--priority`, `--autotargeting-category`, `--autotargeting-brand-option` или `--autotargeting-settings-*`.
1414
1423
  - `--adgroup-id` задаёт значение по умолчанию; в строке можно переопределить через `AdGroupId`.
1415
1424
  - В каждой строке должны разрешаться `Keyword` и `AdGroupId`; неизвестные поля отклоняются с указанием номера строки.
@@ -1443,8 +1452,8 @@ direct dictionaries get-geo-regions --name Москва --region-ids 225,187 --e
1443
1452
  direct clients get --fields ClientId,Login,Currency
1444
1453
 
1445
1454
  # Изменения
1446
- direct changes check --campaign-ids 1,2,3 --timestamp 2026-04-14T00:00:00 --fields CampaignIds,AdGroupIds,AdIds,CampaignsStat
1447
- direct changes check-campaigns --timestamp 2026-04-14T00:00:00
1455
+ direct changes check --campaign-ids 1,2,3 --timestamp 2026-04-14T00:00:00Z --fields CampaignIds,AdGroupIds,AdIds,CampaignsStat
1456
+ direct changes check-campaigns --timestamp 2026-04-14T00:00:00Z
1448
1457
  direct changes check-dictionaries
1449
1458
 
1450
1459
  # Исследование ключевых слов и ретаргетинг