Skip to main content

Connect an MCP client

Connect the official Telegram Ads API key through the extension, then add https://api.tlmtr.dev/mcp/ads (dev) or https://api.tlmtr.io/mcp/ads (production configuration) to your AI client. Telemetrio opens a separate consent page for that client. The provider key stays encrypted on the server; the AI client receives scoped access, never the key. Existing Telemetrio analytics authorization does not grant Ads access.

Three permission groups​

PermissionScopeAllows
Read-onlytelemetrio:ads:readRead explicitly selected accounts, ads, statistics, transactions, reports, audiences, Pixel and targeting dictionaries. Required for every selected account.
Manage advertisingtelemetrio:ads:manageAccount information, creative and delivery changes, start/pause/delete, review submission, uploads, audiences and Pixel. Resuming funded ads can spend existing funds.
Manage budgetstelemetrio:ads:budgetAllocate/withdraw funds, CPM and daily budget limits. Ad creation requires both management groups.

Rights belong to each concrete connection/account pair. A scope union does not give every account every right. Related accounts can have different permissions, including access without the root. New accounts/connections never join existing grants automatically. Revocation blocks subsequent work and withheld results; disconnecting removes the provider credential for every client. Neither action revokes Telegram's own key.

Interactive Ads workspace​

Clients supporting MCP Apps can render Ads explorer and Review changes inside the conversation. Clients without a renderer receive the same structured and textual data. These tools use the existing Ads authorization; no provider key is passed to the widget. The UI is English and follows the host's light/dark theme.

ToolPurpose
ads_explore_adsBrowse one granted account, 50 ads per page, with lifetime metrics and account capabilities. Select, filter, sort, inspect details and compare ads.
ads_review_changesPrepare up to 20 changes in one account and show fresh before/after values. No Telegram mutation is sent.
ads_apply_reviewApply the sealed review after explicit user confirmation. Each operation reports its own result.
ads_inspect_reviewInspect operation results after an interruption without repeating provider writes.

Ask your AI client: “Open the Ads explorer for my personal account.” Select the account from ads_list_connections when several are available. Search and sorting operate on loaded ads; use Load more for additional pages. Metrics are lifetime, not a selected-period report. Missing clicks/metrics are shown as unavailable; actions are labeled by their provider type.

Select ads and choose pause/resume, title/text/CPM/daily-budget edits or budget allocation/withdrawal. Controls reflect each account's granted rights. The review shows separate allocation and withdrawal totals in the account currency. Resuming a funded ad can spend its existing budget. Preparing or editing a review never applies it; Confirm applies only the reviewed intent.

Reviews expire after 15 minutes and are bound to the original authorization and connection generation. If relevant ad values change, prepare a new review. A batch is not atomic: earlier changes may succeed even if a later one fails. A successful edit is read back; Not confirmed means Telegram accepted it but current values differ or could not be verified. Do not repeat blindly.

After an interrupted confirmation, use Inspect status. An unknown outcome is not automatically retried; reconcile the existing operation ID before creating another intent. Review status can be inspected for 24 hours. Revoked or replaced credentials block the old review. Standard canonical tools remain available for other API operations.

The single bundled resource is ui://telemetrio-ads/workspace-v1.html. It loads no external scripts, images or fonts; data and actions go through the host's existing MCP connection. The public OAuth bridge exposes only this exact UI resource.

Account capabilities before creating ads​

Read the selected account before planning a campaign:

  • Root: ads_api_get_current_account.
  • Related account: ads_api_get_accounts_by_id, with its exact granted ID.
  • ads_list_connections shows cached root currency and capabilities. Older connections can show unknown; refresh the connection or read the account.

Account results include capabilities, separately from your granted permissions:

AccountPermitted destination family
TONTelegram channels/posts, bots and Mini Apps; no external websites
EURTelegram destinations or external websites, subject to account and placement restrictions
Stars (XTR)Only the channel or bot that earned the Stars

These are versioned Telemetrio policies derived from currency. They do not represent a provider guarantee. Targeting, media, Pixel, retargeting and geographic delivery remain unknown until independently verified.

For Stars, the Ads API does not currently expose the earning-peer binding. Capabilities show bound_peer: null and bound_peer_status: unknown. This version blocks creation and destination changes with DESTINATION_BINDING_UNKNOWN and validation: requires_verification; use Telegram to verify and manage that source-specific destination. Reconnecting does not resolve the missing binding. Other permitted operations on existing ads remain available.

Create and destination-edit requests validate the actual selected account's currency before a provider write. TON/Stars website requests return DESTINATION_NOT_SUPPORTED with an English explanation and field: promote_url. The original Telegram error and requestId are retained if the provider rejects a request later. Use ads_get_operation to inspect the outcome; do not automatically retry, change the destination or switch accounts. The server performs no such substitutions.

Canonical tools and native parameters​

