TagdsDocs

Tagds documentation

How the Tagds Telegram ad network works, step by step: share listings and earn per player, launch a promotion, connect your bot or Mini App, and monetize your app or channel.

Contents
Start here

What is Tagds?

Tagds is an ad network for Telegram. Advertisers fund a balance; their ads run inside Mini Apps, bots, channels, and in promoters' posts. Whoever spreads an ad earns for the real results it brings.

AdvertiserTops up a balance

USDT or GRAM on TON; the balance is kept in dollars.

Tagds

Measures, counts, filters fake traffic; closes each day.

PublisherImpressions and clicks

Standard share 70%; held 7 days, queued for payout from $10.

PromoterPlayers' steps

The full step amount; held 7 days, paid manually by Tagds.

How money flows. Earnings settle at the end of the day and become withdrawable after the holding period.

Three roles, three panels

Advertiser
Wants players, users or channel members. Tops up a balance and runs campaigns or promotion listings. Panel: advertiser.tagds.net
Publisher
Owns a Mini App, a bot, a Telegram channel or group. Shows or posts ads and earns from impressions and clicks. Panel: publisher.tagds.net
Promoter
Has an X account, a Telegram channel or group — or none of these and shares the link wherever they like. Shares promotion listings and earns from the steps their players take. Panel: promoter.tagds.net

All three roles live in one account: sign up with one role, then add another from My panels in the account menu. In Telegram, send /start to @tagdsbot: the Advertise · Earn with my app · Earn by sharing buttons open the same panels inside Telegram. Panels are in English, Turkish and Russian. No ID documents (KYC) are required.

How does the money flow?

  • Top-up. The advertiser sends USDT or GRAM on the TON network and puts their personal code in the comment. Minimum $1. GRAM is converted to dollars at the rate when it arrives; the balance is always kept in dollars.
  • Spend. Impressions (CPM), clicks (CPC), joins (CPA), or — for promotions — the steps players take. Spend comes off the balance right away and is settled at the end of the day.
  • Publisher earnings. A standard 70% of what advertisers spend in that app or channel (it can differ per app). Held 7 days; once the withdrawable balance reaches $10, a payout is queued by itself and sent as USDT to the publisher's TON wallet. For now the Tagds team sends queued payouts in order; once automatic sending is switched on, they'll go out on their own.
  • Promoter earnings. The full step amount shown on the listing; the Tagds commission is charged to the advertiser on top. Held 7 days; payouts are manual for now, to a Tron (TRC-20) or TON address.
  • Refunds. If traffic is found to be fake during the holding period, the money spent on it goes back to the advertiser.
Promoters

For promoters

You get paid for players, not for followers. Share advertisers' listings on Telegram and X; every time a player who came through your link starts the game, keeps playing or makes a deposit, you earn the amount shown on the listing.

  1. Sign up

    At promoter.tagds.net, or in Telegram: @tagdsbot → Earn by sharing.

  2. Wait for approval

    Sharing unlocks once the Tagds team approves your account.

  3. Choose how you share

    Let the bot post or I'll share myself.
  4. Share a listing

    Take the text, the image and your personal link, and post it.

  5. Get paid

    Each step a player takes is added to your earnings and becomes withdrawable after 7 days.

Sign-up and approval

Sign up in one of two ways:

  • Web: promoter.tagds.net → Create account. An email and a password are all you need (10–200 characters; very common passwords and passwords containing your email are rejected).
  • Telegram: send /start to @tagdsbot → Earn by sharing. The panel that opens inside Telegram also asks for an email and a password; your Telegram account is linked to it, and next time you're signed in straight away.

After sign-up your account shows Your account is awaiting approval: you can browse listings and add your accounts, but you can't open shares yet. Sharing unlocks as soon as the Tagds team approves you. No documents are needed.

First sign-in: choose how you share

The first time you sign in, the panel asks How will you share listings?. You choose once and can switch later under Sharing mode in the account menu, or with Change on the strip at the top of the Listings screen.

OptionHow it worksWhat you need
Let the bot postThe Tagds bot posts listings to your Telegram channel or group by itself: every day between 10:00 and 22:00, up to 3 posts per channel.Make the bot an admin of your channel or group. Whoever adds the bot must be the chat's owner.
I'll share myselfYou see listings as cards; you take the text, the image and your personal link, and post them yourself on X, Telegram or anywhere else.Nothing: you can share without adding any account.

The Listings screen

Listings is the panel's home screen. A thin earnings strip runs across the top: Withdrawable, Pending (with the next unlock date), Advance or Owed, your sharing mode, and Payouts. Below it is the Players you brought chart: day by day over the last 7, 14 or 30 days, how many of your players started, played 2+ days, stayed 7 days and deposited (plus, on Mini App listings, opened); filter it by listing and by account. Then the listing cards.

