호출자가 두 종류이므로 키 범위도 두 가지입니다
워크스페이스 키는 워크스페이스 하나 안에서 동작합니다. 링크, 분석, 그 워크스페이스가 쓸 수 있는 도메인, 그리고 자체 사용량입니다. 파트너 키는 사업 전체에서 동작합니다. 고객과 그들의 구독, 여러분이 판매하는 요금제, 모든 도메인, 수수료 내역이 포함된 결제, 정산, 그리고 집계된 분석 개요입니다. 두 접두사는 눈에 띄게 다르므로, 엉뚱한 서비스에 붙여 넣은 키는 놀라운 일을 벌이는 대신 곧바로 실패합니다.
키는 대시보드에서 만들고, 한 번만 표시되며, 해시로만 저장됩니다. 키마다 고유한 범위 목록이 있으므로 분석만 읽으면 되는 연동에는 아무것도 만들거나 삭제할 수 없는 키를 발급할 수 있습니다. 키에는 만료일을 줄 수 있고 즉시 폐기할 수도 있으며, 각 키가 마지막으로 사용된 시각이 표시됩니다. 아무도 기억하지 못하는 연동을 찾아내는 방법이 바로 이것입니다.
- POST /links, GET /links, GET /links/{id}, PATCH /links/{id}, DELETE /links/{id}
- POST /links/bulk — 호출 한 번에 최대 100개 링크
- GET /links/{id}/qr — 프리셋과 크기를 지정한 PNG 또는 SVG
- GET /analytics/summary, /timeseries, /breakdown, /links/top, /export.csv
- GET 및 POST /domains — 도메인을 연결하고 필요한 DNS 레코드를 확인
- GET /workspace — 요금제 한도와 현재 사용량
- GET /partner/clients, /partner/plans, /partner/payments, /partner/payouts
새벽 3시에 중요한 방식으로 예측 가능합니다
모든 오류는 코드, 사람이 읽을 수 있는 메시지, 문서 URL이라는 같은 형태를 갖습니다. 그래서 클라이언트 라이브러리는 코드로 분기하고 사람은 메시지를 읽습니다. 목록은 페이지 번호가 아니라 커서로 페이지네이션되므로, 그 아래에서 링크가 계속 만들어지는 동안에도 결과가 안정적으로 유지됩니다.
요청 제한은 기본적으로 워크스페이스 키에 분당 600건, 파트너 키에 그 두 배이며, 한도와 남은 횟수, 초기화 시각이 모든 응답에 헤더로 돌아옵니다. 한도를 넘으면 연결이 끊기는 대신 Retry-After 헤더와 함께 429를 반환하므로, 예의 바른 클라이언트는 올바르게 물러설 수 있습니다. 분석 내보내기는 스트리밍으로 처리되므로 100,000행을 양쪽 어디에서도 메모리에 통째로 들고 있을 필요가 없습니다.
따로 폴링해야 했을 이벤트를 위한 웹훅
엔드포인트를 등록하면 링크 생성과 수정, 삭제를 받고, 호스트명이 SSL 대기에서 활성 또는 오류 상태로 옮겨 가는 도메인 수명주기 이벤트를 받으며, 파트너 키에서는 고객 구독과 결제 이벤트까지 받습니다. 도메인 상태 엔드포인트를 1분마다 폴링하는 코드야말로 아무도 작성하지 않아야 할 종류의 코드입니다.
모든 전송에는 타임스탬프가 포함된 HMAC-SHA256 서명 헤더가 붙으므로, 수신 쪽에서 페이로드가 저희에게서 왔고 재전송이 아님을 확인할 수 있습니다. 실패한 전송은 1분, 5분, 30분, 2시간, 12시간으로 간격을 늘려 가며 다섯 번 재시도하고, 그 뒤에는 엔드포인트를 실패 상태로 표시하고 이메일을 보냅니다. 대시보드에서 테스트 이벤트를 보낼 수 있으므로, 실제 업무가 의존하기 전에 연동을 검증할 수 있습니다.
실제로 동작하는 코드에서 생성되는 문서
OpenAPI 명세는 API가 검증에 사용하는 것과 같은 스키마에서 만들어집니다. 그래서 손으로 쓴 레퍼런스처럼 구현과 어긋날 수 없습니다. 명세는 클라이언트 생성기에 넣을 수 있는 파일로 공개되고, 이 사이트에서 탐색 가능한 레퍼런스 문서로도 렌더링되며, 빠른 시작과 페이지네이션, 오류, 웹훅, 요청 제한을 다루는 안내서가 함께 제공됩니다.
버전 1은 고정되어 있습니다. 필드는 추가될 수 있지만 기존 동작은 바뀌지 않으며, 호출자를 깨뜨릴 만한 변경은 다른 경로의 버전 2를 기다립니다. 단축 서비스를 그냥 쓰려는 것이 아니라 그 위에 무언가를 만들려고 고르는 중이라면, 이 약속이 개별 엔드포인트보다 더 값집니다.
설명이 필요 없는 코드
curl -X POST https://api.linkprofit.com/v1/links \
-H 'Authorization: Bearer lp_live_XXXXXXXX' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/spring-collection",
"domain_id": "dom_8kq2vn41",
"slug": "spring",
"title": "Spring collection",
"utm": {
"utm_source": "newsletter",
"utm_medium": "email",
"utm_campaign": "spring-2026"
}
}'const response = await fetch("https://api.linkprofit.com/v1/links", {
method: "POST",
headers: {
Authorization: "Bearer lp_live_XXXXXXXX",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/spring-collection",
domain_id: "dom_8kq2vn41",
slug: "spring",
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(error.code + ": " + error.message);
}
const link = await response.json();
console.log(link, response.headers.get("X-RateLimit-Remaining"));import requests
response = requests.post(
"https://api.linkprofit.com/v1/links",
headers={"Authorization": "Bearer lp_live_XXXXXXXX"},
json={
"url": "https://example.com/spring-collection",
"domain_id": "dom_8kq2vn41",
"slug": "spring",
},
timeout=10,
)
if response.status_code == 429:
raise SystemExit("rate limited, retry after " + response.headers["Retry-After"])
response.raise_for_status()
print(response.json())자주 묻는 질문
어떤 요금제에 API 접근이 포함됩니까?
파트너의 경우 API 접근은 Growth 요금제부터 시작하며 그 위의 모든 요금제에 포함됩니다. 여러분의 고객에게는 여러분이 정합니다. API 접근은 여러분이 만드는 각 요금제의 스위치 가운데 하나이므로, 서비스의 상위 등급으로 둘 수도 있고 모든 등급에 포함할 수도 있습니다.
API를 제 호스트명에서 제공할 수 있습니까?
버전 1에서는 불가능합니다. API는 api.linkprofit.com에서 제공되며, 파트너는 이를 자기 서비스의 API로 고객에게 안내합니다. 고객이 브라우저에서 보는 대시보드와 링크, 이메일, 결제는 모두 여러분의 도메인에 있습니다. API 호스트명은 그 유일하고 솔직한 예외입니다.
테스트용 샌드박스가 있습니까?
전용 워크스페이스와 그 워크스페이스로 범위를 좁힌 키를 사용하십시오. 거기서 만든 링크는 실제 도메인에서 연결되고 실제 분석을 만들어 냅니다. 리디렉션과 타기팅, 웹훅이 문서대로 동작하는지 확인할 때는 모의 환경보다 이 편이 유용합니다.