All 45 methods below are implemented as canonical tools. Tool visibility reflects usable rights; calls independently check exact rights and live credential generation. Each has strict input {connectionId, accountId?, params, operationId?}. Native fields stay inside params; required native fields below are marked *. Either accountId or native params.account_id selects the concrete account; if both are supplied, they must agree. Omitting both selects the provider root, so a related-only grant must name its account. Root-specific methods (current account, create account, related lists, batch account lookup and transaction status) retain their root context; requested or returned account data still requires explicit rights. Transfer methods use native account_id for the related endpoint and the connection root for the other endpoint. Batch IDs must all be granted. Use tools/list for complete types, constraints and method-specific descriptions.

Native methodMCP toolRequired group beyond Read-onlyNative parameters
createAccountads_api_create_accountManage advertisingtitle *, full_name *, email *, phone_number *, country *, city *, legal_name, idempotency_key
editAccountInfoads_api_edit_account_infoManage advertisingaccount_id, title, full_name, email, phone_number, country, city, legal_name
getAccountInfoads_api_get_account_info—account_id
getRelatedAccountsListads_api_get_related_accounts_list—offset, limit
increaseAccountBudgetads_api_increase_account_budgetManage budgetsaccount_id *, amount *, idempotency_key
decreaseAccountBudgetads_api_decrease_account_budgetManage budgetsaccount_id *, amount *, idempotency_key
getTransactionStatusads_api_get_transaction_status—transaction_id *
getCurrentAccountads_api_get_current_account—none
getAccountsByIdads_api_get_accounts_by_id—account_ids *
getAccountTransactionsListads_api_get_account_transactions_list—account_id, offset, limit
getAccountStatsads_api_get_account_stats—account_id, from_time *, to_time *, interval *
getAccountReportads_api_get_account_report—account_id, year *, month *
uploadAdPhotoads_api_upload_ad_photoManage advertisingaccount_id, file *
uploadAdVideoads_api_upload_ad_videoManage advertisingaccount_id, file *
uploadWebsitePhotoads_api_upload_website_photoManage advertisingaccount_id, file *
createAdads_api_create_adBoth management groupsaccount_id, title *, text, photo_id, video_id, promote_url *, cpm *, placement *, target *, impression_frequency, website_name, website_photo_id, button, conversion_event_id, additional_info, show_userpic, initial_budget, daily_budget_limit, is_paused, activate_date, deactivate_date, schedule, return_target, idempotency_key
editAdads_api_edit_adBy field: advertising and/or budgetsaccount_id, ad_id *, title, text, photo_id, video_id, promote_url, cpm, impression_frequency, website_name, website_photo_id, button, conversion_event_id, additional_info, show_userpic, daily_budget_limit, is_paused, activate_date, deactivate_date, schedule, return_target
editAdStatus (deprecated alias → editAd)ads_api_edit_ad_statusManage advertisingaccount_id, ad_id *, is_paused *, return_target
increaseAdBudgetads_api_increase_ad_budgetManage budgetsaccount_id, ad_id *, amount *, return_target, idempotency_key
decreaseAdBudgetads_api_decrease_ad_budgetManage budgetsaccount_id, ad_id *, amount *, return_target, idempotency_key
submitAdForReviewads_api_submit_ad_for_reviewManage advertisingaccount_id, ad_id *, return_target
deleteAdads_api_delete_adManage advertisingaccount_id, ad_id *
getAdsByIdads_api_get_ads_by_id—account_id, ad_ids *, return_target
getAdsListads_api_get_ads_list—account_id, offset, limit, return_target
getAdTransactionsListads_api_get_ad_transactions_list—account_id, ad_id *, offset, limit
getAdStatsads_api_get_ad_stats—account_id, ad_id *, from_time *, to_time *, interval *
createAudienceads_api_create_audienceManage advertisingaccount_id, title *, add_phones, idempotency_key
editAudienceads_api_edit_audienceManage advertisingaccount_id, audience_id *, title, add_phones, remove_phones, reset_phones
deleteAudienceads_api_delete_audienceManage advertisingaccount_id, audience_id *
getAudiencesByIdads_api_get_audiences_by_id—account_id, audience_ids *
getAudiencesListads_api_get_audiences_list—account_id, offset, limit
createPixelads_api_create_pixelManage advertisingaccount_id, idempotency_key
getPixelads_api_get_pixel—account_id
createPixelEventads_api_create_pixel_eventManage advertisingaccount_id, title *, type *, idempotency_key
editPixelEventads_api_edit_pixel_eventManage advertisingaccount_id, event_id *, title *
deletePixelEventads_api_delete_pixel_eventManage advertisingaccount_id, event_id *
getPixelEventsByIdads_api_get_pixel_events_by_id—account_id, event_ids *
getPixelEventsListads_api_get_pixel_events_list—account_id, offset, limit
getTargetLanguagesListads_api_get_target_languages_list—none
getTargetTopicsListads_api_get_target_topics_list—none
getTargetCountriesListads_api_get_target_countries_list—none
getTargetLocationsByIdads_api_get_target_locations_by_id—location_ids *
getTargetLocationsListads_api_get_target_locations_list—country_code *, query *, offset, limit
getTargetChannelads_api_get_target_channel—channel_id *, for_excluding
getTargetBotads_api_get_target_bot—bot_id *

