Send your first Kakao Alimtalk in 5 minutes

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.

POST /api/v2/notices/send

Getting the first Kakao Alimtalk out takes five steps. Only the last one is code — the other four are account setup you do once.

In a hurry? If steps 1–3 are already done, jump to step 5.

Step 1 — Issue your API keys

Sign in to the Sendgo console and create an app under Integration → Apps. You get an accessKey and a secretKey.

# .env
SENDGO_ACCESS_KEY=your_access_key
SENDGO_SECRET_KEY=your_secret_key
SENDGO_KAKAO_SENDER_KEY=your_kakao_sender_key
SENDGO_SMS_SENDER_KEY=your_sms_sender_key
SENDGO_API_VERSION=v2

These two values carry the full sending permission for the account. Keep them in the environment, never in the repository. If you have a fixed server IP, add an IP allowlist to the app — a leaked key is then useless from anywhere else.

Step 2 — Register a sending number and Kakao channel

In South Korea you may only send from a pre-registered number (전기통신사업법). This is the step that delays integrations, because it needs document review and teams usually start it after the code is finished.

  • SMS sending number — submit proof that the number belongs to you. Approval takes business days.
  • Kakao sender profile — connect a KakaoTalk channel to Sendgo and you get a kakaoSenderKey. The channel must already be converted to a business channel in Kakao Business.

Step 3 — Register and approve a template

An Alimtalk body is a template approved in advance. At send time you only fill in the blanks.

[#{var2}] Your order is confirmed.

Order number: #{var1}
Total: #{var3}

Register that, get a template code such as ORDER_CONFIRM_001, and you are ready.

Promotional wording is not approved as an Alimtalk template — informational only. For marketing, use Brand Message or an advertising SMS.

Step 4 — Install the SDK

Framework packages pull their core in, so do not install both.

composer require sendgo/laravel      # Laravel
composer require sendgo/php          # plain PHP
npm install @sendgo/node             # Node.js / TypeScript
pip install sendgo-python            # Python
go get github.com/send-go/go         # Go
gem install sendgo                   # Ruby
dotnet add package Sendgo.SDK        # .NET

Full list and selection guide: Choosing an SDK.

Step 5 — Send

Create the client once and reuse it. Put the sender keys on the client so you do not repeat them per call.

Node.js / TypeScript

import Sendgo from '@sendgo/node';

const sendgo = new Sendgo({
  accessKey:      process.env.SENDGO_ACCESS_KEY!,
  secretKey:      process.env.SENDGO_SECRET_KEY!,
  kakaoSenderKey: process.env.SENDGO_KAKAO_SENDER_KEY,
  smsSenderKey:   process.env.SENDGO_SMS_SENDER_KEY,
  apiVersion:     'v2',
});

await sendgo.alimtalk.send({
  templateCode: 'ORDER_CONFIRM_001',
  contacts: [
    { contact: '01012345678', name: 'Hong Gildong', var1: 'ORD-001', var3: '29,000원' },
  ],
});

@sendgo/node is a default export. import { Sendgo } from '@sendgo/node' does not work.

Python

import os
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",
)

client.alimtalk.send(
    template_code="ORDER_CONFIRM_001",
    contacts=[{"contact": "01012345678", "name": "Hong Gildong", "var1": "ORD-001"}],
)

PHP

<?php

use Sendgo\Php\Sendgo;

$sendgo = new Sendgo([
    'access_key'       => $_ENV['SENDGO_ACCESS_KEY'],
    'secret_key'       => $_ENV['SENDGO_SECRET_KEY'],
    'kakao_sender_key' => $_ENV['SENDGO_KAKAO_SENDER_KEY'],
    'sms_sender_key'   => $_ENV['SENDGO_SMS_SENDER_KEY'],
    'api_version'      => 'v2',
]);

$sendgo->alimtalk->send([
    'templateCode' => 'ORDER_CONFIRM_001',
    'contacts'     => [
        ['contact' => '01012345678', 'name' => 'Hong Gildong', 'var1' => 'ORD-001'],
    ],
]);

Laravel

sendgo/laravel auto-registers its ServiceProvider, so inject the client directly.

<?php

use Sendgo\Php\Sendgo;

class OrderController extends Controller
{
    public function __construct(private Sendgo $sendgo) {}

    public function confirm(Order $order)
    {
        $this->sendgo->alimtalk->send([
            'templateCode' => 'ORDER_CONFIRM_001',
            'contacts'     => [[
                'contact' => $order->user->phone,
                'name'    => $order->user->name,
                'var1'    => $order->number,
            ]],
        ]);

        return response()->json(['success' => true]);
    }
}

Push this onto a queue in production — an external API call inside the request cycle makes your own response time depend on Kakao's.

Java

import io.sendgo.*;
import io.sendgo.model.*;
import java.util.List;

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());

sendgo.alimtalk().send(AlimtalkRequest.builder()
    .templateCode("ORDER_CONFIRM_001")
    .contacts(List.of(
        Contact.builder().contact("01012345678").name("Hong Gildong").var1("ORD-001").build()
    ))
    .build());

Go

client, err := sendgo.New(sendgo.Config{
    AccessKey:      os.Getenv("SENDGO_ACCESS_KEY"),
    SecretKey:      os.Getenv("SENDGO_SECRET_KEY"),
    KakaoSenderKey: os.Getenv("SENDGO_KAKAO_SENDER_KEY"),
    SmsSenderKey:   os.Getenv("SENDGO_SMS_SENDER_KEY"),
    ApiVersion:     "v2",
})
if err != nil {
    log.Fatal(err)
}

_, err = client.Alimtalk.Send(sendgo.AlimtalkRequest{
    TemplateCode: "ORDER_CONFIRM_001",
    Contacts: []sendgo.Contact{
        {Contact: "01012345678", Name: "Hong Gildong", Var1: "ORD-001"},
    },
})

If the first send failed

Code Meaning Fix
INVALID_ACCESS_KEY Wrong key Check the environment variables are actually loaded
ACCESS_KEY_NOT_APPROVED App not approved yet Check the app status in the console
IP_NOT_ALLOWED Called from outside the allowlist Add your server's outbound IP
INVALID_TEMPLATE_CODE Unknown or unapproved template Compare against the console; it must be approved, not pending
INVALID_KAKAO_SENDER_KEY Wrong sender profile key Recheck the key in the console
EMPTY_CONTACTS Recipient array is empty Make sure contacts is actually populated
PAYMENT_REQUIRED Out of credit Top up; retrying will not help

Full list: Error codes and retry strategy.

Next

자주 묻는 질문

Do I really have to register a template before sending an Alimtalk?
Yes. Alimtalk only delivers to templates that passed Kakao's review. You cannot compose the body at send time; you fill the variables (var1 to var8) of an approved template. If you need free-form text, use Brand Message or SMS/LMS instead.
Can I test without registering a sending number?
No. Korean telecommunications law requires the caller ID to be pre-registered, and an unregistered number fails at send time rather than at signup. Start the registration before you write any code — it is the longest lead time in the whole integration.
Do I need to manage the auth token myself?
No. Every official SDK issues the token, caches it, refreshes it on expiry and retries once on 401/403. Writing your own token loop means fetching a new token on every request.
What is the base URL?
https://sendgo.io/api, with a version segment of v1 or v2. Use v2 for new code. The SDKs default to the correct host, so you normally do not set it.

이 문서에서 쓰는 패키지

관련 문서