Skip to main content

Outbound API

These APIs let a human agent or AI send messages to a customer, and end or block a consultation. All of them require the BrandWrite scope.

Common:

  • Base URL: https://api.talkbridge.io
  • Headers: Authorization: Bearer blumnb-..., Content-Type: application/json
  • brandKey: the Brand Key of the target brand — shown in the "Integration keys" card in Developer mode of TalkBridge Center, or in brands from GET /api/agent/me (details in channels[].key)
  • Response envelope: { "ok": boolean, "code": string, "message": string } — see Error Codes for the full list

Send text​

POST /api/agent/send
FieldTypeRequiredDescription
brandKeystring✅Brand (channel) key
userKeystring✅Target customer key
textstring✅Text to send
curl -X POST https://api.talkbridge.io/api/agent/send \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d '{ "brandKey": "mybrand", "userKey": "Ab3d_x9Kq2Lm", "text": "Hello" }'
{ "ok": true, "code": "0", "message": null, "serial": "bw-1757400000000-a1b2" }

serial is the serial number of this send — the same value is used in Cancel a send (delete) and in the agent echo on your inbound webhook.

If Kakao does not accept the message, the response is HTTP 200 with ok: false. code is Kakao's result code as-is — for example, replying to a chat whose consultation session has ended returns -502.

{ "ok": false, "code": "-502", "message": "이미 종료된 상담이라 전송되지 않았어요. 고객이 다시 메시지를 보내면 새 상담으로 이어져요.", "serial": "bw-1757400000000-a1b2" }

See send failure codes for each code's meaning and whether to retry. Rich and attachment sends use the same codes.


Send rich message​

Sends Kakao rich message bubbles such as buttons, lists, and image cards.

POST /api/agent/send/rich
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key
richstring✅The rich envelope JSON below, passed as a string
note

rich is a JSON object serialized to a string. Invalid JSON is rejected with 400 BAD_RICH.

Rich envelope schema​

user_key, sender_key, and serial_number are filled in by the server — do not put them in the envelope.

FieldRequiredDescription
chat_bubble_type✅TEXT · IMAGE · WIDE · ITEM_LIST · WIDE_ITEM_LIST · CAROUSEL_FEED · PERSONAL (personal-info consent — prefer the dedicated API) · KAKAO_CERT (KakaoTalk identity verification — coming soon; currently rejected with UNSUPPORTED_BUBBLE)
messageconditionalBubble text. Up to 1,000 characters for TEXT, 76 for WIDE. At least one of message and attachment is required
attachment.image.img_urlconditionalImage URL — required for IMAGE and WIDE. Use the url returned by Upload attachments
attachment.buttons[]Buttons. { "type": "WL", "name": "…", "url_pc": "…", "url_mobile": "…" } (WL = web link)
attachment.quick_replies[]Quick replies (up to 10). See Quick replies for the format
attachment.item · attachment.carousel · attachment.couponconditionalitem for WIDE_ITEM_LIST, carousel for CAROUSEL_FEED (2–6 cards), coupon
auto_answerSystem auto-reply (S1–S5) — TEXT only

Example ① TEXT + buttons:

{
"chat_bubble_type": "TEXT",
"message": "Please check your order",
"attachment": { "buttons": [ { "type": "WL", "name": "View order", "url_pc": "https://example.com/orders", "url_mobile": "https://example.com/m/orders" } ] }
}

Example ② IMAGE (an uploaded image):

{ "chat_bubble_type": "IMAGE", "attachment": { "image": { "img_url": "https://…/photo.jpg" } } }

Example ③ WIDE (image + short text + button):

{
"chat_bubble_type": "WIDE",
"message": "New products for September",
"attachment": {
"image": { "img_url": "https://…/banner.jpg" },
"buttons": [ { "type": "WL", "name": "Learn more", "url_pc": "https://example.com/new", "url_mobile": "https://example.com/m/new" } ]
}
}

The response is the same as for a text send and includes serial.

Quick replies (quick_replies)​

Buttons laid out horizontally below the bubble. When the customer taps one, a preset text is sent or a link opens. Up to 10 per message.

Format of a single button:

