문서 · 빠른 시작

5분 만에 첫 알림 보내기

API 키 하나로, 한 명의 사용자에게 직접 닿는 알림을 보냅니다. 기기 등록·푸시 권한은 EosNoti 앱(iOS·Android)이 대신 처리합니다.

AI로 연동

AI에게 맡기고 5분 만에 붙이기

이 통합 가이드를 Claude·Cursor 같은 AI 코딩 어시스턴트에 첨부하면, 회원가입 지점의 EosNoti 연동 코드를 자동으로 만들어 줍니다. 발급받은 API 키만 준비하세요.

/eosnoti-integration.md
1

계정 + 애플리케이션(채널) 만들기

콘솔에서 가입하고 애플리케이션(채널)을 만들면 API 키를 받습니다. 생성 직후 한 번만 노출되니 안전한 곳에 보관하세요(백엔드 시크릿, 브라우저 노출 금지). 이후 모든 발송·연동 API는 이 키로 인증합니다.

콘솔에서 시작하기
2

6자리 코드로 채널 구독 (정·역방향)

external_id(당신 서비스의 사용자 ID, 예: 내부 user PK)를 담은 6자리 페어링 코드를 백엔드에서 발급해 구독시킵니다. 정방향: 내 앱이 코드를 보여주고 사용자가 EosNoti 앱 '코드 추가 → 코드 입력'에 넣으면 백엔드가 상태를 폴링합니다. 같은 코드를 QR로도 낼 수 있습니다 — 응답의 url을 QR로 그리면 폰 기본 카메라로 찍어도 앱이 열립니다. 코드 하나에 폴링 하나이므로, 사용자가 입력했든 스캔했든 같은 폴링이 redeemed로 바뀝니다. 역방향: 앱 '내 코드 보기'가 코드를 보여주고 사용자가 내 앱 입력칸에 넣으면 백엔드가 redeem합니다. 한 사람이 여러 기기를 가져도 같은 external_id로 묶입니다. 코드는 단발성·10분 만료입니다.

6자리 코드 페어링 흐름 (정·역방향)내 서비스백엔드 발급 · 내 앱 표시/입력EosNoti 앱사용자 기기 · 코드 추가정방향AB7K9PX9Q3MR역방향바인딩 완료external_id ↔ 사용자 기기 · 이제 ext:<id> 로 그 사람에게 발송
API_KEY=<발급받은 api_key>

# [정방향] 내 앱이 코드 표시 → 사용자가 EosNoti 앱에 입력
curl -s -X POST https://api.eosnoti.com/v1/pairing-codes \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"external_id":"user_8821"}'
# ← {"code":"AB7K9P","url":"https://www.eosnoti.com/s/AB7K9P","expires_at":"..."}
curl -s https://api.eosnoti.com/v1/pairing-codes/AB7K9P \
  -H "Authorization: Bearer $API_KEY"
# ← {"status":"pending|redeemed|expired","subscription_id":...}

# 같은 코드를 QR로도 낼 수 있다 — 6자리가 아니라 «url»을 QR로 그린다.
# 폰 기본 카메라로 찍어도 앱이 열리고, 앱이 없으면 설치 안내로 폴백한다.
# 입력이든 스캔이든 위 폴링 하나가 redeemed로 바뀐다(발급도 폴링도 그대로).

# [역방향] EosNoti 앱이 코드 표시 → 사용자가 내 앱에 입력 → redeem
curl -s -X POST https://api.eosnoti.com/v1/pairing-codes/X9Q3MR/redeem \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"external_id":"user_8821"}'
# ← {"subscription_id":"...","external_id":"user_8821"}
3

오래 사는 구독 링크 (메일·문자로 보낼 때)

10분보다 오래 살아야 하는 링크가 필요할 때 external_id를 담은 subscribe-link를 발급합니다. url을 그대로 보내면 사용자가 폰에서 누르는 것만으로 EosNoti 앱이 열리며 구독·external_id 바인딩까지 끝나고, 앱이 없으면 설치 안내 화면이 열립니다. QR로 제시해도 결과는 같습니다. 다만 이 코드에는 상태 조회가 없어 폴링으로 연결을 감지할 수 없습니다 — 화면에서 연결을 기다려야 한다면 2단계의 페어링 코드 url을 QR로 쓰십시오. 링크는 단발성·ttl 만료입니다(기본 24시간, 최대 30일).