Sample listing card (illustration; amounts are examples).

  1. 1Image. The advertiser's image; your share kit turns it into an image sized for each platform.
  2. 2Platforms. Where you may share this listing (Telegram, X), shown in the top-right corner.
  3. 3Steps and amounts. What you earn for each step of each player you bring. A step marked "tracked" is counted but not paid.
  4. 4Your result. Your shares, players and earnings on this listing.
  5. 5Share buttons. In self-sharing mode, Share on Telegram / Share on X per platform; in bot mode, The bot is posting · n/G today and the Post with the bot switch.

Sharing it yourself: the share kit

  1. Pick a listing

    Tap Share on Telegram or Share on X on the card.

  2. Choose an account and a language

    If you've linked accounts on that platform, pick one — or choose Without an account; with no accounts, the kit opens straight away. Pick the Post language (EN, TR, RU) and tap Get the share kit.

  3. Take the kit

    Your link (copy it), the text (Copy text; already fits X's 280 characters) and the image (Download image: 1280×720 for Telegram, 1200×675 for X). Inside Telegram, long-press the image to save it.
  4. Post it

    Write on X or Share on Telegram opens the text ready to go, or paste it yourself. Use the link exactly as given.
  5. Optional: verify

    Paste your tweet link (X) or post link (Telegram) into the kit — see below.

A kit opened without an account stays on the card under Today's kits for the rest of the day; reopening it for the same listing and platform doesn't use another share. Old tagds.net/r/… links keep working; new kits give you a direct t.me link.

Daily sharing limit

Each account can open up to 3 shares a day (Tagds keeps this between 1 and 3). Every kit you open uses one share from that account; the limit resets at midnight Türkiye time (UTC+3).

  • A kit opened with a linked account counts against that account. Each account has its own limit.
  • A kit opened without an account counts per platform (3 for Telegram, 3 for X).
  • Bot posts use the same limit, per channel.
  • When it's used up, you'll see Today's limit used, resets tomorrow.

The limit only caps how many kits you open. There's no cap on how many players one post can bring; once a listing's daily or total cap is reached, steps are still recorded but not paid.

Verifying on X and Telegram

Verification records where you posted, and the advertiser sees it in their results table. Earnings depend on players who arrive through your link — they count whether or not you verify.

X

After tweeting, paste the tweet's link (https://x.com/<user>/status/<number>) into Tweet link in the kit and tap Verify. Tagds checks the tweet's author and that your link is in the text. If you've added your X account to the panel, the tweet must come from that account, and your first valid tweet verifies the account too. One tweet verifies one share.

Telegram

Paste the post's link (https://t.me/<channel>/<number>) into Post link (optional). If you shared with a linked channel, the link must point to that channel. The post's content isn't read.

Let the bot post: set it up in two steps

When you choose Let the bot post, the panel opens Set up bot posting. Until both steps are done, listings stay closed and the bot posts nowhere. To go on without the bot, tap I'll share myself on the same screen.

  1. Link your Telegram account

    Get the link → Open in Telegram → Start in the bot. Open it from the Telegram account that owns the channel or group. The link is valid for 15 minutes and is just for you; the screen moves to step two by itself. If you signed up inside Telegram, this step is already done.
  2. Pick your channel or group

    Type (Channel or Group) → Get the link. The link is valid for 30 minutes.

  3. Make the bot an admin

    The button opens Telegram. Pick your channel or group and make the bot an admin. The bot checks that you're the chat's owner and reads the member count; accounts that are only admins aren't accepted.

  4. Done

    The screen updates by itself, the channel shows Verified and your listings open. Once your profile is approved, the bot starts posting. To add more channels: My accounts → Add account.

How does the bot post?

  • Every day between 10:00 and 22:00 (Türkiye time), up to 3 posts per channel, spread across the day (with 3, no earlier than 10:00, 14:00 and 18:00).
  • At least 60 minutes between two posts in the same channel; the same listing goes to the same channel at most once every 24 hours.
  • Listings rotate: the one that hasn't been posted in that channel for the longest goes first.
  • Each post has the listing's image, the advertiser's text and your personal link. The text is in your panel language.
  • Only listings open to Telegram whose advertiser has a balance are posted. The bot can't post X-only listings; you share those yourself.
  • Turn off any listing you don't want with the Post with the bot switch on its card.

How do you earn?

On every listing, the advertiser sets the steps a player can take and how much each step pays. When a player who came through your link completes a step, that amount is added to your earnings. Amounts differ from listing to listing; you'll see them on the card.

  1. 01OpenedOpened the Mini App through your link (measured on Mini App listings only).
  2. 02StartedStarted the game or the bot.
  3. 032 daysPlayed on at least 2 days.
  4. 047 daysStayed active for 7 days.
  5. 05DepositMade a deposit in the game.
$ marks steps that can pay. The advertiser chooses which steps pay and how much; a step set to 0 shows as "tracked" — counted, not paid.

Worked example

StepPer playerPlayersYou earn
Started the game$0.10100$10
Stayed 7 days$0.1530$4.50
Made a deposit$15$5
Total$19.50

An example: 100 people started the game through your link, 30 stayed for 7 days, 5 made a deposit. Real amounts are on each listing. Each player pays out once per step.

Which players count?

Counted

  • A real Telegram account that arrived through your link, with the step reported by the advertiser's bot.
  • Each Telegram account once per listing — and each of its steps once.
  • First touch wins: whichever link brought the person to that listing first gets all of their later steps.
  • Steps taken within 30 days of the player's first arrival.

Not counted

  • Someone who already came to the same listing through another promoter's link.
  • The same step completed a second time.
  • A step taken more than 30 days after the player's first arrival.
  • Someone who opened the Mini App but never started the game (shown separately as "opened but didn't start").

Holding period, advances and payouts

  • Holding period. Earnings settle at the end of each day and become withdrawable 7 days later. The Unlock calendar on Payouts shows how much unlocks on which day.
  • Payout address. Payouts → Payout address. Tron (TRC-20): 34 characters starting with T; you receive USDT (TRC-20) or TRX. TON: 48 characters starting with UQ… or EQ…; for an exchange address (e.g. Binance TON) add the memo — it may be required.
  • Payout. Manual for now: the Tagds team sends your withdrawable amount to your address and records the transaction ID (tx) in the panel; you'll find it under Payout and advance history. The $10 payout threshold for publishers doesn't apply to promoters.
  • Advance. A trust payment from Tagds, deducted from your first earnings. Until your earnings cover it, the strip shows Owed and nothing becomes withdrawable.

Refunds and fake traffic

Advertisers pay for real players. The following count as fake traffic:

  • Starting the game with your own Telegram accounts, second accounts or bot accounts.
  • Bringing the same person in through several accounts.
  • Tricking the advertiser's bot into reporting steps.

If fake traffic is found, your account is suspended: you can't open new shares, and your old links still work but their conversions aren't paid. The affected earnings still in the holding period are taken back and refunded to the advertiser. Earnings that have already passed the holding period are not taken back.

Frequently asked questions

What if two promoters share the same listing?

Each promoter has their own link. A player is credited to whoever's link brought them to the listing first; tapping someone else's link later doesn't change that.

What if someone else shares my link?

The code in the link identifies you: wherever it's posted, players who come through it are credited to you. You're also responsible if your link is spread through spam or fake traffic.

Why wasn't a player counted?

  • They had already come to the same listing through another link (first touch).
  • They had completed that step before, or more than 30 days had passed since they first arrived.
  • They opened the Mini App but never started the game.
  • The advertiser's bot didn't report the step.
  • The step was counted but not paid: the advertiser's balance ran short, the listing's daily or total cap was reached, or your account was suspended at the time.

I have few followers. Can I still earn?

Yes. Pay depends on the steps of the players you bring, not on follower counts. Follower and member numbers are for information only.

What happens if I delete my post?

Players who already came through your link keep counting for their steps within the 30-day window.

Can I share without adding an account?

Yes. In I'll share myself mode you can open a kit without any account; tracking happens through the link. Bot posting needs a linked channel or group.

When do I get paid?

Each day's earnings become withdrawable after 7 days. The Tagds team sends payouts manually to your saved Tron (TRC-20) or TON address.

Which languages can I post in?

Every share kit includes English, Turkish and Russian text; if the advertiser didn't write one of them, it falls back to the first one they did write.

Advertisers

For advertisers

Run your ads in Telegram Mini Apps, bots, channels and promoters' posts. With the Promotion format you pay only for results: players who start, keep playing and deposit.

Sign-up and top-up

  1. Sign up

    advertiser.tagds.net → Create account (email and password), or in Telegram: @tagdsbot → Advertise.
  2. Open Balance

    Balance: choose USDT or GRAM. You'll see Tagds' TON address, your personal comment code (TG-XXXXXXXX), a QR code and an Open in wallet button.
  3. Send

    Send on the TON network from your wallet with the code in the comment field, exactly as shown. Minimum $1.

  4. See it on your balance

    Once the transaction is final it's credited in dollars (usually within a minute); the screen refreshes by itself.

Ad formats

FormatWhere and howYou pay
BannerA slim strip on a Mini App page.CPM or CPC
RewardedThe user watches to the end and gets a reward in the app.CPM
InterstitialOpens between two screens or two levels; the close button is always visible.CPM
TaskAsks the user to join your channel or bot.CPA (per join)
Channel postThe Tagds bot posts your ad in Telegram channels and groups.CPC (per click)
PromotionPromoters share your listing on X and Telegram; players land in your bot or Mini App.Per step (CPA)

Current minimum bids are in the Formats and prices table on the home page. Targeting: country and the user's Telegram language; for channel posts, a minimum member count. Ads stop by themselves when the daily budget is spent or the balance runs out.

Creating a promotion listing

Campaigns → New campaign → format Promotion. The wizard shows the live listing card and a preview of the share text on the right; saving is a single step.

Title, description
The title and short description on the promoter's card.
Share text (EN · TR · RU)
What promoters copy: at least one language, up to 1,000 characters. Wherever you write {link}, the promoter's personal link goes in; leave it out and the link is added at the end. On X, text over 280 characters is shortened and the link stays at the end. A language you skip falls back to the first one you wrote. No hashtags or short codes needed.
Image
PNG, JPEG or WebP; up to 1 MB, at least 300×150 px. In the kit it's fitted to 1280×720 for Telegram and 1200×675 for X.
Platforms
Telegram, X or both. Promoters can share only on the platforms you choose; the bot only posts listings that include Telegram.
Destination
Bot: the player opens your bot via t.me/<bot>?start=<code>. Mini App: your Mini App opens via t.me/<bot>/<short name>?startapp=<code>; ownership verification is required (below).
Bot
Your bot's username (t.me/<bot>; ends in "bot").
Steps and amounts
Built-in steps: baslatti (started the game), aktif_2 (played at least 2 days), aktif_7 (active for 7 days), yatirdi (made a deposit) — or your own name (lowercase letters, digits, _). Up to 10 steps. The amount is what the promoter receives; set 0 and the step is tracked only. At least one step must pay.
Daily and total cap
The daily cap is required, the total cap optional: the most that can come off your balance (commission included). Once a cap is reached, steps are recorded but not paid.
Notification URL
An optional https address; see Integration.

How the commission is applied

Promoters receive the full amount you set. The Tagds commission (30%) is added on top: you pay amount × 100 / (100 − 30), rounded up. The wizard shows what you pay next to each step.

Promoter getsYou payTagds
$0.10$0.142858$0.042858
$0.15$0.214286$0.064286
$1$1.428572$0.428572

Secret key and going live

When you save, the secret key is shown once; store it safely (it signs your conversion reports). Listings without a key aren't visible to promoters. Then tap Send for review.

Review

Tagds reviews every campaign and listing before it goes live: Draft → Send for review → In review → Live or Rejected (the reason appears in the panel; fix it and send again).

  • A listing can't be approved without a balance; top up first.
  • Changing a live listing's share text, platforms, bot or destination (Mini App short name, bot id) sends it back to review. Step amounts, caps and the notification URL don't.
  • For other formats, changing the title, text, button, link or image sends the campaign back to review.
  • A Mini App listing can't be sent for review or go live until ownership is verified.
  • Banned categories (gambling, adult) are not accepted.

Manage a live listing with Pause / Resume; a paused listing disappears from promoters' lists.

Mini App setup and ownership verification

  1. Set the destination

    In the listing, set Destination to Mini App. Enter your bot's username, the Mini App's short name (t.me/<bot>/<short name>; leave it empty for the bot's main Mini App) and the bot's numeric id. The numeric id is the number before the ":" in your bot token — never paste the token itself anywhere.

  2. Add the measurement script

    Once you save, the listing shows a Setup and verification section. Add the measurement script as one line in your Mini App page's <head>, after telegram-web-app.js:

    HTML
    <!-- Your Mini App's HTML: one line after Telegram's script -->
    <script src="https://telegram.org/js/telegram-web-app.js"></script>
    <script src="https://tagds.net/sdk/v1/tagds.js" data-olcum async></script>
  3. Open the verification link

    Open the verification link from the panel (t.me/<bot>/<short name>?startapp=<verification code>) in Telegram. When the Mini App opens, the script sends Telegram's signed launch data to Tagds. This link isn't a promoter share: it isn't counted or paid.

  4. Verified

    Tagds checks that the signature belongs to your bot; within a few seconds the section shows Verified (it refreshes by itself). Now Send for review.

If it doesn't verify

  • A wrong numeric bot id means the signature won't match; the panel's signature error count goes up.
  • If your Mini App has a Content-Security-Policy, add https://tagds.net to script-src and connect-src, or the request won't go out.
  • Open the link in Telegram, not in a browser. The launch data must be less than 24 hours old.
  • If the destination, bot or short name changes later, verification resets and the listing goes back to review; open the link again.

Keep the script on the page after verification: it measures every launch through a promoter's link (Opened) and powers the "opened but didn't start" filter.

Tracking results

The Promoters section of the campaign page has: listing on/off, steps, caps, notification URL, secret key (create / regenerate), Node.js and curl samples, and a results table by period. Each promoter × account is one row (shares without an account get one row per platform), with a daily chart.

  1. 01OpenedOpened the Mini App through a promoter's link (measurement script).
  2. 02Startedbaslatti
  3. 032 daysaktif_2
  4. 047 daysaktif_7
  5. 05Deposityatirdi
On Mini App listings, people who opened more than 24 hours ago without starting show up in the "opened but didn't start" rate; nothing is paid for them.

Steps that weren't paid because your balance couldn't cover them are counted separately. Spend comes off your balance right away, settles at the end of the day, and shows in Ledger.

Developers

Integration

Promotion tracking has two parts: capture the code when a player arrives through a promoter's link, then send Tagds a signed report each time the player completes a step. In a Mini App, the measurement script reports the launch for you.

Flow

  1. PromoterShares t.me/game_bot?start=AbC… or t.me/game_bot/play?startapp=AbC…
  2. PlayerTaps it; Telegram opens your bot with /start AbC… or your Mini App with start_param = AbC….
  3. Your bot / Mini AppStores the code with the player's Telegram id (first code wins).
  4. Measurement scriptIn a Mini App, reports the launch to Tagds (Opened); optionally Tagds.basladi().
  5. Your serverWhen the player completes a step: POST /api/donusum + X-Tagds-Imza.
  6. TagdsChecks first touch, duplicates, the 30-day window, caps and balance; counts it and credits the promoter.

Reading the start / startapp parameter

Bot

For a t.me/<bot>?start=<code> link, Telegram sends your bot the message /start <code>. Store the code with the player's Telegram id; if the player already came with another code, keep the first one (Tagds also counts first touch).

JavaScript
// In your bot's /start handler: take the code from "/start AbC…"
// (Telegram sends this message when someone opens t.me/<bot>?start=<code>)
const m = /^\/start(?:@\w+)?\s+([A-Za-z0-9_-]{16,64})$/.exec(message.text || "");
if (m) {
  const code = m[1]; // the promoter's code (22 characters)
  await db.saveFirstCode(message.from.id, code); // keep the player's first code; don't let a later code overwrite it
}

Mini App

For a t.me/<bot>/<short name>?startapp=<code> link, the code is in initData's start_param field (on the client: Telegram.WebApp.initDataUnsafe.start_param). Telegram only provides it when the app is opened through the link, so store it on first launch. On your server, read it after validating initData with your own bot token:

JavaScript
// On your server: validate initData with your own bot token first (Telegram's rule),
// then read start_param and the player's id
const params = new URLSearchParams(initData); // Telegram.WebApp.initData (raw string)
const code = params.get("start_param");       // the promoter's code, or null
const user = JSON.parse(params.get("user"));  // user.id = telegramId

Measurement script (Mini App)

Required for listings that point to a Mini App. No dependencies, and it never breaks your game (fails silently, 5-second timeout).

HTML
<!-- Your Mini App's HTML: one line after Telegram's script -->
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<script src="https://tagds.net/sdk/v1/tagds.js" data-olcum async></script>
  • On launch, if start_param is a Tagds code, it posts Telegram's signed initData to POST /api/olcum/acilis. Tagds verifies the signature against the listing's bot id: the launch counts as Opened and the player is matched to the link (first touch).
  • Opened with the verification code, it only verifies ownership — nothing is recorded or attributed.
  • Opened without a code, it sends nothing.

Tagds.basladi()

JavaScript
// When the player actually starts playing (e.g. enters the first level)
if (window.Tagds) Tagds.basladi(); // reports the baslatti step; no secret key needed

Call it when the player really starts playing: it reports the baslatti step, no secret key needed. If your server also sends a signed baslatti report, whichever arrives first counts and the other is treated as a duplicate. If the listing has no such step, nothing is counted.

HTTPResponseMeaning
200{"ok":true,"acilis":true,"eslesme":true}Launch recorded, player matched to the link.
200{"ok":true,"dogrulama":true,…}Launched with the verification code: ownership verified only.
400govde · bot_id_yokBody isn't {initData}, or the listing has no numeric bot id.
401imza · zamaninitData isn't from this bot, or it's older than 24 hours.
404kod_yokUnknown code.

Conversion report: POST /api/donusum

HTTP
POST /api/donusum HTTP/1.1
Host: tagds.net
Content-Type: application/json
X-Tagds-Imza: <hex(HMAC-SHA256(secret, raw body))>

{"clickId":"AbCdEfGhIjKlMnOpQrStUv","telegramId":123456789,"adim":"baslatti","ts":1760000000}
clickId · string
The code from the link (the start or start_param value): 16–64 characters; letters, digits, _ and -.
telegramId · number
The player's Telegram user id (a digit string works too).
adim · string
A step defined on the listing: baslatti, aktif_2, aktif_7, yatirdi or your own name (up to 32 characters).
ts · integer
Unix time in seconds; within ±5 minutes of Tagds' clock.

Signature

X-Tagds-Imza = hex(HMAC-SHA256(secret key, raw body)). It's computed over the exact bytes you send: don't re-serialize the body or add whitespace after signing. A sha256= prefix is also accepted. The body is JSON, up to 4 KB.

Responses

HTTPneden / durumMeaningWhat to do
200sayildi: trueCounted and credited to the promoter (also for 0-amount steps).—
200durum: askida · tavan · bakiye_yokRecorded but not paid: promoter suspended, cap reached, or balance couldn't cover the fee.Don't resend; check balance and caps.
200neden: tekrarThis player already has this step.Ignore; retrying is safe.
200neden: pencereMore than 30 days since the player first arrived.Ignore.
200neden: tik_baska_oyuncudaAn old one-time /r/ code is tied to another player.Ignore.
400govdeMalformed body or missing field.Fix the body.
400adim_yokThe step isn't defined on the listing.Check the listing's steps.
401imzaSignature mismatch.Check the key, the raw body, lowercase hex.
401zamants is outside ±5 minutes.Sync your server clock (NTP).
404tik_yokUnknown code.Make sure you read the code correctly.
413—Body larger than 4 KB.—
429hizMore than 600 requests per minute from one IP.Back off and retry.
200
{"ok":true,"sayildi":true,"durum":"sayildi","donusum_id":4182}
200 · duplicate
{"ok":true,"sayildi":false,"neden":"tekrar"}
401
{"ok":false,"neden":"imza","error":"İmza geçersiz"}

Lookup: GET /api/donusum/tik/:code

Asks which listing and promoter a code belongs to. Signature: hex(HMAC-SHA256(secret key, <code>.<ts>)) in the same X-Tagds-Imza header, with ts in the query string.

Node.js
// Ask which listing and promoter a code belongs to
export async function lookup(code) {
  const ts = Math.floor(Date.now() / 1000);
  const signature = crypto.createHmac("sha256", SECRET).update(code + "." + ts).digest("hex");
  const res = await fetch(TAGDS + "/api/donusum/tik/" + code + "?ts=" + ts, { headers: { "X-Tagds-Imza": signature } });
  return res.json(); // { ok, kampanya_id, tanitimci, hesap, platform, … }
}
200
{"ok":true,"clickId":"AbCdEfGhIjKlMnOpQrStUv","baslangic":true,"kampanya_id":12,"paylasim_id":345,"tanitimci_id":67,"tanitimci":"@promoter","hesap":"@channel","platform":"telegram","at":"2026-10-21T09:12:44.000Z","oyuncu":null,"adimlar":[]}

For a share code (baslangic: true), oyuncu and adimlar come back empty because the code brings many players. For an old /r/ code, the player and their steps are included. Error codes are the same as for conversion reports.

Notification URL (optional)

If you set an https address on the listing, Tagds calls it with GET on the first baslatti step of each new player who came through a link, so you can capture promoter details on your side.

URL
https://api.example.com/tagds?click=[clickId]&campaign=[campaignId]&promoter=[promoterId]&account=[account]&platform=[platform]&ts=[ts]
PlaceholderValue
[clickId]The code from the link
[campaignId]The campaign (listing) id
[promoterId]The promoter's id
[promoterName]The promoter's name
[account]@channel or x.com/account; empty if unknown
[platform]telegram or x
[shareId]The share id
[ts]Match time (Unix seconds)
  • Values are URL-encoded.
  • https only, port 443, a domain name (no IP addresses, no localhost).
  • 5-second timeout, 3 attempts (1 and 2 seconds apart); any 2xx counts as success. Redirects aren't followed and the response body isn't read.
  • For old /r/ links it's called on every click.

Secret key

  • Campaign page → Promoters → Create key. It starts with tgs_ (47 characters) and is shown only once, right then.
  • Regenerate: the new key works immediately and the old one stops working at once. Be ready to swap the key on your server.
  • Keep the key on your server only (an environment variable). Never put it in your Mini App, client code or repository.
  • Listings without a key aren't visible to promoters.

Code samples

Node.js
// Node.js 18+ — no dependencies
import crypto from "node:crypto";

const TAGDS = "https://tagds.net";
const SECRET = process.env.TAGDS_SECRET; // tgs_… the secret key, shown once in the panel

// Call when a player completes a step.
// code: the start / start_param value; telegramId: the player's Telegram id
export async function reportStep(code, telegramId, step) {
  const body = JSON.stringify({ clickId: code, telegramId, adim: step, ts: Math.floor(Date.now() / 1000) });
  const signature = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
  const res = await fetch(TAGDS + "/api/donusum", {
    method: "POST",
    headers: { "content-type": "application/json", "X-Tagds-Imza": signature },
    body, // send exactly the bytes you signed
  });
  return { status: res.status, ...(await res.json()) };
}

// Try it from the command line
// TAGDS_SECRET=tgs_… node report.mjs <code> <telegramId>
const [code, telegramId] = process.argv.slice(2);
console.log(await reportStep(code, Number(telegramId), "baslatti"));
Python
# Python 3.8+ — no dependencies
import hashlib, hmac, json, os, time, urllib.error, urllib.request

TAGDS = "https://tagds.net"
SECRET = os.environ["TAGDS_SECRET"].encode()  # tgs_… the secret key, shown once in the panel

def report_step(code, telegram_id, step):
    """Call when a player completes a step; returns (HTTP status, response)."""
    # code: the start / start_param value; telegramId: the player's Telegram id
    body = json.dumps({"clickId": code, "telegramId": telegram_id, "adim": step, "ts": int(time.time())},
                      separators=(",", ":")).encode()
    signature = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    req = urllib.request.Request(TAGDS + "/api/donusum", data=body, method="POST",  # send exactly the bytes you signed
                                 headers={"content-type": "application/json", "X-Tagds-Imza": signature})
    try:
        with urllib.request.urlopen(req, timeout=10) as r:
            return r.status, json.load(r)
    except urllib.error.HTTPError as e:  # 4xx/5xx bodies are JSON too
        return e.code, json.load(e)

if __name__ == "__main__":  # Try it from the command line: TAGDS_SECRET=tgs_… python report.py <code> <telegramId>
    import sys
    print(report_step(sys.argv[1], int(sys.argv[2]), "baslatti"))
curl
# Bash + openssl: TAGDS_SECRET and CODE environment variables
BODY='{"clickId":"'"$CODE"'","telegramId":123456789,"adim":"yatirdi","ts":'"$(date +%s)"'}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$TAGDS_SECRET" | sed 's/^.* //')
curl -sS -X POST https://tagds.net/api/donusum \
  -H 'content-type: application/json' -H "X-Tagds-Imza: $SIG" -d "$BODY"

Testing tips

First check your signature against this test vector (no network needed); the body must match byte for byte:

Test vector
secret    tgs_test_ornek
body      {"clickId":"AbCdEfGhIjKlMnOpQrStUv","telegramId":123456789,"adim":"baslatti","ts":1760000000}
signature 2c2a9365e74cf323166299bc1a23c8068ff2f59e6321305eddf97903ba55168c

secret    tgs_test_ornek
text      AbCdEfGhIjKlMnOpQrStUv.1760000000
signature 533d7df9f5ee87262b060eabc61544165c6d4a5b445d4020b52772b4904e39de
  • Keep end-to-end tests free: add a tracking step with amount 0 (e.g. test); it's counted but doesn't touch your balance.
  • Send the same report twice: expect 200 with neden: tekrar.
  • Set ts 10 minutes back: 401 zaman. Change one character of the key: 401 imza. Made-up code: 404 tik_yok.
  • Mini App: open the verification link in Telegram; the panel should show Verified.

Publisher SDK (short)

To show ads in your Mini App (publisher side; separate from promotion tracking):

HTML
<script src="https://tagds.net/sdk/v1/tagds.js"></script>
<script type="module">
  // Rewarded or interstitial ad
  const ad = Tagds.init({ blockId: "blk_…" });
  const r = await ad.show(); // r = { done, state, error, description }
  if (r.done) giveReward();

  // Banner: drawn inside the element you pass
  await Tagds.banner({ blockId: "blk_…", el: "#banner" });
</script>
  • show() always resolves: done is true when a reward was earned (rewarded), the join was verified (task), or the ad was shown and closed (interstitial). state: load (no ad or request error), playing (closed early), destroy (finished), render (banner drawn).
  • Events: ad.addEventListener("onStart" | "onReward" | "onSkip" | "onError", f).
  • Identity comes from Telegram.WebApp.initData; your bot token never reaches us. If you use a CSP, add https://tagds.net to connect-src and img-src.
  • Your app's page in the panel gives you the block id (blk_…) and ready-made code, and shows when the connection works.

Next.js and TypeScript

The SDK is a plain script with no dependencies, so it works in any framework. In Next.js you load it once, add a small type file so TypeScript knows window.Tagds, and call it from client components.

  1. Load the scripts

    In the App Router, in app/layout.tsx. With the Pages Router, put the same two <Script> tags in pages/_app.tsx.

  2. Add the types

    Any .d.ts file your tsconfig.json includes (the default "**/*.ts" covers types/tagds.d.ts).

  3. Call it from client components

    Only in "use client" components, inside useEffect or a click handler: window.Tagds doesn't exist during server rendering.

app/layout.tsx
// app/layout.tsx — load the scripts once
import Script from "next/script";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Script src="https://telegram.org/js/telegram-web-app.js" strategy="beforeInteractive" />
        <Script src="https://tagds.net/sdk/v1/tagds.js" strategy="afterInteractive" />
        {children}
      </body>
    </html>
  );
}
types/tagds.d.ts
// types/tagds.d.ts — so TypeScript knows window.Tagds
type TagdsResult = { done: boolean; state: "load" | "playing" | "destroy" | "render"; error: boolean; description: string };
type TagdsEvent = "onStart" | "onReward" | "onSkip" | "onError";

