uurlu

API 문서

QR 코드 생성과 URL 단축을 REST로 제공합니다. 인증 키가 필요 없고, 모든 응답에Access-Control-Allow-Origin: *가 붙어 브라우저에서 바로 호출할 수 있습니다.

기준 URL

https://your-domain

QR 코드 생성

GET/api/qr
POST/api/qr

두 메서드는 동일한 파라미터를 받습니다. GET은 쿼리 문자열, POST는 JSON 본문을 사용합니다. 기본 응답은 이미지 바이트라 <img src>에 URL을 그대로 넣을 수 있습니다.

공통 옵션

이름타입기본값설명
typestringurlurl · text · email · tel · sms · wifi · vcard · geo
formatstringpngpng 또는 svg. 그 외 포맷은 지원하지 않습니다.
sizeint51264–2000. 출력 한 변의 픽셀 길이 (여백 포함).
marginint20–20. 모듈 단위의 여백(quiet zone).
eccstringML·M·Q·H. 오류 복원 레벨. 인쇄물에는 H 권장.
darkstring#000000전경색. #rgb · #rrggbb · #rrggbbaa.
lightstring#ffffff배경색. #ffffff00 을 주면 투명 PNG.
responsestringbinaryjson 으로 주면 dataUrl 을 담은 JSON 반환.
downloadboolfalsetrue 면 Content-Disposition: attachment 추가.

type 별 내용 파라미터

중첩 객체가 아닌 평면 구조라 쿼리 문자열과 JSON 본문에서 형태가 같습니다.

type필수선택
urldata
textdata
emailtosubject, body
telphone
smsphonemessage
wifissidpassword, encryption(WPA·WEP·nopass), hidden
vcard이름·전화·이메일 중 하나firstName, lastName, organization, title, phone, email, website, address, note
geolatitude, longitude

긴 URL을 짧게 넣기 (권장)

URL이 길수록 QR 패턴이 촘촘해져 인쇄물/저조도 환경에서 스캔 실패가 늘어날 수 있습니다. 먼저 /api/shorten으로 짧은 링크를 만든 뒤 그 값을 /api/qr?data=...에 넣는 흐름을 권장합니다. 웹 UI에서는 QR 탭 URL 입력 아래 “이 URL 숏으로 바꾸기” 버튼이 같은 동작을 수행합니다.

# 1) 긴 URL 단축
curl -X POST "https://your-domain/api/shorten" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com/really/long/path?utm_source=newsletter&utm_medium=email"}'

# 응답 예시
{
  "shortUrl": "https://your-domain/s/abc1234",
  ...
}

# 2) shortUrl을 QR에 인코딩
curl "https://your-domain/api/qr?data=https://your-domain/s/abc1234&size=512&ecc=H" --output short-link-qr.png

예시

# 가장 단순한 형태 — PNG 이미지가 그대로 돌아옵니다
curl "https://your-domain/api/qr?data=https://example.com" --output qr.png

# 투명 배경 SVG, 여백 없음
curl "https://your-domain/api/qr?data=https://example.com&format=svg&light=%23ffffff00&margin=0" \
  --output qr.svg

# Wi-Fi 접속용 QR
curl "https://your-domain/api/qr?type=wifi&ssid=MyCafe&password=hunter2&encryption=WPA" \
  --output wifi.png

# POST + JSON, dataUrl 로 받기
curl -X POST "https://your-domain/api/qr" \
  -H 'Content-Type: application/json' \
  -d '{"type":"vcard","firstName":"길동","lastName":"홍","phone":"+82-10-1234-5678",
       "ecc":"H","size":800,"response":"json"}'

HTML에 바로 삽입

<img src="https://your-domain/api/qr?data=https://example.com&size=256" width="256" alt="QR" />

URL 단축

POST/api/shorten

요청 본문

이름타입기본값설명
urlstring필수줄일 http/https 주소. 스킴 생략 시 https 로 간주.
slugstring선택원하는 코드. 영문·숫자·하이픈·밑줄 3–64자.
expiresInint선택만료까지 남은 초. 생략하면 만료 없음.

예시

curl -X POST "https://your-domain/api/shorten" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com/very/long/path","slug":"my-link","expiresIn":86400}'

응답 (201 Created)

{
  "code": "my-link",
  "shortUrl": "https://your-domain/s/my-link",
  "url": "https://example.com/very/long/path",
  "createdAt": "2026-07-28T08:00:00.000Z",
  "expiresAt": "2026-07-29T08:00:00.000Z",
  "clicks": 0,
  "lastClickedAt": null,
  "qrUrl": "https://your-domain/api/qr?data=...",
  "statsUrl": "https://your-domain/api/links/my-link",
  "reused": false
}

slug 없이 같은 URL을 두 번 단축하면 새 코드를 만들지 않고 기존 링크를 그대로 돌려주며 200reused: true가 됩니다. 이 서비스의 QR API URL(/api/qr?…)은 단축할 수 있습니다. 단축 링크·통계 URL처럼 이미 짧은 주소는 새로 만들지 않고, 저장된 링크가 있으면 그 값을 돌려줍니다.

링크 조회 및 리다이렉트

GET/s/{code}

원본 주소로 307 리다이렉트하고 클릭 수를 1 올립니다. 코드가 없거나 만료되었으면 안내 페이지를 보여줍니다. 예: https://your-domain/s/my-link

GET/api/links/{code}

클릭 수와 만료 정보를 JSON으로 반환합니다. 없으면 404.

curl "https://your-domain/api/links/my-link"
GET/api/health

서비스 상태와 현재 저장소 드라이버를 반환합니다.

관리자 전용

아래 두 엔드포인트는 ADMIN_TOKEN 환경변수가 설정되어 있을 때만 동작하며 Authorization: Bearer <token> 헤더가 필요합니다. 변수가 없으면 404로 응답합니다. 삭제를 공개하면 누구나 남의 링크를 지울 수 있고, 목록을 공개하면 단축된 모든 URL이 노출되기 때문입니다.

DELETE/api/links/{code}
GET/api/links?limit=50
curl -X DELETE "https://your-domain/api/links/my-link" \
  -H "Authorization: Bearer $ADMIN_TOKEN"

오류 형식

모든 오류는 같은 형태입니다. 검증 실패(422)일 때 details에 필드별 메시지가 담깁니다.

{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed.",
    "details": { "size": "Too big: expected number to be <=2000" }
  }
}
상태code의미
400bad_request본문이 JSON이 아니거나 URL을 인코딩할 수 없음
401unauthorized관리자 토큰이 없거나 틀림
404not_found코드를 찾을 수 없거나 관리자 기능이 비활성화됨
409conflict요청한 slug 가 이미 사용 중
413payload_too_large본문 또는 인코딩된 내용이 한도 초과
415unsupported_media_typeContent-Type 이 application/json 이 아님
422validation_failed파라미터 값이 규칙에 맞지 않음
503service_unavailable고유 코드 발급 실패 — 재시도 권장

제한 사항