Short links in SMS and Alimtalk, with click tracking
Shorten long URLs to fit inside an SMS and measure who clicked. Creating short links, reading click stats, and splitting stats per campaign.
POST /api/v2/short-urlsPutting a long URL directly into a text message costs you twice: it eats your byte budget, and you learn nothing about who clicked.
[Event] Autumn sale! https://shop.example.com/promotions/autumn-2026?utm_source=sms&utm_campaign=autumn
→ blows past 90 bytes into LMS pricing, and engagement is invisible.
[Event] Autumn sale! https://sendgo.io/s/k7Rm2xQ
→ fits in an SMS, and clicks are counted.
Creating a short link
POST /api/v2/short-urls
| Field | Required | Notes |
|---|---|---|
targetUrl |
✅ | Original URL. http/https only, up to 2,048 characters |
title |
A label for the management screen | |
expiresAt |
After this, 410 Gone. Y-m-d H:i:s |
|
forceNew |
true issues a new code even for a URL already shortened |
Node.js / TypeScript
const created = await sendgo.shortUrl.create({
targetUrl: 'https://shop.example.com/promotions/autumn-2026',
title: 'Autumn sale landing',
expiresAt: '2026-09-30 23:59:59',
});
const { code, shortUrl } = created.data;
await sendgo.sms.sendSms({
content: `[Event] Autumn sale! ${shortUrl}`,
contacts: [{ contact: '01012345678' }],
});
Python
created = client.short_url.create(
target_url="https://shop.example.com/promotions/autumn-2026",
title="Autumn sale landing",
)
link = created["data"]["shortUrl"]
client.sms.send_sms(
content=f"[Event] Autumn sale! {link}",
contacts=[{"contact": "01012345678"}],
)
PHP
<?php
$short = $sendgo->shortUrl->create([
'targetUrl' => 'https://shop.example.com/promotions/autumn-2026',
'title' => 'Autumn sale landing',
]);
$link = $short['data']['shortUrl'];
$sendgo->sms->sendSms([
'content' => "[Event] Autumn sale! {$link}",
'contacts' => [['contact' => '01012345678']],
]);
Reading click statistics
const stats = await sendgo.shortUrl.stats(code, { from: '2026-09-01' });
await sendgo.shortUrl.list({ count: 10 }); // list
await sendgo.shortUrl.show(code); // detail
await sendgo.shortUrl.deactivate(code); // stop redirecting, keep the stats
stats = client.short_url.stats(code, from_="2026-09-01")
client.short_url.list(count=10)
client.short_url.show(code)
<?php
$stats = $sendgo->shortUrl->stats($code, ['from' => '2026-09-01']);
$sendgo->shortUrl->list(['count' => 10]);
$sendgo->shortUrl->show($code);
$sendgo->shortUrl->deactivate($code);
Separate statistics per campaign
If several campaigns point at the same landing page, use forceNew to get distinct codes. Otherwise the numbers merge and you cannot tell which campaign worked.
const augustLink = await sendgo.shortUrl.create({
targetUrl: 'https://shop.example.com/sale',
title: 'August sale - Alimtalk',
forceNew: true,
});
const septemberLink = await sendgo.shortUrl.create({
targetUrl: 'https://shop.example.com/sale', // same destination
title: 'September sale - SMS',
forceNew: true, // different code
});
Easy to get wrong
- Put the link in a template variable, not the Alimtalk template body. Hard-coding a URL in the template means re-review for every campaign. Pass the short link through
#{var3}instead. - Set an expiry. A live link to a finished event sends late clickers to a dead page.
- Do not put short links in your sitemap. For some links the unguessable code is the access control.
Next
자주 묻는 질문
- Why use a short link at all?
- Two reasons. An SMS is capped at 90 bytes, and one long URL can eat half of that. And a raw link tells you nothing about who clicked, whereas a short link records click statistics.
- Can I disable a short link later?
- Yes, deactivate stops the redirect while keeping the statistics, so past engagement data stays queryable. You can also set expiresAt up front, after which the link returns 410 Gone.
- Does requesting the same URL twice create a new code?
- By default it reuses the existing code. Pass forceNew to get a separate code when you want per-campaign statistics.