subscribe-link 채널 구독 흐름 (링크 탭 · QR 스캔)내 서비스subscribe-link 발급url 전달 또는 QR 표시EosNoti 앱사용자 기기링크 탭 또는 QR 스캔링크 탭/s/<code>QR 스캔같은 코드 · external_id 내장바인딩 완료external_id ↔ 사용자 기기 · 이제 ext:<id> 로 그 사람에게 발송
API_KEY=<발급받은 api_key>

# external_id를 담은 subscribe-link 발급
curl -s -X POST https://api.eosnoti.com/v1/subscribe-links \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"user_8821","ttl":86400}'   # ttl 초, 0/생략=24h
#                                                 상한 30일(2592000) — 초과·음수는 400
# ← {"url":".../s/<code>","code":"<code>","expires_at":"..."}

# ① url을 문자·메신저로 그대로 전달 → 사용자가 폰에서 탭하면 EosNoti 앱이 열림
#    (앱 미설치면 설치 안내 웹페이지로 폴백)
# ② 또는 url을 QR로 표시 → 사용자가 EosNoti 앱 "코드 추가 → QR 스캔"으로 스캔
# 어느 쪽이든 앱이 기기 등록·구독·external_id 바인딩까지 자동 처리

# 구독 여부 조용히 확인 (발송·쿼터 소비 없음). 구독/미구독 모두 200 동일 스키마
curl -s "https://api.eosnoti.com/v1/subscriptions/lookup?external_id=user_8821" \
  -H "Authorization: Bearer $API_KEY"
# ← {"subscribed":true,"device_count":2,"push_enabled":true,"platforms":["ios","android"]}
#   미구독이면 {"subscribed":false,"device_count":0,"push_enabled":false,"platforms":[]}

사용자에게 보낼 안내가 필요합니까?

앱 설치부터 코드·QR·링크로 구독하는 방법까지, 수신자 눈높이로 정리한 공개 페이지가 있습니다. 이 링크를 그대로 사용자에게 보내면 됩니다.

구독 안내 페이지 보기
4

알림 보내기

API 키로 특정 사용자(ext:외부ID) 또는 broadcast(구독자 전체)에 메시지를 보냅니다. ext: 대상은 그 사람이 연결한 모든 기기 — EosNoti 앱 iOS(APNs)·Android(FCM) — 로 한 번에 자동 전달됩니다. notify(일반)와 ask(선택지)를 지원합니다. 이미지는 필드로만 전달됩니다: icon은 알림 좌측 발신자 아바타(생략 시 콘솔에서 설정한 애플리케이션(채널) 아바타), image는 콘텐츠 이미지로 알림 우측 썸네일(iOS)·이미지 첨부(Android)와 인박스 카드에 표시됩니다. 둘 다 http(s) URL만 허용, 메시지당 1장이며, body 본문에 URL을 적어도 이미지로 렌더되지 않습니다. 따로 호스팅할 아이콘이 없다면 icon에 EosNoti 콘솔 파비콘 URL(예: https://console.eosnoti.com/icon.png, 512px 정사각 PNG)을 넣으면 됩니다.

API_KEY=<발급받은 api_key>

# 한 사람에게 (그 사람의 모든 기기 — iOS·Android — 로, notify)
# icon  = 알림 좌측 발신자 아바타 (생략 시 콘솔에서 설정한 애플리케이션(채널) 아바타)
# image = 콘텐츠 이미지 → 알림 우측 썸네일(iOS)·이미지 첨부(Android) + 인박스 카드
#         (둘 다 http(s) URL만, 메시지당 1장. body에 URL을 적어도 이미지로 안 보임)
#         파일을 직접 올리시려면 아래 5단계 ②를 보십시오
curl -X POST https://api.eosnoti.com/v1/messages \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"ext:user_8821","kind":"notify",
       "title":"결제 완료","body":"주문 #2043이 접수됐습니다","priority":"high",
       "icon":"https://console.eosnoti.com/icon.png",
       "image":"https://example.com/receipt-2043.jpg"}'

# 구독자 전체에게 + 선택지 묻기 (ask)
curl -X POST https://api.eosnoti.com/v1/messages \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"broadcast","kind":"ask",
       "body":"회의 참석하시겠습니다?","choices":["참석","불참"]}'
5

이미지 보내는 두 가지 방법

이미지는 어느 요금제에서나 무제한으로 보내실 수 있습니다. 링크를 넘기시면 저희는 아무것도 보관하지 않습니다. 파일을 직접 올리는 방법은 저희가 대신 보관해 드리는 것이라, 요금제별로 «동시에 보관할 수 있는 장수»가 정해져 있습니다. 올린 이미지는 7일 뒤 자동으로 지워지고, 그만큼 장수가 다시 늘어납니다.