FieldMax lengthRequiredDescription
name14 chars✅Button label
type2 chars✅Button type — see below
url_mobile300 charsBy typeURL to open on mobile (http/https only)
url_pc300 charsURL to open on PC (http/https only)
scheme_android300 charsBy typeAndroid app scheme
scheme_ios300 charsBy typeiOS app scheme
url_target"out" to open in an external browser
extra100 charsMetadata passed with the button (BK, BT)
chat_event50 charsBot event to call when switching to a bot (BT)
biz_form_keyBy typeKakao Business Form key (BF)

type and the fields each one requires:

typeActionRequired fields
BKSends the button label as the customer's messageNone
WLOpens a web linkurl_mobile
ALOpens an app scheme or web linkAt least 2 of scheme_android, scheme_ios, url_mobile
BTSwitches to bot consultation (ends the consultation, then calls the bot event) — only for channels using a Kakao i Open Builder chatbotNone
BFOpens a Kakao Business Formbiz_form_key

Example ④ TEXT + quick replies:

{
"chat_bubble_type": "TEXT",
"message": "How can we help you?",
"attachment": {
"quick_replies": [
{ "type": "BK", "name": "Track order" },
{ "type": "BK", "name": "Returns" },
{ "type": "WL", "name": "FAQ", "url_mobile": "https://example.com/m/faq", "url_pc": "https://example.com/faq" }
]
}
}
caution
Limits differ from buttons (buttons[])
Quick replies quick_replies[]Buttons buttons[]
Label length14 chars28 chars (may be truncated depending on bubble and device)
URL / scheme length300 chars1,000 chars
CountUp to 102–5 depending on bubble type
Available typeBK, WL, AL, BT, BFThe above plus MD (sends label + body) and AC (add channel)

If a limit is exceeded, Kakao rejects the message and the send returns a failure. Check the 14-character limit especially when reusing a button label as a quick reply.


Send attachments​

Sends images and files directly to the customer. The server uploads them to Kakao and assembles the bubbles (image = rich IMAGE or a regular photo, file = plain FILE). Unlike Upload attachments, which only returns a URL, this API delivers to the customer.

POST /api/agent/send/attachments # multipart/form-data
PartRequiredDescription
brandKey✅Brand key
userKey✅Target customer key
textText to send along — with rich images it goes into the first bubble; with regular photos (imageStyle=plain) it is sent as a separate text bubble before the photos
files✅Files (multiple allowed). jpg, png and gif are sent as image bubbles; other formats (including webp and heic) are sent as file bubbles (detected by Content-Type or extension)
imageStyleImage bubble style — rich (default) or plain. See the table below
imageStyleWhat the customer seesLimits
rich (default)An image with a caption inside a white card. Tapping it does not open the full-size imageCaption required ("이미지" is added if empty) · aspect ratio 3:4–2:1 · width ≥ 500px — outside that, the server pads with white margins
plainA regular photo bubble, the same as photos customers send. Tapping opens the full-size imageNo caption · no aspect-ratio or width limits · up to 5MB (larger images are scaled down by the server)

For photos the customer needs to see in detail, such as drafts or print proofs, plain is recommended.

curl -X POST https://api.talkbridge.io/api/agent/send/attachments \
-H "Authorization: Bearer blumnb-..." \
-F "brandKey=mybrand" -F "userKey=Ab3d_x9Kq2Lm" -F "text=Here is the material you requested" \
-F "files=@photo.png" -F "files=@manual.pdf"

# As a regular photo bubble
curl -X POST https://api.talkbridge.io/api/agent/send/attachments \
-H "Authorization: Bearer blumnb-..." \
-F "brandKey=mybrand" -F "userKey=Ab3d_x9Kq2Lm" -F "imageStyle=plain" -F "text=Here is the draft" \
-F "files=@draft.jpg"
{ "ok": true, "results": [ { "kind": "image", "ok": true, "code": "0", "serial": "bw-…" }, { "kind": "file", "ok": true, "code": "0", "serial": "bw-…" } ] }

Each bubble gets its own serial. ok is true if at least one bubble succeeded, and failed items (ok: false) carry a message explaining why. An image that is still over 5MB after the server scales it is not sent to Kakao; only that item fails with IMAGE_TOO_LARGE. To delete them, see Cancel a send (delete).


Cancel a send (delete)​

Deletes a sent message within 24 hours of sending. Text, rich, image and file messages are all deleted with this one API, and the unit of deletion is one bubble.

