샌드고 API 인증 — 액세스 키와 Bearer 토큰

샌드고 API 인증 — 액세스 키와 Bearer 토큰

accessKey/secretKey 로 토큰을 발급받아 Bearer 인증으로 호출하는 방법. v1 과 v2 의 차이, 토큰 캐싱, 401/403 처리까지.

POST /api/v2/token

샌드고 인증은 두 단계입니다. 키로 토큰을 받고, 토큰으로 발송한다.

거의 모든 경우 이 문서를 읽을 필요가 없습니다 — 공식 SDK 가 전부 대신 처리합니다. REST 를 직접 호출하거나, SDK 가 없는 언어에서 클라이언트를 만들 때만 필요합니다.

준비물

샌드고 콘솔 → 연동 관리 → 앱에서 발급받은 accessKeysecretKey.

export SENDGO_ACCESS_KEY=your_access_key
export SENDGO_SECRET_KEY=your_secret_key

두 값은 계정의 발송 권한 전체를 가집니다. 저장소에 커밋하지 마세요. 실수로 커밋했다면 콘솔에서 폐기 후 재발급해야 합니다 — 커밋을 되돌리는 것만으로는 노출이 사라지지 않습니다.

토큰 발급

accessKey:secretKey 를 Base64 로 인코딩해 Basic 인증 헤더로 보냅니다.

curl -X POST https://sendgo.io/api/v2/token \
  -H "Authorization: Basic $(printf '%s:%s' "$SENDGO_ACCESS_KEY" "$SENDGO_SECRET_KEY" | base64)"
{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

발급받은 토큰으로 호출

이후 모든 요청은 Bearer 인증을 씁니다. v1 과 v2 의 값이 다릅니다.

버전 헤더
v1 Authorization: Bearer base64(token)
v2 Authorization: Bearer token

v1 에서 토큰을 한 번 더 인코딩하지 않으면 401 이 돌아옵니다. 신규 연동은 v2 를 쓰세요.

curl -X POST https://sendgo.io/api/v2/notices/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "templateCode": "ORDER_CONFIRM_001",
    "scheduleType": "DIRECTLY",
    "kakaoSenderKey": "your_kakao_sender_key",
    "senderKey": "your_sms_sender_key",
    "contacts": [{ "contact": "01012345678", "var1": "ORD-001" }]
  }'

SDK 를 쓸 때

키만 넘기면 끝입니다. 토큰 발급, 캐싱, 만료 시 재발급, 401/403 재시도가 모두 안에서 처리됩니다.

import Sendgo from '@sendgo/node';

const sendgo = new Sendgo({
  accessKey:  process.env.SENDGO_ACCESS_KEY!,
  secretKey:  process.env.SENDGO_SECRET_KEY!,
  apiVersion: 'v2',
});
// 토큰 관련 코드는 없습니다. 첫 발송 때 알아서 받아옵니다.
from sendgo import Sendgo

client = Sendgo(
    access_key=os.environ["SENDGO_ACCESS_KEY"],
    secret_key=os.environ["SENDGO_SECRET_KEY"],
    api_version="v2",
)
<?php

$sendgo = new Sendgo\Php\Sendgo([
    'access_key'  => $_ENV['SENDGO_ACCESS_KEY'],
    'secret_key'  => $_ENV['SENDGO_SECRET_KEY'],
    'api_version' => 'v2',
]);
client, err := sendgo.New(sendgo.Config{
    AccessKey:  os.Getenv("SENDGO_ACCESS_KEY"),
    SecretKey:  os.Getenv("SENDGO_SECRET_KEY"),
    ApiVersion: "v2",
})

클라이언트는 한 번 만들어 재사용하세요. 요청마다 새로 만들면 캐시된 토큰이 버려지고 매번 토큰을 새로 발급받게 됩니다. Laravel·Spring·NestJS 확장은 싱글턴으로 등록하므로 이 문제가 없습니다.

인증 오류

코드 HTTP 원인
INVALID_ACCESS_KEY 401 액세스 키가 존재하지 않거나 시크릿이 틀림
ACCESS_KEY_NOT_APPROVED 403 앱이 아직 승인 대기 상태
IP_NOT_ALLOWED 403 앱에 설정한 허용 IP 밖에서 호출

IP_NOT_ALLOWED 는 로컬에서 개발할 때 자주 만납니다. 개발 환경에서는 허용 IP 를 비워 두거나 개발자 IP 를 추가하세요. 서버 IP 는 배포 후 실제 아웃바운드 IP 로 확인해야 합니다 — NAT 게이트웨이나 로드밸런서 뒤라면 인스턴스 IP 와 다릅니다.

다음 단계

자주 묻는 질문

v1 과 v2 의 인증은 무엇이 다른가요?
토큰 발급 방식은 같지만 Bearer 값이 다릅니다. v1 은 Authorization: Bearer base64(token) 으로 토큰을 한 번 더 Base64 인코딩해 보내고, v2 는 Authorization: Bearer token 으로 원본을 그대로 보냅니다. 신규 연동은 v2 를 쓰세요.
요청할 때마다 토큰을 새로 발급받아야 하나요?
아니요. 발급받은 토큰은 만료 전까지 재사용합니다. 공식 SDK 는 토큰을 캐시하고 만료 시 자동 재발급하며, 401/403 을 받으면 갱신 후 1회 재시도합니다. 직접 구현할 경우에도 매 요청 발급은 피하세요.
401 과 403 은 어떻게 다른가요?
401 은 인증 실패(INVALID_ACCESS_KEY 등)로 키 자체가 틀렸거나 토큰이 만료된 경우입니다. 403 은 인증은 됐지만 권한이 없는 경우로, ACCESS_KEY_NOT_APPROVED(앱 미승인)나 IP_NOT_ALLOWED(허용 IP 밖) 가 대표적입니다.

이 문서에서 쓰는 패키지

관련 문서