Cursor API 개요
Cursor는 팀의 데이터, AI 기반 코딩 에이전트, 분석에 프로그래밍 방식으로 접근할 수 있는 여러 API를 제공합니다.
사용 가능한 API
| API | 설명 | 사용 가능 여부 |
|---|---|---|
| Admin API | 팀 구성원, 설정, 사용량 데이터, 지출 및 모델 액세스를 관리합니다. 맞춤형 대시보드와 모니터링 도구를 구축할 수 있습니다. | 엔터프라이즈 팀 |
| Analytics API | 팀의 Cursor 사용량, AI 지표, 활성 사용자, 모델 사용량에 대한 종합적인 인사이트를 제공합니다. | 엔터프라이즈 팀 |
| AI Code Tracking API | 기여도 파악과 분석을 위해 커밋 및 변경 단위로 AI 생성 코드 기여를 추적합니다. | 엔터프라이즈 팀 |
| Bugbot API | Bugbot 리뷰를 트리거하고 리뷰별 분석 데이터를 가져옵니다. | 엔터프라이즈 팀 |
| Cloud Agents API | 자동화된 워크플로와 코드 생성을 위한 AI 기반 코딩 에이전트를 프로그래밍 방식으로 생성하고 관리합니다. | 베타(모든 플랜) |
| Origin API | Origin 리포지토리, 커밋, 검사, 풀 리퀘스트 및 앱 설치를 다룹니다. | 알파 |
| TypeScript SDK | 단일 인터페이스로 TypeScript에서 로컬 및 클라우드 런타임의 Cursor 에이전트를 실행합니다. | 모든 사용자 |
| Python SDK | 로컬 및 클라우드 런타임용 동기 및 비동기 클라이언트를 통해 Python에서 Cursor 에이전트를 실행합니다. | 모든 사용자 |
| SDK Bridge | 개방형 브리지 프로토콜과 독립 실행형 바이너리를 기반으로 다른 언어용 에이전트 SDK를 구축합니다. | 모든 사용자 |
Cloud Agents API와 SDK는 Cursor 에이전트 워크플로(워크스페이스 컨텍스트, 도구, 명령어 및 편집)를 실행합니다. 독립형 모델 추론 또는 채팅 완성 API가 아닙니다. Auto / auto-smart를 사용하면 Cursor Router가 해당 에이전트 실행에 사용할 모델을 선택합니다. TypeScript SDK의 Router 또는 Python SDK를 참조하세요.
인증
모든 Cursor API는 기본 인증을 지원합니다. Cloud Agents API는 Bearer 토큰도 지원하므로 HTTP 클라이언트에서 더 쉽게 사용할 수 있는 방식을 선택하세요.
기본 인증
기본 인증 시 API 키를 사용자 이름으로 사용하고 비밀번호는 비워 두세요:
curl https://api.cursor.com/teams/members \ -u YOUR_API_KEY:또는 Authorization 헤더를 직접 설정하세요:
Authorization: Basic {base64_encode('YOUR_API_KEY:')}Bearer 인증 (Cloud Agents API)
Cloud Agents API는 Authorization: Bearer <key> 헤더도 지원합니다. 두 방식은 동일하게 동작하므로 HTTP 클라이언트에서 사용하기 편한 방식을 선택하세요:
curl https://api.cursor.com/v1/me \ -H "Authorization: Bearer YOUR_API_KEY"API 키 생성
팀 관리자는 대시보드의 API 키 페이지에서 API 키를 생성하고 관리할 수 있습니다.
Admin API & AI Code Tracking API
- cursor.com/dashboard → API Keys로 이동합니다
- New API Key를 클릭합니다
- 키를 알아보기 쉬운 이름으로 지정합니다(예: "Usage Dashboard Integration")
- 생성된 키를 즉시 복사합니다. 이후에는 다시 볼 수 없습니다
키 형식: crsr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
필수 범위: admin:*
Analytics API
Cursor Dashboard → API Keys에서 API 키를 생성합니다.
Cloud Agents API
Cursor Dashboard → API Keys에서 사용자 API 키를 생성하거나 팀 설정의 서비스 계정 API 키를 사용하세요.
API 키는 조직에 연결되며 모든 관리자가 볼 수 있습니다. 원래 생성자의 계정 상태는 키에 영향을 주지 않습니다.
요청 한도
모든 API에는 공정한 사용과 시스템 안정성을 위해 요청 제한이 적용됩니다. 요청 한도는 팀별로 적용되며 매분 재설정됩니다.
API별 요청 한도
| API | 엔드포인트 유형 | 요청 한도 |
|---|---|---|
| Admin API | 대부분의 엔드포인트 | 분당 20회 요청 |
| Admin API | /teams/filtered-usage-events 및 /organizations/filtered-usage-events | 분당 60회 요청 |
| Admin API | /teams/user-spend-limit | 분당 250회 요청 |
| Analytics API | 대부분의 팀 단위 엔드포인트 | 분당 100회 요청 |
| Analytics API | /analytics/team/conversation-insights | 분당 20회 요청 |
| Analytics API | 사용자별 엔드포인트 | 분당 50회 요청 |
| AI Code Tracking API | 전체 엔드포인트 | 엔드포인트당 분당 20회 요청 |
| Bugbot API | /bugbot/review | 분당 30회 요청 |
| Bugbot API | dryRun: true가 적용된 /bugbot/review | 분당 10회 요청(트리거 한도와 별도) |
| Cloud Agents API | 전체 엔드포인트 | 표준 요청 제한 |
요청 제한 응답
요청 제한을 초과하면 429 Too Many Requests 응답이 반환됩니다:
{ "error": "Too Many Requests", "message": "Rate limit exceeded. Please try again later."}캐싱
여러 API는 ETag를 활용한 HTTP 캐싱을 지원하여 대역폭 사용량을 줄이고 성능을 향상합니다.
지원되는 API
- Analytics API: 모든 엔드포인트(팀 단위 및 사용자별)에서 HTTP 캐싱을 지원합니다
- AI Code Tracking API: 엔드포인트에서 HTTP 캐싱을 지원합니다
캐싱 작동 방식
- 초기 요청: 지원되는 엔드포인트 중 하나에 요청을 보냅니다
- 응답에 ETag 포함: API가 응답 헤더에
ETag를 반환합니다 - 후속 요청:
If-None-Match헤더에ETag값을 포함합니다 - 304 Not Modified: 데이터가 변경되지 않은 경우 본문 없이
304 Not Modified응답을 받습니다
예시
# 최초 요청curl -X GET "https://api.cursor.com/analytics/team/dau" \ -H "Authorization: Bearer YOUR_API_KEY" \ -D headers.txt# 응답에 포함: ETag: "abc123xyz"# ETag를 포함한 후속 요청curl -X GET "https://api.cursor.com/analytics/team/dau" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "If-None-Match: \"abc123xyz\""# 데이터가 변경되지 않았으면 304 Not Modified 반환캐시 유효 기간
- 캐시 유효 기간: 15분 (
Cache-Control: public, max-age=900) - 응답에는
ETag헤더가 포함됩니다 - 데이터가 변경되지 않은 경우
304 Not Modified를 받으려면 이후 요청에If-None-Match헤더를 포함하세요
이점
- 대역폭 사용량 감소: 304 응답에는 본문이 포함되지 않습니다
- 더 빠른 응답: 변경되지 않은 데이터를 처리하지 않아도 됩니다
- 요청 제한에 유리: 304 응답은 요청 제한에 포함되지 않습니다
- 성능 향상: 특히 자주 폴링되는 엔드포인트에 유용합니다
모범 사례
1. 지수 백오프 구현
429 응답을 받으면 재시도 전 대기 시간을 점차 늘리세요:
import timeimport requestsdef make_request_with_backoff(url, headers, max_retries=5): for attempt in range(max_retries): response = requests.get(url, headers=headers) if response.status_code == 429: # 지수 백오프: 1초, 2초, 4초, 8초, 16초 wait_time = 2 ** attempt print(f"Rate limited. Waiting {wait_time}s before retry...") time.sleep(wait_time) continue return response raise Exception("Max retries exceeded")2. 시간에 따라 요청 분산하기
짧은 시간에 요청을 몰아서 보내기보다 API 호출을 시간에 걸쳐 분산하세요:
- 배치 작업이 서로 다른 간격으로 실행되도록 예약하세요
- 대규모 데이터 세트를 처리할 때 요청 사이에 지연 시간을 추가하세요
- 큐 시스템을 사용해 트래픽 급증을 완화하세요
3. 캐싱 활용
Analytics API 및 AI Code Tracking API:
이 API는 ETag를 통한 HTTP 캐싱을 지원합니다. ETag를 사용해 대역폭 사용량을 줄이고 불필요한 요청을 방지하는 방법은 위의 캐싱 섹션을 참조하세요.
주요 이점:
- 대역폭 사용량 감소
- 데이터가 변경되지 않았을 때 더 빠른 응답
- 요청 한도에 포함되지 않음(304 응답의 경우)
Analytics API에서 캐싱을 더 효과적으로 지원하려면 타임스탬프 대신 날짜 단축 표기(7d, 30d)를 사용하세요.
4. 사용량 모니터링
한도를 초과하지 않도록 요청 패턴을 추적하세요.
- API 호출 타임스탬프와 응답 코드 기록
- 429 응답 알림 설정
- 일일/주간 사용량 추세 모니터링
- 실제 필요에 따라 폴링 간격 조정
5. 배치 처리 활용하기
페이지네이션이 적용된 엔드포인트의 경우:
- 요청당 더 많은 데이터를 가져올 수 있도록 적절한 페이지 크기를 사용하세요
- Analytics API 사용자별 엔드포인트:
users파라미터를 사용해 특정 사용자를 필터링하세요 - 대량 데이터 추출: 가능한 경우 CSV 엔드포인트를 사용하세요(데이터를 효율적으로 스트리밍함)
6. 적절한 간격으로 폴링하기
업데이트 빈도가 낮은 엔드포인트를 과도하게 폴링하지 마세요:
- Admin API
/teams/daily-usage-data: 시간당 최대 한 번만 폴링하세요(데이터는 매시간 집계됨) - Admin API
/teams/filtered-usage-events: 시간당 최대 한 번만 폴링하세요(데이터는 매시간 집계됨) - Admin API
/organizations/pooled-usage: 시간당 최대 한 번만 폴링하세요(데이터는 매시간 집계됨) - Admin API
/organizations/filtered-usage-events: 시간당 최대 한 번만 폴링하세요(데이터는 매시간 집계됨) - Analytics API: 캐싱 지원을 개선하려면 날짜 단축 표기(
7d,30d)를 사용하세요 - AI Code Tracking API: 데이터는 거의 실시간으로 수집되지만, 몇 분 간격으로 폴링하면 충분합니다
7. 오류를 적절히 처리하기
모든 API 호출에 적절한 오류 처리를 구현하세요:
async function fetchAnalytics(endpoint) { try { const response = await fetch(`https://api.cursor.com${endpoint}`, { headers: { 'Authorization': `Basic ${btoa(API_KEY + ':')}` } }); if (response.status === 429) { // 요청 제한에 걸림 - 백오프 구현 throw new Error('Rate limit exceeded'); } if (response.status === 401) { // 유효하지 않은 API 키 throw new Error('Authentication failed'); } if (response.status === 403) { // 권한 부족 throw new Error('Enterprise access required'); } if (!response.ok) { throw new Error(`API error: ${response.status}`); } return await response.json(); } catch (error) { console.error('API request failed:', error); throw error; }}공통 오류 응답
모든 API는 표준 HTTP 상태 코드를 사용합니다:
400 잘못된 요청
요청 파라미터가 유효하지 않거나 필수 필드가 누락되었습니다.
{ "error": "Bad Request", "message": "Some users are not in the team"}401 Unauthorized
API 키가 유효하지 않거나 누락되었습니다.
{ "error": "Unauthorized", "message": "Invalid API key"}403 접근 금지
API 키는 유효하지만 권한이 부족합니다(예: 엔터프라이즈 요금제가 아닌 경우 엔터프라이즈 기능 사용).
{ "error": "Forbidden", "message": "Enterprise access required"}404 찾을 수 없음
요청한 리소스를 찾을 수 없습니다.
{ "error": "Not Found", "message": "Resource not found"}429 요청 과다
요청 제한을 초과했습니다. 지수 백오프를 구현하세요.
{ "error": "Too Many Requests", "message": "Rate limit exceeded. Please try again later."}500 내부 서버 오류
서버 측 오류입니다. 문제가 계속되면 지원팀에 문의하세요.
{ "error": "Internal Server Error", "message": "An unexpected error occurred"}