> **The machine-readable contract for the Sendgo API**

If your language has no official Sendgo SDK — or you want to generate your own client — start from the OpenAPI 3.0.3 spec.

- Always current: [`https://sendgo.io/openapi.yaml`](https://sendgo.io/openapi.yaml)
- Source: [send-go/openapi](https://github.com/send-go/openapi)
- Server: `https://api.sendgo.io/api`

---

## Endpoints

| Channel | Method | Path |
|---------|--------|------|
| Issue token | `POST` | `/{version}/token` |
| Kakao Alimtalk | `POST` | `/{version}/notices/send` |
| Kakao Friendtalk — **Deprecated** | `POST` | `/{version}/friends/send` |
| Brand Message — send | `POST` | `/{version}/brand-messages/send` |
| Brand Message — list campaigns | `GET` | `/{version}/brand-messages` |
| Brand Message — campaign detail | `GET` | `/{version}/brand-messages/{campaign_id}` |
| SMS / LMS / MMS | `POST` | `/{version}/messages/send` |
| Short URL — create | `POST` | `/{version}/short-urls` |
| Short URL — list | `GET` | `/{version}/short-urls` |
| Short URL — detail | `GET` | `/{version}/short-urls/{code}` |
| Short URL — reaction stats | `GET` | `/{version}/short-urls/{code}/stats` |
| Short URL — stop redirecting | `DELETE` | `/{version}/short-urls/{code}` |

`{version}` is `v1` or `v2`. **Brand Message is v2 only.**

**Friendtalk was discontinued on 2025-12-31 under Kakao's policy.** Since 2026-01-01 requests to `/{version}/friends/send` are delivered as **Brand Message (free-form)** automatically — the call still succeeds, but what goes out is a Brand Message. The endpoint is not being removed: it is still the only path for free-form types (`FT`/`FI`/`FW`) to individual recipients, and `/{version}/brand-messages/send` returns `NOT_A_BRAND_MESSAGE` for that combination. Use Brand Message for template-based rich types (`FL`/`FC`/`FM`/`FP`/`FA`), non-friend targeting (`N`/`I`) and broadcasts (`F`).

---

## Authentication

Two steps.

**1. Issue a token** with Basic auth over `accessKey:secretKey`:

```bash
curl -X POST https://api.sendgo.io/api/v2/token \
  -H "Authorization: Basic $(printf '%s:%s' "$ACCESS_KEY" "$SECRET_KEY" | base64)"
```

**2. Call the API** with that token as a Bearer credential:

| Version | Header |
|---------|--------|
| v1 | `Authorization: Bearer base64(token)` |
| v2 | `Authorization: Bearer token` |

v1 expects the token **Base64-encoded a second time**; v2 sends it verbatim. Getting this backwards is the usual cause of a `401` on a token you just issued.

Tokens are valid for **24 hours**. Read `expiresAt` (v2) / `expires_at` (v1) from the issue response, cache the token, and reissue only when it is about to lapse — issuing one per request is wasted latency on every single call.

Requests are also checked against the IP allow-list configured for the application, so a token alone is not enough from an unregistered address (`IP_NOT_ALLOWED`).

---

## Send an Alimtalk

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

---

## Send a Brand Message

```bash
# Targeted — targeting M/N/I requires `contacts`
curl -X POST https://api.sendgo.io/api/v2/brand-messages/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "targeting": "M",
    "messageType": "FL",
    "friendTemplateUuid": "9cd5460b-6458-4edc-9b11-c26d3013c340",
    "contacts": [{ "contact": "01012345678", "var1": "29,000 KRW" }]
  }'

# Broadcast — every consenting channel friend, no recipient list
curl -X POST https://api.sendgo.io/api/v2/brand-messages/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "targeting": "F",
    "messageType": "FW",
    "friendTemplateUuid": "9cd5460b-6458-4edc-9b11-c26d3013c340"
  }'
```

A broadcast is processed asynchronously upstream, so the send response only acknowledges acceptance. Poll the campaign for progress:

```bash
curl "https://api.sendgo.io/api/v2/brand-messages/$CAMPAIGN_ID" \
  -H "Authorization: Bearer $TOKEN"
```

`GET /{version}/brand-messages` returns Brand Message campaigns only (`BRAND_GROUP`, `BRAND_BASIC`) — use `/{version}/friends` for Friendtalk campaigns.

---

## Response envelope

Success:

```json
{
  "traceId": "01J2X8N4YV5T3Q9M0K7B6C5D4E",
  "message": "Success",
  "data": { }
}
```

Failure:

```json
{
  "traceId": "01J2X8N4YV5T3Q9M0K7B6C5D4E",
  "code": "INVALID_TEMPLATE_CODE",
  "message": "The template code does not exist.",
  "errors": { },
  "timestamp": "2026-08-10 04:31:22"
}
```

Both shapes are **flat** — the error fields are not nested under `data` or `error`. Branch on `code`, not on `message`: messages are prose and may be reworded, codes are the contract. Include `traceId` when you contact support; it identifies the exact request in our logs.

`timestamp` is server-local (`Y-m-d H:i:s`, Asia/Seoul) with no offset — parse it as KST rather than as UTC or ISO 8601.

---

## Generate a client

```bash
# TypeScript
npx @openapitools/openapi-generator-cli generate \
  -i https://sendgo.io/openapi.yaml -g typescript-fetch -o ./sendgo-client

# Python
openapi-generator-cli generate \
  -i https://sendgo.io/openapi.yaml -g python -o ./sendgo-client

# Go
openapi-generator-cli generate \
  -i https://sendgo.io/openapi.yaml -g go -o ./sendgo-client
```

**Prefer the official SDK where one exists.** A generated client gives you typed request bodies, but nothing else: the SDKs cache the token, reissue it transparently on `TOKEN_EXPIRED` / `TOKEN_MISMATCH`, and retry that one request — logic you would otherwise write yourself in every service. See the [SDK index](/en/sdk) for the 20 supported languages and frameworks.

---

## Explore and validate

Paste `openapi.yaml` into [Swagger Editor](https://editor.swagger.io) to browse the endpoints and schemas visually.

```bash
npx @redocly/cli lint openapi.yaml
```

---

## For AI coding tools

The spec is one of several machine-readable entry points:

| URL | Contents |
|-----|----------|
| `/openapi.yaml` | This specification |
| `/llms.txt` | Index of every guide, in the [llmstxt.org](https://llmstxt.org) format |
| `/llms-full.txt` | Every guide concatenated as plain text |
| `/{lang}/sdk/{slug}.md` | The raw markdown of any SDK guide |

---

## Package information

- **Package**: `send-go/openapi` (GitHub)
- **Repository**: [send-go/openapi](https://github.com/send-go/openapi)
- **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** for Alimtalk and Brand Message, and a caller ID under **Sender numbers** for SMS.