# ① 링크로 보내기 — 모든 요금제, 무제한. 저희는 아무것도 보관하지 않습니다.
curl -X POST https://api.eosnoti.com/v1/messages \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"to":"ext:user_8821","body":"주문이 접수됐습니다",
       "image":"https://example.com/receipt-2043.jpg"}'

# ② 올려서 보내기 — 유료 요금제. JPEG만, 한 장 2MB까지, 7일 뒤 자동 삭제.
#    동시 보관 장수는 요금제마다 다릅니다(Free는 0 — ①번 링크 방식만). 요금제 안내 참고.
URL=$(curl -s -X POST https://api.eosnoti.com/v1/images \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg | jq -r .url)
# ← {"url":"...","expires_at":"...","used":13,"quota":100}   quota=-1이면 무제한

curl -X POST https://api.eosnoti.com/v1/messages \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d "{\"to\":\"ext:user_8821\",\"body\":\"주문이 접수됐습니다\",\"image\":\"$URL\"}"

# 보관 장수를 다 쓰면 409 image_quota_exceeded, 무료 요금제는 403 plan_required.
# 어느 쪽이든 ①번 링크 방식은 그대로 쓰실 수 있습니다.
6

상태·응답 확인

발송 후 전달·읽음 수와 ask 응답을 조회합니다. 발송 응답의 queued_deliveries가 1 이상이면 그 external_id에 바인딩된 구독이 있다는 뜻이라, 백엔드에서 연결 확인용으로 쓰면 됩니다. 구독자 목록 조회는 콘솔 세션(쿠키) 전용이라 백엔드 api_key로는 호출되지 않습니다.

API_KEY=<발급받은 api_key>
MSG=<message_id>

# 전달·읽음 수 + 응답 조회
curl -s https://api.eosnoti.com/v1/messages/$MSG \
  -H "Authorization: Bearer $API_KEY"
# ← {"deliveries":{...},"replies":[...],"replies_total":1}
#    replies는 미리보기 200건까지 — 전체는 아래 /replies를 커서로 훑습니다

# ask 응답 롱폴링 (최대 30초) + 페이징
curl -s "https://api.eosnoti.com/v1/messages/$MSG/replies?wait=30&limit=200" \
  -H "Authorization: Bearer $API_KEY"
# ← {"replies":[...],"next_cursor":"<있으면 더 있음>"}
#    limit 기본 200 · 최대 1000. next_cursor를 &cursor= 로 넘겨 이어서 받습니다
#    (커서를 주면 «그 뒤의 새 응답»만 기다리므로 롱폴링이 실제로 대기합니다)

# 연결 확인(조용히): GET /v1/subscriptions/lookup?external_id= (위 3단계 참고)
# 발송 겸용이면 이 응답의 queued_deliveries>0 로도 확인 가능
# (구독자 목록 조회는 콘솔 세션 전용 — 백엔드 api_key로는 401)
더 알아두기

붙이기 전에 알아둘 것

여기까지면 발송은 됩니다. 아래는 운영에 들어가기 전에 한 번은 확인해야 하는 것들입니다.

발송 한도는 응답 헤더로 옵니다

발송 성공 응답에 X-Quota-Limit · X-Quota-Used · X-Quota-Remaining · X-Quota-Reset(일)과 X-Quota-Month-* (월)가 함께 옵니다. 한도를 넘기면 429 quota_exceeded 이므로, 배치 발송이라면 남은 수량을 보고 멈추는 편이 안전합니다.

429 · quota_exceeded

구독자가 아이디를 직접 넣을 수도 있습니다

채널 설정에서 「구독 시 아이디 입력」을 켜면, 페어링 코드 없이 구독한 사용자도 스스로 external_id를 신고합니다. 백엔드가 코드를 발급하기 어려운 서비스에서 쓰기 좋습니다. 다만 값의 진위는 서비스가 따로 확인해야 합니다.

external_id_mode

대화·예약 발송은 API 경로가 아닙니다

ask 후속(대화 잇기)과 예약 발송은 콘솔·맥앱의 운영 경로 기능입니다. API 키로 parent_message_id나 scheduled_at을 보내면 400으로 거부됩니다. 사람이 손으로 운영하는 흐름이라 세션 인증을 요구합니다.

console only

구독하는 순간 환영 메시지를 보낼 수 있습니다

채널 설정에 환영 메시지를 넣어 두면 구독 직후 자동으로 첫 알림이 갑니다. 구독이 제대로 됐는지 사용자가 바로 확인할 수 있어 문의가 줄어듭니다.

welcome_message

준비됐습니까?

무료로 시작해서 첫 알림을 보내보세요.

무료로 시작하기