editAdStatus is retained only as a compatibility alias to editAd with is_paused; prefer ads_api_edit_ad. There are also nine convenience read tools: ads_list_connections, ads_list_ads, ads_get_ad, ads_get_account_stats, ads_get_ad_stats, ads_get_transactions, ads_get_account_report, ads_get_targeting_options and ads_lookup_target. Convenience data tools use the root account and cannot expose an ungranted root. ads_list_connections includes actual authorized accountAccess rows; related-only grants omit root metadata.

Money and CPM use the selected account currency (EUR, TON or XTR), not cents or a currency conversion. initial_budget allocates funds; is_paused and scheduling control delivery. Account transfers need Manage budgets on both endpoints, and transaction status needs Read-only on both returned endpoints. succeeded for the request does not mean the transfer settled: explicitly poll ads_api_get_transaction_status using transaction_id until native status is completed or failed.

Timestamps use Unix seconds. Statistics have an exclusive end and at most 1000 intervals of 300 or 86400 seconds. A native schedule uses seven 24-bit week_hours_mask values, one hour per bit, and a fixed UTC timezone offset in seconds, or use_viewer_timezone for users targeting. Pass schedule:false to clear scheduling. Preserve native provider day/hour ordering and allowed timezone values; no IANA timezone conversion is performed. Other native targeting/media rules remain provider validations.

Explicit mutation and recovery​

Reads reject operationId. Before each mutation, generate a high-entropy UUIDv4 (or 16–128 ASCII letters/digits/underscore/hyphen ID) for that one intent. If supplying native idempotency_key, use exactly the same value. Results contain {result,operationId,status:"succeeded",replayed}. Never change the ID just because a request times out.

There is no automatic retry. Use ads_get_operation({connectionId,operationId}) to inspect safe status and retry guidance without sending a provider mutation. An explicit identical retry with the same grant, credential generation, account, payload and staged bytes is allowed only within the original 24 hours. Cached results can be replayed; IDs cannot be recycled after the window. OPERATION_PENDING means another call owns the intent; IDEMPOTENCY_MISMATCH means its payload changed; OPERATION_EXPIRED requires reconciliation. Transport/protocol/post-dispatch failures may return OPERATION_OUTCOME_UNKNOWN with the original operation ID. Reconcile the original outcome; a rejected retry does not prove that the first call failed. Revoked/rotated credentials cannot recover hidden cached results under a different binding.

Staged binary uploads​

  1. Compute the unchanged file's byte count and lowercase SHA-256. Call ads_prepare_file_upload with connectionId, optional accountId, purpose (uploadAdPhoto, uploadAdVideo or uploadWebsitePhoto), mimeType, byteCount, and sha256.
  2. PUT exact bytes to the returned fixed-origin url, with Authorization: Bearer <uploadToken> and returned contentType. The opaque credential authorizes only this upload, with no GET, list or MCP access. Do not send the provider key.
  3. After a successful PUT, call the corresponding canonical upload tool with params.file:{uploadId} and one stable operationId. Its native result supplies the photo/video ID for subsequent ad edits.

Ad photos allow JPEG/PNG up to 5 MiB, ad videos MP4 up to 20 MiB, and website photos JPEG/PNG up to 1 MiB. Preparation expires in 15 minutes; streams have 10-second idle and 30-second total deadlines. URLs, local paths, base64 and binary bodies in MCP JSON are rejected. An upload belongs to one operation ID; unknown outcomes retain its original bytes through recovery, while successful uploads release bytes and retain replay metadata. A second operation cannot consume the same upload.

Bounds and verification​

Ads MCP JSON is bounded to 2 MiB; native provider responses to 8 MiB; complete MCP responses to 32 MiB. Account discovery and owner grant management are paged. GET /v1/mcp-grants/page?offset=0&limit=20 returns {grants,nextOffset}; each complete page is at most 4 MiB and may contain fewer rows than requested. Follow advancing offsets until null. Extension automatic processing is capped at eight pages and 8 MiB of retained safe metadata; incomplete or malformed access displays unavailable rather than an inferred denial. Manage the complete grant list in Telemetrio.

The internal /v1/mcp credential stays between the issuer and Ads service. It is never a browser input or chatbot secret. Ordinary verification uses synthetic provider fixtures/read-only live checks. All 45 methods are covered synthetically; this is not evidence of live writes, hosted rollout, or provider acceptance of every creative. Live provider mutations require explicit authorization for concrete test accounts/actions.