interface TagdsController {
  show(): Promise<TagdsResult>;
  addEventListener(event: TagdsEvent, cb: (r: TagdsResult) => void): void;
  removeEventListener(event: TagdsEvent, cb: (r: TagdsResult) => void): void;
}

interface Window {
  Tagds?: {
    init(o: { blockId: string }): TagdsController;
    banner(o: { blockId: string; el: string | HTMLElement; onClose?: () => void }): Promise<TagdsResult>;
    basladi(): void;
    version: string;
  };
}
Banner
"use client";
// components/TagdsBanner.tsx — client only
import { useEffect, useRef } from "react";

export function TagdsBanner({ blockId }: { blockId: string }) {
  const ref = useRef<HTMLDivElement>(null);
  useEffect(() => {
    if (!ref.current || !window.Tagds) return;
    window.Tagds.banner({ blockId, el: ref.current });
  }, [blockId]);
  return <div ref={ref} />;
}
Rewarded / interstitial
"use client";
// components/WatchAdButton.tsx — rewarded or interstitial
export function WatchAdButton({ blockId }: { blockId: string }) {
  const onClick = async () => {
    if (!window.Tagds) return;
    const r = await window.Tagds.init({ blockId }).show();
    if (r.done) {
      // update the UI; the real reward comes from your reward URL (server to server)
    }
  };
  return <button onClick={onClick}>Watch ad</button>;
}
  • Give the real reward from your reward URL (Tagds calls it server to server when the ad is completed); r.done is for the UI.
  • Promotion tracking in a Next.js Mini App: add data-olcum to the same tag (<Script src="…/sdk/v1/tagds.js" data-olcum strategy="afterInteractive" />) and call window.Tagds?.basladi() when the player really starts playing.
