기업회원 신청 서류 안내
신청자 구분에 따라 재직증명서 또는 위임장을 함께 제출해 주세요.
신청자 구분에 따라 재직증명서 또는 위임장을 함께 제출해 주세요.
Python / SDK REFERENCE
The Python SDK for sending Kakao Alimtalk, Brand Message and SMS — works standalone or with Django and FastAPI.
pip install sendgo-pythonThe Python SDK for sending Kakao Alimtalk, Brand Message and SMS
sendgo-python is the official Python SDK for the Sendgo messaging API.
It works on its own and is the core behind the sendgo-django and sendgo-fastapi extensions.
Requires Python 3.10 or newer.
pip install sendgo-python
from sendgo import Sendgo
client = Sendgo(
access_key=os.environ["SENDGO_ACCESS_KEY"],
secret_key=os.environ["SENDGO_SECRET_KEY"],
kakao_sender_key=os.environ.get("SENDGO_KAKAO_SENDER_KEY"),
sms_sender_key=os.environ.get("SENDGO_SMS_SENDER_KEY"),
api_version="v2",
)
# Send an Alimtalk
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[
{"contact": "01012345678", "name": "Gildong Hong", "var1": "ORD-001", "var2": "29,000 KRW"},
],
)
# Send an SMS
client.sms.send_sms(
content="[Sendgo] Your code is 123456 (valid for 5 minutes)",
contacts=[{"contact": "01012345678"}],
)
All methods take keyword arguments only, so call sites stay readable as payloads grow. Tokens are issued and refreshed for you.
# Multiple recipients
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[
{"contact": "01011111111", "name": "Gildong Hong", "var1": "ORD-001", "var2": "29,000 KRW"},
{"contact": "01022222222", "name": "Chulsoo Kim", "var1": "ORD-002", "var2": "15,000 KRW"},
],
)
# Scheduled send
client.alimtalk.send(
template_code="PROMO_SUMMER_2026",
schedule_type="SCHEDULED",
at="2026-07-28 09:00:00",
contacts=[{"contact": "01012345678", "var1": "Summer sale — 50% off"}],
)
# Fall back to SMS when the Alimtalk fails
client.alimtalk.send(
template_code="DELIVERY_START_001",
replace_sms="Y",
sms_subject="[Shipping notice]",
sms_content="Your order has shipped.\nTracking: #{var2}",
contacts=[{"contact": "01012345678", "var1": "ORD-001", "var2": "1234567890"}],
)
⚠️ Deprecated — Friendtalk was discontinued on 2025-12-31 under Kakao's policy. Since 2026-01-01, Friendtalk send requests are automatically delivered as Brand Message (free-form) by Kakao. Calls still succeed, and this is still the only path for free-form types (
FT/FI/FW) sent to individual recipients, so there is no need to change working code right now.Use Brand Message instead for:
- template-based rich types (
FL/FC/FM/FP/FA)- recipients who are not channel friends (
targeting=N/I)- broadcasts to every opted-in channel friend (
targeting=F)Message types map one-to-one and the server does the conversion —
FT→BT,FI→BI,FW→BW,FL→BL,FC→BC,FM→BM,FP→BP,FA→BA.
# Text
client.friendtalk.send(
content="Hello! Check out this month's deals.",
contacts=[{"contact": "01012345678"}],
)
# Image
client.friendtalk.send(
message_type="FI",
content="This week's featured products.",
image_url="https://cdn.example.com/banner.jpg",
image_link="https://example.com/event",
contacts=[{"contact": "01012345678"}],
)
# With buttons
client.friendtalk.send(
content="Your coupon has arrived. Use it now!",
buttons=[{"name": "Get coupon", "type": "WL", "linkMo": "https://example.com/coupon"}],
contacts=[{"contact": "01012345678"}],
)
Brand Message is the successor channel to Friendtalk. Message types map one-to-one
(FT→BT, FI→BI, FW→BW, FL→BL, FC→BC, FM→BM, FP→BP, FA→BA);
pass the Friendtalk code and the server converts it.
Unlike Friendtalk it can also:
targeting="N")targeting="F", no recipient list needed)v2 only. For plain text or images (
FT/FI/FW) to channel friends, the Friendtalk API is simpler.
# Single send — channel friends
client.brand_message.send(
targeting="M",
message_type="FL",
friend_template_uuid="9cd5460b-6458-4edc-9b11-c26d3013c340",
contacts=[{"contact": "01012345678", "var1": "29,000 KRW"}],
)
# Broadcast — every consenting channel friend (no contacts)
client.brand_message.broadcast(
message_type="FW",
friend_template_uuid="9cd5460b-6458-4edc-9b11-c26d3013c340",
)
# Campaign lookups. `from` is a Python keyword, so the argument is `from_`.
campaigns = client.brand_message.campaigns(from_="2026-08-01", count=10)
one = client.brand_message.campaign("1f0a6d0e-6b3b-4f0f-9b2f-2f6f6a1b7c11")
Two argument names avoid Python keyword collisions: from_ (for from) and list_ (for the carousel list payload). Both are sent under their original API names.
# SMS (up to 90 bytes)
client.sms.send_sms(
content="[Sendgo] Your code is 123456 (valid for 5 minutes)",
contacts=[{"contact": "01012345678"}],
)
# LMS (long text, up to 2,000 bytes)
client.sms.send_lms(
subject="[Important] Scheduled maintenance",
content="Maintenance is scheduled.\n\n■ When: 2026-07-25 02:00–06:00\n■ Impact: all services",
contacts=[{"contact": "01012345678"}],
)
# MMS (with an image)
client.sms.send_mms(
subject="[Event] July deals",
content="Check out this month's deals!",
contacts=[{"contact": "01012345678"}],
)
# Scheduled SMS
client.sms.send_sms(
content="[Reminder] Please confirm your appointment.",
schedule_type="SCHEDULED",
at="2026-07-23 08:00:00",
contacts=[{"contact": "01012345678"}],
)
Use sendgo-django, which reads a SENDGO settings dict and gives you a lazily built client:
# settings.py
SENDGO = {
"ACCESS_KEY": os.environ["SENDGO_ACCESS_KEY"],
"SECRET_KEY": os.environ["SENDGO_SECRET_KEY"],
"KAKAO_SENDER_KEY": os.environ.get("SENDGO_KAKAO_SENDER_KEY"),
"API_VERSION": "v2",
}
from sendgo_django import client
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[{"contact": order.phone, "var1": order.number}],
)
Use sendgo-fastapi, which exposes the client as a dependency:
from fastapi import Depends, FastAPI
from sendgo_fastapi import SendgoDep
app = FastAPI()
@app.post("/notify")
async def notify(phone: str, order_no: str, sendgo = Depends(SendgoDep)):
return sendgo.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[{"contact": phone, "var1": order_no}],
)
Sending is a network call, so it belongs in a task rather than a request cycle:
from celery import shared_task
from sendgo import Sendgo, SendgoError
@shared_task(bind=True, max_retries=3)
def send_order_confirm(self, phone: str, order_no: str):
try:
Sendgo(...).alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[{"contact": phone, "var1": order_no}],
)
except SendgoError as exc:
# 5xx is transient; 4xx will not succeed on retry.
if exc.status_code >= 500:
raise self.retry(exc=exc, countdown=2 ** self.request.retries)
raise
from sendgo import SendgoError
try:
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[{"contact": "01012345678"}],
)
except SendgoError as e:
if e.error_code in ("INVALID_ACCESS_KEY", "INVALID_SECRET_KEY"):
notify_ops("Check the Sendgo API keys.")
elif e.error_code == "PAYMENT_REQUIRED":
notify_ops("Out of Sendgo credit.")
elif e.error_code == "IP_NOT_ALLOWED":
notify_ops("IP is not allow-listed.")
elif e.status_code >= 500:
retry_later() # retryable
else:
logger.error("Sendgo error %s: %s", e.status_code, e)
Branch on error_code, not on the message text — messages can change, codes are the contract.
TOKEN_EXPIRED and TOKEN_MISMATCH are handled inside the SDK: the token is reissued and the request retried once.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
access_key |
str |
required | — | Sendgo access key |
secret_key |
str |
required | — | Sendgo secret key |
kakao_sender_key |
str | None |
optional | None |
Kakao sender profile key |
sms_sender_key |
str | None |
optional | None |
SMS caller ID key |
api_version |
str |
optional | "v1" |
API version (v1 | v2) |
base_url |
str |
optional | "https://sendgo.io" |
API base URL |
Short URLs shrink the links in your message body and count whether they were actually clicked. SMS is billed by byte, so a shorter link leaves more room for copy.
v2 only.
Shortening the same target URL again returns the existing link. Pass forceNew
to mint a new code when you want per-campaign reaction figures kept separate.
deactivate does not delete the link — it only stops the redirect. Use it when a link
in an already-sent message has to be killed; the accumulated stats stay, and visitors
to a stopped link get 410 Gone.
created = sendgo.short_url.create(
target_url="https://example.com/promotions/summer-sale",
title="Summer sale landing",
)
code = created["data"]["code"]
link = created["data"]["shortUrl"]
# Reaction stats — daily series + device / referrer / country breakdowns
stats = sendgo.short_url.stats(code, from_="2026-08-01")
sendgo.short_url.list(count=10)
sendgo.short_url.show(code)
sendgo.short_url.deactivate(code) # Stops the redirect only; the stats stay
stats returns a daily series (daily) plus breakdowns by device (byDevice), referrer (byReferer) and country (byCountry). The daily series is read from a pre-aggregated table, so response time stays flat no matter how many clicks accumulate.
sendgo-python (PyPI)Sign in to Sendgo and open API/SDK → API integration to issue an access key and secret key.
Register a Kakao sender profile under Kakao channel to get your kakao_sender_key, and a caller ID under Sender numbers for SMS.
From issuing an access key to sending a Kakao Alimtalk, with working code in Node.js, Python, PHP, Laravel, Java and Go.
Pick the organisation, issue API keys, register sender numbers and templates from a coding agent. Everything except topping up credit works without the console.
Exchange an accessKey and secretKey for a bearer token, and call the Sendgo API with it. Differences between v1 and v2, token caching, and the 401/403 codes.
Send Kakao Alimtalk with an approved template code. Runnable code for Laravel, Node.js, Python, PHP, Java, Go, Ruby and .NET, plus every required field and why sends fail.
Send Korean SMS (90 bytes), LMS (long text) and MMS (with images) through Sendgo. Type selection, byte counting, verification-code patterns and advertising rules.
Send Brand Messages to channel friends, non-friends, or every consenting friend at once. How targeting splits the request path, and when to keep using the Friendtalk endpoint.
Use replaceSms so a text message goes out when the Alimtalk cannot be delivered. Required fields, cost implications, and the mistake that silently sends nothing.
Send one template to many recipients with different values each, in batches. Batch sizing, partial failures, queue patterns and the data hygiene that prevents most incidents.
Send at a specific time with scheduleType SCHEDULED. Timestamp format, the KST timezone trap, and how scheduling interacts with the advertising night ban.
Register Kakao channels, submit Alimtalk templates for review, file sender numbers, and sync opt-outs without ever sending anyone to sendgo.io. Includes webhook delivery of review outcomes.
Every error code returned by the Sendgo send endpoints, and how to tell a failure worth retrying from one that will fail identically every time.
Shorten long URLs to fit inside an SMS and measure who clicked. Creating short links, reading click stats, and splitting stats per campaign.
The official Django extension for sending Kakao Alimtalk, Brand Message and SMS — configured from settings, with a lazily built client.
pip install sendgo-djangoThe official FastAPI extension for sending Kakao Alimtalk, Brand Message and SMS — injected as a dependency, configured from environment variables.
pip install sendgo-fastapi