Documentation menu
Java / SDK REFERENCE
Java SDK Guide
The pure-Java SDK for sending Kakao Alimtalk, Brand Message and SMS — built on java.net.http, no framework required.
이 문서의 목차
- 패키지
- io.sendgo:sendgo-java
- 언어
- Java
- 레지스트리
- Maven Central
implementation "io.sendgo:sendgo-java:1.1.0"The pure-Java SDK for sending Kakao Alimtalk, Brand Message and SMS
io.sendgo:sendgo-java is the framework-agnostic Java SDK for the Sendgo messaging API.
It builds on java.net.http.HttpClient and Jackson — no Spring required.
Requires Java 17 or newer.
Install
Gradle
implementation "io.sendgo:sendgo-java:1.1.0"
Maven
<dependency>
<groupId>io.sendgo</groupId>
<artifactId>sendgo-java</artifactId>
<version>1.1.0</version>
</dependency>
Quick start
import io.sendgo.SendgoClient;
import io.sendgo.SendgoConfig;
import io.sendgo.model.AlimtalkRequest;
import io.sendgo.model.Contact;
SendgoClient sendgo = new SendgoClient(SendgoConfig.builder()
.accessKey(System.getenv("SENDGO_ACCESS_KEY"))
.secretKey(System.getenv("SENDGO_SECRET_KEY"))
.kakaoSenderKey(System.getenv("SENDGO_KAKAO_SENDER_KEY"))
.smsSenderKey(System.getenv("SENDGO_SMS_SENDER_KEY"))
.apiVersion("v2")
.build());
// Send an Alimtalk
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("ORDER_CONFIRM_001")
.contact(Contact.builder()
.contact("01012345678")
.name("Gildong Hong")
.var1("ORD-001")
.build())
.build());
Each channel is a method on the client: alimtalk(), friendtalk(), brandMessage(), sms().
Tokens are issued and refreshed inside the SDK.
Alimtalk in detail
import java.util.List;
// Multiple recipients
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("ORDER_CONFIRM_001")
.contacts(List.of(
Contact.builder().contact("01011111111").name("Gildong Hong").var1("ORD-001").build(),
Contact.builder().contact("01022222222").name("Chulsoo Kim").var1("ORD-002").build()))
.build());
// Scheduled send
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("PROMO_SUMMER_2026")
.scheduleType("SCHEDULED")
.at("2026-07-28 09:00:00")
.contact(Contact.builder().contact("01012345678").var1("Summer sale").build())
.build());
For named template variables beyond var1–var8, Contact accepts an arbitrary map:
Contact.builder()
.contact("01012345678")
.variable("title", "Order confirmed")
.variable("date", "2026-08-10")
.build();
Contact serialises those through Jackson's @JsonAnyGetter, so named and numbered variables can be mixed in one request.
Friendtalk
⚠️ 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.
import io.sendgo.model.FriendtalkRequest;
sendgo.friendtalk().send(FriendtalkRequest.builder()
.messageType("FI")
.content("This week's featured products.")
.imageUrl("https://cdn.example.com/banner.jpg")
.imageLink("https://example.com/event")
.contact(Contact.builder().contact("01012345678").build())
.build());
Brand Message
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 reach recipients who are not channel friends (targeting("N")) and broadcast to every consenting channel friend (targeting("F")).
v2 only. Set
.apiVersion("v2").
import io.sendgo.model.BrandMessageRequest;
// Single send — channel friends
sendgo.brandMessage().send(BrandMessageRequest.builder()
.targeting("M")
.messageType("FL")
.friendTemplateUuid("9cd5460b-6458-4edc-9b11-c26d3013c340")
.contact(Contact.builder().contact("01012345678").var1("29,000 KRW").build())
.build());
// Broadcast — every consenting channel friend (contacts is dropped)
sendgo.brandMessage().broadcast(BrandMessageRequest.builder()
.messageType("FW")
.friendTemplateUuid("9cd5460b-6458-4edc-9b11-c26d3013c340")
.build());
// Campaign lookups. Pass nulls to fall back to the server defaults.
var list = sendgo.brandMessage().campaigns(null, null, 10);
var one = sendgo.brandMessage().campaign("1f0a6d0e-6b3b-4f0f-9b2f-2f6f6a1b7c11");
campaigns() also has a no-argument overload that uses every server default.
broadcast() rebuilds the request with targeting("F") and no contacts — an empty recipient array would be rejected as an invalid request.
SMS / LMS / MMS
import io.sendgo.model.SmsRequest;
// SMS (up to 90 bytes)
sendgo.sms().sendSms(SmsRequest.sms()
.content("[Sendgo] Your code is 123456 (valid for 5 minutes)")
.contact(Contact.builder().contact("01012345678").build()));
// LMS (long text, up to 2,000 bytes)
sendgo.sms().sendLms(SmsRequest.lms()
.subject("[Important] Scheduled maintenance")
.content("Maintenance: 2026-07-25 02:00-06:00")
.contact(Contact.builder().contact("01012345678").build()));
// MMS
sendgo.sms().sendMms(SmsRequest.mms()
.subject("[Event] July deals")
.content("Check out this month's deals!")
.contact(Contact.builder().contact("01012345678").build()));
SmsRequest does not use builder()/build() like the other request types — it is created with the
sms() / lms() / mms() static factories and configured with fluent setters that return the request itself.
sendSms / sendLms / sendMms also force the message type, so the factory and the send method cannot
disagree; send(...) uses whatever type the request carries.
Spring Boot
Use io.sendgo:sendgo-spring, which auto-configures a SendgoClient bean once sendgo.access-key is set:
sendgo:
access-key: ${SENDGO_ACCESS_KEY}
secret-key: ${SENDGO_SECRET_KEY}
kakao-sender-key: ${SENDGO_KAKAO_SENDER_KEY}
api-version: v2
@Service
public class OrderNotifier {
private final SendgoClient sendgo;
public OrderNotifier(SendgoClient sendgo) {
this.sendgo = sendgo;
}
public void confirmed(String phone, String orderNo) {
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("ORDER_CONFIRM_001")
.contact(Contact.builder().contact(phone).var1(orderNo).build())
.build());
}
}
The bean is @ConditionalOnMissingBean, so defining your own SendgoClient overrides it.
Error handling
import io.sendgo.exception.SendgoException;
try {
sendgo.alimtalk().send(request);
} catch (SendgoException e) {
switch (e.getErrorCode()) {
case "INVALID_ACCESS_KEY", "INVALID_SECRET_KEY" ->
log.error("Check the Sendgo API keys");
case "PAYMENT_REQUIRED" ->
log.error("Out of Sendgo credit");
case "IP_NOT_ALLOWED" ->
log.error("IP is not allow-listed");
case "INVALID_TEMPLATE_CODE" ->
log.warn("Unknown template");
default -> {
if (e.getStatusCode() >= 500) {
retryLater(request); // transient
} else {
log.error("Sendgo {}: {}", e.getStatusCode(), e.getMessage());
}
}
}
}
Branch on getErrorCode(), 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.
SendgoException is a RuntimeException, so it does not force try/catch on every call site — handle it where you have a recovery strategy.
Configuration options
| Builder method | Type | Required | Default | Description |
|---|---|---|---|---|
accessKey |
String |
required | — | Sendgo access key |
secretKey |
String |
required | — | Sendgo secret key |
kakaoSenderKey |
String |
optional | null |
Kakao sender profile key |
smsSenderKey |
String |
optional | null |
SMS caller ID key |
apiVersion |
String |
optional | "v2" |
API version (v1 | v2) |
baseUrl |
String |
optional | "https://sendgo.io" |
API base URL |
Short 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.
import io.sendgo.model.ShortUrlRequest;
Map<String, Object> created = sendgo.shortUrl().create(ShortUrlRequest.builder()
.targetUrl("https://example.com/promotions/summer-sale")
.title("Summer sale landing")
.build());
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) created.get("data");
String code = (String) data.get("code");
// Reaction stats — daily series + device / referrer / country breakdowns
Map<String, Object> stats = sendgo.shortUrl().stats(code, "2026-08-01", null);
sendgo.shortUrl().list(null, null, 10);
sendgo.shortUrl().show(code);
sendgo.shortUrl().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.
Package information
- Package:
io.sendgo:sendgo-java(Maven Central) - Repository: send-go/java
- Registry: https://central.sonatype.com/artifact/io.sendgo/sendgo-java
- License: MIT
Getting your API keys
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 kakaoSenderKey, and a caller ID under Sender numbers for SMS.
이 패키지로 할 수 있는 것
Send your first Kakao Alimtalk in 5 minutes →
From issuing an access key to sending a Kakao Alimtalk, with working code in Node.js, Python, PHP, Laravel, Java and Go.
Send a Kakao Alimtalk — PHP, Node.js, Python, Java, Go examples →
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 SMS, LMS and MMS in South Korea — code examples →
Send Korean SMS (90 bytes), LMS (long text) and MMS (with images) through Sendgo. Type selection, byte counting, verification-code patterns and advertising rules.