POST /api/agent/delete
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key
serialstringone ofThe serial from the send response — deletes exactly that bubble (recommended)
textstringone ofWhen you don't know the serial, finds the recent send by its exact body text
withinSecondsnumberLookback window for the text search (seconds, 10–86400; default 180)
{ "ok": true, "code": "0", "message": null, "serial": "bw-1757400000000-a1b2" }

Rules to know first​

  • You can delete only up to 24 hours after sending.
  • The bubble disappears from the customer's chat room and a "This message has been deleted" notice is left in its place. It is not a silent removal.
  • The consultation count is not restored. Deleting is not the same as cancelling the send.
  • Personal-data consent and KakaoTalk verification bubbles, and messages sent by the customer, cannot be deleted.
  • Deleting a bubble that was already deleted returns ok: false with a message saying it is already deleted.
  • Store the serial when you send. Every send response and the webhook agent signal carry it. Looking up by text is a fallback for when you lost the serial.

1. Text and rich messages​

A text send or rich send is a single bubble, so you delete it with the one serial in the response.

# Send → store the serial from the response
curl -X POST https://api.talkbridge.io/api/agent/send \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d '{ "brandKey": "mybrand", "userKey": "Ab3d_x9Kq2Lm", "text": "We have confirmed your order" }'
# → { "ok": true, "code": "0", "serial": "bw-1757400000000-a1b2" }

# Delete
curl -X POST https://api.talkbridge.io/api/agent/delete \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d '{ "brandKey": "mybrand", "userKey": "Ab3d_x9Kq2Lm", "serial": "bw-1757400000000-a1b2" }'

If you don't have the serial, you can pass "text": "We have confirmed your order" instead. If you sent the same text several times, the most recent one is deleted.

2. A single image​

When you send one image with Send attachments, results[] has one item; delete it with that serial. Any text you sent with it becomes the image bubble's caption, so it is the same bubble — deleting it removes the image and the caption together.

{ "ok": true, "results": [ { "kind": "image", "ok": true, "code": "0", "serial": "bw-1757400000100-c583" } ] }
curl -X POST https://api.talkbridge.io/api/agent/delete \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d '{ "brandKey": "mybrand", "userKey": "Ab3d_x9Kq2Lm", "serial": "bw-1757400000100-c583" }'

If you sent a caption, you can also delete with "text": "<the caption you sent>".

3. Several images (a group)​

Even when you send several images at once, each image is its own bubble in the customer's chat room, and results[] has a serial per image. You also delete once per bubble — a single call does not delete the whole group.

{ "ok": true, "results": [
{ "kind": "image", "ok": true, "code": "0", "serial": "bw-1757400000200-36e8" },
{ "kind": "image", "ok": true, "code": "0", "serial": "bw-1757400000201-2ecb" }
] }
# Delete the whole group — one call per successful item's serial
for s in bw-1757400000200-36e8 bw-1757400000201-2ecb; do
curl -X POST https://api.talkbridge.io/api/agent/delete \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d "{ \"brandKey\": \"mybrand\", \"userKey\": \"Ab3d_x9Kq2Lm\", \"serial\": \"$s\" }"
done
  • You can also delete only the images you choose; the other bubbles stay.
  • Looking up by text works only for the first image: the caption goes on the first image and later images get a default caption. Delete groups by serial.
  • If some images fail, ok is still true as long as at least one was sent. Failed items (ok: false) never reached the customer, so there is nothing to delete; message explains why (for example, an unsupported image — very small or very tall images are not supported).
  • If you send a file together with text, the file bubble and the text bubble go out separately (kind: "file" and kind: "text"). Delete each by its own serial.

Confirming a deletion​

  • Webhook: each successful deletion sends one kind: "deleted" signal. Its serial is the bubble that was deleted — deleting a whole group sends one per image. Deletions made from another agent tool arrive the same way.
  • Retrieval: in recent messages the original outbound item gets deleted: true. For a group, it is set once every image has been deleted.

Failure codes​

codeMeaningWhat to do
NOT_FOUNDNo recent send matched textIncrease withinSeconds or pass serial
NOT_DELETABLEPersonal-data consent or KakaoTalk verification bubbleCannot be deleted
EXPIREDMore than 24 hours since sendingCannot be deleted
Other codesAlready deleted, etc.Follow the message

End consultation​

A human agent actively ends an in-progress consultation session. If a closing greeting is provided, it is sent first, then the session ends.

