API 레퍼런스
Bearer 키로 상태 이벤트를 전송하고 현재 상태와 열린 문제 항목을 조회하는 API입니다.
SDK 없이 Authorization: Bearer <keyId>.<secret> 헤더를 사용합니다. 키는 환경 변수나 secret manager에 보관하세요.
Method | Path | Scope |
|---|---|---|
|
|
|
|
|
|
|
|
|
조회 시 status:read 키는 자기 프로젝트에 고정됩니다. 다른 projectSlug를 지정하면 403 project_forbidden입니다. admin:read 키는 projectSlug를 생략하면 조직 전체를 조회합니다. 없는·삭제된·다른 조직 프로젝트는 존재 여부를 숨기기 위해 200과 빈 목록을 반환합니다.
Bearer 인증 후 CRM이 호출자의 검증된 secret으로 HMAC을 재서명하여 내부 ingest에 전달합니다. 이벤트 검증·저장·프로젝트 권한·rate limit은 ingest가 처리하며 상태 코드와 JSON 응답, Retry-After를 그대로 반환합니다. 요청 본문은 최대 64 KB입니다.
curl -X POST https://crm.theseeker.io/api/v1/status/events \
-H "Authorization: Bearer $THESEEKER_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"slug":"checkout-api","result":"ok","latencyMs":123,"message":"ready","metrics":{"queueDepth":2}}'curl -X POST https://crm.theseeker.io/api/v1/status/events \
-H "Authorization: Bearer $THESEEKER_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"slug":"checkout-api","events":[{"result":"ok","latencyMs":123},{"result":"degraded","message":"slow upstream"}]}'배치는 최상위 slug가 필수이며 모든 항목은 같은 모니터에 기록됩니다. events[].slug로 모니터를 나누지 않습니다. events는 1..1000개이며 64 KB 제한도 동시에 적용됩니다. SDK의 reportMany wire payload를 그대로 복사하지 말고 위처럼 최상위 slug를 지정하세요.
필드 | 계약 |
|---|---|
| 프로젝트 내 모니터 slug. 단건·배치 모두 최상위 필수 |
| 각 이벤트 필수: |
| 선택. 0..2147483647 정수 |
| 선택. 오류·상태 설명 문자열 |
| 선택. JSON 객체 |
| 배치에서만 사용하는 이벤트 배열 |
slug, result, latencyMs, message, metrics는 SDK의 toWireEvent 필드입니다. ingest 직접 payload는 추가로 이벤트 시간 time, timestamp, checkedAt 중 하나를 ISO 문자열로 받을 수 있습니다(우선순위도 이 순서). SDK 이벤트 필드가 아니며, 생략하면 수신 시각입니다. 과거 24시간·미래 2분 범위를 벗어나면 거부됩니다. 서명 헤더 X-Timestamp와는 별개입니다.
성공 응답 예:
{"accepted":true,"replay":false,"inserted":1}코드 | 의미 |
|---|---|
| 이벤트 접수. 동일 HMAC nonce 재전송이면 |
| 잘못된 JSON·이벤트·시간·필수 slug 누락 |
| Bearer 인증 실패 또는 ingest 인증 실패 |
| scope·프로젝트·IP 접근 권한 부족 |
|
|
| 64 KB 초과 또는 이벤트 개수 제한 초과 |
| rate limit·예산 초과. |
|
|
CRM 자체 오류는 { "error": { "code": "...", "message": "..." } } 형태이며 ingest 오류 JSON은 원본 그대로 전달됩니다. Bearer 요청은 매번 새 nonce를 생성하므로 동일 본문의 재호출이 자동 dedupe되지는 않습니다. timeout 후 재시도는 중복 기록 가능성을 고려하세요.
curl 'https://crm.theseeker.io/api/v1/status?projectSlug=payments' \
-H "Authorization: Bearer $THESEEKER_API_KEY"{
"generatedAt": "2026-10-05T00:10:00.000Z",
"overall": "degraded",
"monitors": [{
"id": "monitor-id", "slug": "checkout-api", "name": "Checkout API",
"projectSlug": "payments", "state": "degraded",
"lastReceivedAt": "2026-10-05T00:09:00.000Z", "lastResult": "error", "lastLatencyMs": 123
}]
}overall은 maintenance·unknown을 제외한 최악 상태(down > degraded > up)입니다. 모니터가 없거나 순위를 정할 상태가 없으면 unknown입니다. 상태 행이 없으면 모니터 state는 unknown, 최신 이벤트 필드는 null입니다.
curl 'https://crm.theseeker.io/api/v1/status/issues?projectSlug=payments&minOpenSec=600&limit=50' \
-H "Authorization: Bearer $THESEEKER_API_KEY"Query | 기본값 | 계약 |
|---|---|---|
| 키 범위 | 선택. 조회할 프로젝트 |
|
| 0..86400 정수. 열린 기간이 이 값 이상인 인시던트만 조회 |
|
| 1..100 정수. 반환할 최대 항목 수 |
잘못된 정수·범위는 400 VALIDATION입니다. 해결되지 않은 인시던트 중 미삭제 모니터·프로젝트만 조회하고, 시작 시각 오름차순으로 반환합니다. count는 전체 일치 건수가 아니라 이번 응답의 항목 수입니다.
{
"generatedAt": "2026-10-05T00:10:00.000Z",
"count": 1,
"issues": [{
"id": "incident-id",
"monitor": {"id":"monitor-id","slug":"checkout-api","name":"Checkout API","projectSlug":"payments"},
"state": "down", "peakState": "down", "severity": null,
"incidentStatus": "investigating", "title": null, "isManual": false,
"startedAt": "2026-10-05T00:00:00.000Z", "openSec": 600,
"lastReceivedAt": "2026-10-05T00:09:00.000Z", "lastResult": "error", "consecutiveFail": 4,
"lastError": {"time":"2026-10-05T00:09:00.000Z","result":"error","message":"upstream timed out"}
}]
}lastError는 해당 모니터의 최근 7일 내 마지막 ok가 아닌 이벤트이며 없으면 null입니다. 수동 인시던트도 포함되고, 자동 인시던트의 비어 있는 상태는 investigating으로 표시됩니다.
이 API는 agent-task polling을 위해 설계되었습니다. minOpenSec로 일시 오류를 거르고, issue id = incident id로 dedupe하세요. 같은 인시던트는 한 번만 처리하고, 같은 모니터의 실행 중 작업도 중복 실행하지 않는 것이 좋습니다. 실제 수정 전에 다시 조회해 자연 회복 여부를 확인하세요. MCP list_status_issues도 같은 { generatedAt, count, issues }를 반환합니다(projectSlug?, projectId?, minOpenSec?, limit?).
Bearer 대신 ingest endpoint의 /v1/events로 직접 보내려면 같은 프로젝트 키의 keyId·secret으로 서명합니다. CRM /api/v1/status/events에는 이 HMAC 헤더가 필요하지 않습니다.
서명 문자열은 아래 항목을 구분자·개행 없이 이어 붙입니다.
UPPERCASE_METHOD + PATH + TIMESTAMP + NONCE + SHA256_HEX(RAW_BODY)PATH는 /v1/events(query 제외), timestamp는 SDK와 동일하게 Unix 밀리초(ingest는 Unix 초도 허용), nonce는 요청마다 새 UUID입니다. 본문 SHA-256과 최종 HMAC-SHA256은 hex 인코딩입니다. timestamp는 서버 시각 ±300초 이내여야 합니다. 서명한 raw body 바이트 그대로 전송하세요.
BODY='{"slug":"checkout-api","result":"ok","latencyMs":123}'
TIMESTAMP="$(node -p 'Date.now()')"
NONCE="$(uuidgen)"
BODY_HASH="$(printf '%s' "$BODY" | openssl dgst -sha256 -r | cut -d ' ' -f 1)"
SIGNING="POST/v1/events${TIMESTAMP}${NONCE}${BODY_HASH}"
SIGNATURE="$(printf '%s' "$SIGNING" | openssl dgst -sha256 -hmac "$STATUS_SECRET" -r | cut -d ' ' -f 1)"
curl -X POST "${INGEST_URL}/v1/events" \
-H 'Content-Type: application/json' \
-H "X-Ingest-Key-Id: $STATUS_KEY_ID" \
-H "X-Timestamp: $TIMESTAMP" -H "X-Nonce: $NONCE" \
-H "X-Signature: $SIGNATURE" --data-binary "$BODY"INGEST_URL, STATUS_KEY_ID, STATUS_SECRET는 미리 환경 변수로 설정합니다. 예제를 실행할 때 셸 tracing(set -x)을 끄고 secret·서명·인증 헤더를 로그에 남기지 마세요. 같은 논리 요청을 재전송할 때만 timestamp·nonce·서명·본문을 재사용하면 ingest의 replay 보호를 활용할 수 있습니다.
이 페이지가 도움이 되었나요?