모든 엔드포인트는 HTTPS 위에서 동작하며, Bearer JWT 인증이 필요합니다. 모든 요청·응답 본문은 UTF-8 JSON입니다.
elliurl 서비스 베이스 URL은 https://elliurl.com 입니다.
단축 URL 자체는 https://elliurl.kr/<code> 에서 서빙됩니다.
모든 API 요청은 브랜드 도메인 (elliurl.com) 아래 /api 경로로 보냅니다.
POST /api/shorten 에 JWT 인증과 함께 JSON을 보내면
즉시 단축 URL이 반환됩니다. 모든 API는 로그인이 필요합니다.
| API 유형 | 인증 | 설명 |
|---|---|---|
| 사용자 API | JWT | Authorization: Bearer <token> |
이메일로 가입 후 로그인하면 JWT 토큰이 발급됩니다. 유효기간 7일.
# 1. 회원가입 curl -X POST https://elliurl.com/api/auth/signup \ -H "content-type: application/json" \ -d '{"email": "you@example.com", "password": "mypassword"}' # 응답에서 token 필드를 복사 # {"token": "eyJhbG...", "user": {"id": "...", "plan": "pro"}} # 2. 이후 로그인 (토큰 만료 시) curl -X POST https://elliurl.com/api/auth/login \ -H "content-type: application/json" \ -d '{"email": "you@example.com", "password": "mypassword"}' # 3. 토큰 사용 curl https://elliurl.com/api/me \ -H "Authorization: Bearer eyJhbG..."
/api/auth/google/start 접속 후
Google 인증 → 자동으로 JWT 발급 + 대시보드 리다이렉트.
JWT 인증이 필요합니다. 플랜별 일일 호출 한도가 적용됩니다.
긴 URL을 받아서 elliurl.kr/<code> 단축 URL을 반환합니다. 생성된 링크는 계정에 자동 귀속됩니다.
[a-zA-Z0-9_-]. 생략 시 6자 nanoid 자동 생성.curl -X POST https://elliurl.com/api/shorten \ -H "content-type: application/json" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -d '{"target":"https://ellilabs.com/blog/long-post"}'
{
"code": "9fgGfh",
"short_url": "https://elliurl.kr/9fgGfh",
"target": "https://ellilabs.com/blog/long-post",
"created_at": 1775901439,
"scan_status": "pending"
}
400 malicious_target을 반환하고 링크는 생성되지 않습니다.
이후 백그라운드에서 Cloudflare URL Scanner가 추가 검증하며, flagged 시 자동 비활성화됩니다.
프로덕션 실시간 통계(생성된 링크 수, 총 클릭, 국가 수, 최근 공개 링크 5건). KV 60초 캐시.
{
"total_links": 42,
"total_clicks": 118,
"countries": 3,
"created_24h": 8,
"recent": [
{ "code": "abc", "host": "ellilabs.com", "click_count": 5, "created_at": 1775900000 }
]
}
이메일·비밀번호 또는 Google OAuth로 가입·로그인. 성공 시 JWT를 반환합니다.
{
"token": "eyJhbGc...",
"exp": 1776506564,
"user": {
"id": "uuid",
"email": "you@example.com",
"plan": "pro"
}
}
plan_status = "alpha_grandfathered" 로 승급됩니다.
결제 시스템이 열린 뒤에도 Pro 월 ₩0 영구 유지.
로그인. signup과 동일한 응답 형태의 새 JWT를 반환합니다.
현재 JWT를 블랙리스트에 추가 (TTL = JWT 잔여 시간). 이후 해당 토큰은 401을 반환합니다.
현재 로그인한 사용자 정보.
{ "id": "uuid", "email": "you@example.com", "plan": "pro", "is_admin": false }
JWT 인증 필수. 링크 조회·수정·삭제 엔드포인트.
내 링크 목록 (최신순 최대 100건). 각 링크의 클릭 수·OG 메타 포함.
{
"items": [
{
"code": "abc",
"target": "https://ellilabs.com",
"title": "회사 홈",
"og_title": "Elli Labs — ...",
"og_description": "...",
"og_image": "https://...",
"is_active": 1,
"click_count": 42,
"created_at": 1775901439
}
]
}
내 링크 수정. null 값을 보내면 해당 필드 제거.
내 링크 soft delete (is_active=0). KV 캐시도 즉시 무효화됩니다.
특정 링크의 클릭 통계. 내가 소유한 링크만.
{
"code": "abc",
"summary": {
"total": 42,
"last_24h": 5,
"last_7d": 18
},
"by_country": [{ "country": "KR", "n": 38 }],
"by_device": [{ "device": "mobile", "n": 25 }]
}
elliurl의 핵심 차별점. 링크 생성 시 목적지 URL의 OG 태그가 서버사이드로
자동 fetch되어 D1에 캐시됩니다. PATCH /api/me/links/:code로
원하는 제목·설명·이미지로 덮어쓸 수 있고, 크롤러 UA
(KakaoTalk, Slackbot, Twitterbot, facebookexternalhit 등)가 단축 URL을 방문하면
오버라이드된 메타가 반환됩니다. Bitly·TinyURL에서는 불가능한 동작.
elliurl.kr/a(커피 카피) 와
elliurl.kr/b(숫자 카피) 로 두 번 단축 →
각 링크의 og_title을 다르게 오버라이드 →
카카오톡 두 채널에 나눠 공유 → /api/me/links/:code/stats로 클릭률 비교.
단축 URL의 QR 코드 SVG. 512×512, error correction level M.
응답 헤더에 content-disposition: inline; filename="elliurl-:code.svg",
KV 24h 캐시. 비활성 또는 미존재 코드는 404.
curl https://elliurl.com/qr/abc -o abc.svg # HTML 임베드 <img src="https://elliurl.com/qr/abc" width="256" />
PNG가 필요하면 SVG를 브라우저 <canvas> 에 그려서 export 하거나
ImageMagick/rsvg 같은 도구로 로컬 변환하세요.
내 플랜·구독 상태.
{
"plan": "pro",
"plan_status": "active",
"plan_expires_at": 1778500000,
"grandfathered": false,
"alpha_window_active": true,
"has_paid_subscription": true
}
plan_status 값: free ·
alpha_grandfathered · active ·
past_due · cancelled · expired
토스 정기결제 billing auth 초기화. 반환된 파라미터로 프론트엔드에서
TossPayments.requestBillingAuth('카드', {...})를 호출하세요.
해외 카드 결제용 LemonSqueezy checkout URL 생성.
구독 해지. billing key를 제거하고 plan_status = "cancelled"로 전환. 현재 결제 주기 종료일까지는 Pro 기능 유지.
Pro 플랜 유저는 자신의 도메인(go.yourbrand.com)을
elliurl에 연결해서 단축 링크를 자기 브랜드 도메인으로 서빙할 수 있습니다.
Cloudflare for SaaS를 이용해 TLS 인증서가 자동 발급됩니다.
내가 등록한 커스텀 도메인 목록.
go.ellilabs.com
응답의 instructions 필드에 DNS CNAME 설정 방법이 포함됩니다.
CNAME 추가 후 Cloudflare가 소유권 확인 + TLS 인증서 발급까지 약 30초~5분.
도메인 상태 조회. 호출 시 Cloudflare에서 최신 상태를 fresh fetch하여 DB에 반영합니다.
도메인 등록 해제. Cloudflare에서도 함께 삭제됩니다.
{
"error": {
"code": "invalid_target",
"message": "유효한 http(s) URL만 허용됩니다"
}
}
| 코드 | HTTP | 설명 |
|---|---|---|
invalid_target | 400 | 스킴·형식 또는 내부 IP |
invalid_code | 400 | 슬러그 형식 위반 |
code_taken | 409 | 슬러그 중복 |
malicious_target | 400 | Google Web Risk 차단 |
rate_limited | 429 | 일일 한도 초과 |
free_link_quota | 402 | Free 플랜 월 50개 초과 |
unauthorized | 401 | JWT 누락·만료·블랙리스트 |
forbidden | 403 | 관리자 권한 필요 |
not_found | 404 | 리소스 없음 |
pro_required | 402 | Pro 플랜 전용 기능 |
domain_quota | 402 | 커스텀 도메인 한도 초과 |
| 대상 | 한도 | 기준 |
|---|---|---|
로그인 POST /api/auth/login | 10/분 | IP 단위 sliding window |
가입 POST /api/auth/signup | 5/분 | IP 단위 sliding window |
| JWT 사용자 API (Free) | 1,000/일 | 유저 단위 |
| JWT 사용자 API (Pro) | 10,000/일 | 유저 단위 |
| JWT 사용자 API (Business) | 100,000/일 | 유저 단위 |
429 상태 코드가 반환됩니다.
자동화·배치 작업은 가입 후 JWT로 호출하세요.