Publishers

For publishers

Show ads in your Mini App, bot, Telegram channel or group, and earn from impressions and clicks. Standard share: 70%.

Adding a Mini App or bot

  1. Add your app

    publisher.tagds.net → Apps → Add app: the Mini App link (https://t.me/<bot>/<app>), the bot's username and numeric id (not the token). For rewarded and task ads, a reward URL (https, with the [userId] placeholder).
  2. Wait for review

    Your app is reviewed; once approved, it's ready to receive ads.

  3. Add a block, paste the code

    Pick a format (banner, rewarded, interstitial, task) and paste the code from the panel into your app; the panel shows when it's connected.

  • Block ad categories you don't want, and set how many rewarded or interstitial ads one person can see per hour.
  • Every ad always shows an "Ad" label and a close button.
  • Ads are shown only to real users verified by Telegram; counting happens on our servers.

Channels and groups

  1. Link Telegram

    Account menu → Link Telegram.

  2. Add your channel

    Channels → Add channel or group. The link is valid for 30 minutes; add the bot to your channel as an admin (allowed to post and delete messages). Whoever adds it must be an admin there.
  3. Confirm ownership

    The bot sends you a verification link in a private message; open it. Then the channel is reviewed.

  • 1, 2 or 3 ads a day; you choose the posting hours and how many hours later a post is deleted (or kept). There are at least 4 hours between two ads.
  • You earn for every real person who taps the button (CPC). Your own clicks and repeat clicks by the same person aren't paid.
  • Paid clicks per post are capped relative to the channel's member count; channels that exceed it are put under review.
  • If you remove the bot from the channel, posting stops.

Earnings and payouts

  • You receive a standard 70% of what advertisers spend in your app or channel (it can differ per app; you'll see your own rate in the panel).
  • Earnings settle at the end of each day and are held for 7 days before becoming withdrawable.
  • Once your withdrawable balance reaches $10, a payout request is queued by itself (no need to ask) and paid as USDT to your TON wallet. For now the Tagds team sends queued payouts in order; once automatic sending is switched on, they'll go out on their own. You can follow the status under Payouts; large amounts may go through a Tagds approval.
  • Payouts → your TON wallet address (48 characters starting with UQ… or EQ…). If you change a saved address, no new payout opens for 48 hours; the first address has no wait.
Usage guidelines

Usage guidelines

Not a legal document: a short summary of the rules the system actually enforces.

Content and review

  • Every campaign and listing is reviewed before it goes live, and again when its visible content changes.
  • Banned categories: gambling and adult content. Publishers can also block categories they don't want in their own apps.
  • Every ad carries an "Ad" label; interstitials always show a close button.
  • Channel-post and task ads can only link to t.me addresses.
  • A promotion listing must point to the advertiser's own bot or Mini App; for Mini Apps, ownership verification is required.

Fake traffic

  • Impressions, clicks and conversions are counted on our servers; Mini App impressions come with user data signed by Telegram.
  • In channel ads, the channel owner's own clicks and repeat clicks by the same person aren't paid.
  • In promotions, each Telegram account counts once per listing, first touch wins, and steps are reported by the advertiser's bot with a signature.
  • Bot accounts, second accounts, and clicking or starting things yourself are fake traffic.

Refunds and suspension

  • Money spent on traffic found to be fake during the holding period (7 days) is refunded to the advertiser.
  • A publisher's app or channel found to be fake is shut down, and its open payout is cancelled.
  • A promoter who brings fake traffic is suspended: no new shares, conversions aren't paid, and earnings still in the holding period are refunded.
  • Earnings that have passed the holding period and become withdrawable are not taken back.

Account and security

  • You sign in with email and password; linking Telegram is optional. One Telegram account can be linked to one Tagds account only.
  • A channel or group can belong to only one Tagds account.
  • Tagds never asks for your bot token — only the bot's numeric id.
  • Secret keys (tgs_…) stay on your server only; never share them.

Privacy and fraud prevention

  • To prevent fraud (multiple accounts, fake players, payout abuse) we record the IP address, browser information (user agent), device information and a device fingerprint at sign-up, sign-in, Telegram linking, payout address changes, shares and payout requests.
  • The fingerprint is a hash computed in the browser from screen, time zone, language, hardware and rendering properties; the raw values never leave the device. A random device ID is also stored in the browser.
  • In Mini Apps with the tracking snippet, each open records the player's Telegram ID, IP address and the same device information.
  • These records are kept for 180 days and then deleted. Only Tagds administrators see them, for fraud review; they are not sold and not used for ad targeting.

Last updated: · Back to top