POST /api/agent/end
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key
greetingstringClosing greeting to send before ending (optional)

End + hand off to bot​

Ends the consultation and hands off to a bot scenario.

POST /api/agent/end-with-bot
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key
botEventstringBot event to hand off to (optional)

Sends Kakao's personal-info consent bubble to the customer. When the customer agrees, their nickname and phone number are delivered as a webhook personal_info event. Kakao channels only.

POST /api/agent/personal-info/request
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key
curl -X POST https://api.talkbridge.io/api/agent/personal-info/request \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d '{ "brandKey": "mybrand", "userKey": "Ab3d_x9Kq2Lm" }'
# → { "ok": true, "code": "0", "serial": "bw-1757400000000-a1b2" }
  • ok in the response is the result of sending the bubble. The consent result arrives by webhook, not in this response.
  • The bubble's text and button are fixed by Kakao and cannot be changed. It can be sent once per consultation session, and consent is valid only within 3 days of sending.
  • Like any other send, it counts toward your consultations (no extra usage if you are already serving that consultation that day).
  • This bubble cannot be removed with Cancel a send.
Failure codeMeaning
UNSUPPORTED_CHANNELNot a Kakao channel
-520Consent was already requested in this consultation (once per session) — you can send it again once the customer starts a new consultation
EMPTYuserKey is empty
The consent result is delivered only once

TalkBridge relays the consent result (nickname and phone number) without storing it. There is no way to receive it again or look it up, so connect your webhook before you send the request and store the data as soon as it arrives. Discord and Slack integrations are only told that consent was given — the values are not sent there.


Block / unblock customer​

POST /api/agent/block
POST /api/agent/unblock
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key

Upload attachments​

Upload the image or file you want to attach to an outbound message first, to obtain its URL and key.

POST /api/agent/upload/image # multipart: brand, file, imageType?(rich|plain)
POST /api/agent/upload/file # multipart: brand, file, fileType(file|audio|video)

Upload an image with the imageType that matches where you will send it. A URL uploaded for the other kind is rejected when sending.

imageTypeUsed forLimits
rich (default)The image of a rich messageAspect ratio 3:4–2:1 · width ≥ 500px · up to 5MB
plainSend a regular photoUp to 5MB

Image upload example:

curl -X POST https://api.talkbridge.io/api/agent/upload/image \
-H "Authorization: Bearer blumnb-..." \
-F "brand=mybrand" -F "imageType=plain" -F "file=@photo.jpg"
{ "ok": true, "code": "0000", "url": "http://dn-m.talk.kakao.com/.../photo.jpg", "imageType": "plain" }

Use the returned url in the image field of a rich message (rich) or with Send a regular photo below (plain).

  • Only jpg, png and gif can be uploaded. The server checks the file content itself, so renamed files (e.g. a webp saved as .jpg) and corrupted files return 400 UNSUPPORTED_IMAGE.
  • plain is prepared by the server the same way as Send attachments (photo orientation fixed; scaled down above 5MB or a 4096px long side).
  • rich is passed as uploaded (no padding or scaling). Above 5MB it returns 413 IMAGE_TOO_LARGE. To also fit the aspect ratio and send right away, use Send attachments.

Send a regular photo​

Sends a url obtained with imageType=plain as a regular photo bubble. Tapping it opens the full-size image. It cannot carry a caption — send one separately with Send text if needed.

POST /api/agent/send/image
FieldTypeRequiredDescription
brandKeystring✅Brand key
userKeystring✅Target customer key
imageUrlstring✅The url returned by upload/image (imageType=plain). External image URLs are not accepted by Kakao and are rejected with 400 BAD_URL
curl -X POST https://api.talkbridge.io/api/agent/send/image \
-H "Authorization: Bearer blumnb-..." -H "Content-Type: application/json" \
-d '{ "brandKey": "mybrand", "userKey": "Ab3d_x9Kq2Lm", "imageUrl": "http://dn-m.talk.kakao.com/.../photo.jpg" }'
{ "ok": true, "code": "0", "message": null, "serial": "bw-…" }
Watch out for self-echo

When an outbound send succeeds, a kind: "agent" signal comes back to your inbound webhook twice (an acceptance signal with phase: "accepted", then the journal entry) — an echo of your own send. To avoid infinite loops, filter out kind == "agent" events in your webhook handler. See Inbound payload for details.