모니터링·로그 API
Posmit의 발송은 발송 요청 → 큐 잡 → 전송 시도의 3단계로 기록됩니다.
POST /v1/notifications가 접수한 발송 요청(notification request)마다 큐 잡(job)이 만들어져 대기·처리·재시도를 거치고, 워커가 공급자를 호출할 때마다 전송 시도(dispatch attempt)가 1건씩 남습니다.
이 문서는 각 단계를 조회하는 API와 감사 로그·데드레터 큐 API를 다룹니다.
모든 엔드포인트는 대시보드 로그인 세션(JWT) Bearer 인증을 사용합니다. 토큰 발급은 대시보드 인증을 참고하세요. 대시보드 화면에서의 사용법은 가이드 › 운영 · 모니터링에서 설명합니다.
발송 지표
기간 내 발송 요청과 전송 시도를 집계합니다. (역할: owner / admin / operator / viewer)
| 파라미터 | 타입 | 설명 |
|---|---|---|
from | string | 선택. ISO 8601 일시. 생략 시 현재로부터 24시간 전 |
to | string | 선택. ISO 8601 일시. 생략 시 현재 시각 |
curl "https://api.posmit.io/v1/metrics?from=2026-07-10T00:00:00Z&to=2026-07-11T00:00:00Z" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"{
"from": "2026-07-10T00:00:00.000Z",
"to": "2026-07-11T00:00:00.000Z",
"totalRequests": 1250,
"byStatus": { "sent": 1180, "failed": 42, "queued": 28 },
"byChannel": { "email": 700, "sms": 350, "kakao_alimtalk": 200 },
"totalAttempts": 1298,
"successAttempts": 1180,
"failedAttempts": 118
}totalRequests/byStatus/byChannel은 기간 내 접수된 발송 요청 기준입니다.byStatus의 키는 요청 상태(queued/processing/sent/failed/canceled)입니다.totalAttempts/successAttempts/failedAttempts는 기간 내 시작된 전송 시도 기준입니다. 한 요청이 재시도·폴백으로 여러 번 시도될 수 있으므로 요청 수보다 클 수 있습니다.
발송 큐 잡
아직 끝나지 않은 발송 큐 잡 목록을 적재 시각 내림차순으로 조회합니다. (역할: owner / admin / operator / viewer)
쿼리 파라미터는 없으며, 종료되지 않은 상태의 잡만 반환합니다. 대시보드 화면의 검색어·채널·상태 필터는 이 응답을 화면에서 걸러 보여 주는 것입니다.
| 상태 | 의미 |
|---|---|
scheduled | 예약 발송 대기 (미래 시각) |
queued | 큐 적재 완료, 처리 대기 |
processing | 워커가 처리 중 |
retrying | 실패 후 백오프 재시도 대기 |
dead_letter | 최대 재시도 초과 (데드레터 큐) |
completed / failed / canceled로 종료된 잡은 목록에서 제외됩니다.
종료된 발송의 결과는 전송 시도 이력으로 조회합니다.
{
"jobs": [
{
"id": "…",
"notificationRequestId": "…",
"channel": "sms",
"templateCode": "order-shipped",
"recipient": "01012345678",
"status": "retrying",
"scheduledAt": null,
"enqueuedAt": "2026-07-11T09:00:00.000Z",
"attemptCount": 2,
"maxAttempts": 5,
"nextRetryAt": "2026-07-11T09:04:00.000Z",
"providerKind": "aligo_sms",
"providerDisplayName": "알리고 SMS",
"lastError": { "code": "dispatch_error", "message": "provider timeout" }
}
]
}attemptCount는 지금까지 수행한 시도 횟수, maxAttempts는 최대 시도 횟수입니다.
nextRetryAt은 retrying 상태에서 다음 재시도 예정 시각이며, lastError는 마지막 실패 원인입니다(실패 이력이 없으면 null).
예약된 발송 잡을 취소합니다. (역할: owner / admin / operator)
scheduled 상태의 잡만 취소할 수 있습니다.
이미 큐에 적재되었거나 처리 중인 잡을 취소하려 하면 409 Conflict가 반환됩니다.
성공 시 잡과 발송 요청이 모두 canceled로 바뀌고 204 No Content가 반환됩니다.
잡이 없으면 404입니다.
curl -X POST https://api.posmit.io/v1/jobs/JOB_ID/cancel \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"전송 시도 이력
공급자 호출 1건마다 남는 전송 시도 이력을 최신순으로 조회합니다. (역할: owner / admin / operator / viewer)
| 파라미터 | 타입 | 설명 |
|---|---|---|
requestId | UUID | 선택. 특정 발송 요청의 시도만 조회 |
limit | int | 선택. 1 ~ 500, 기본 100 |
cursor | string | 선택. 이전 응답의 cursor 값 (커서 페이지네이션) |
{
"attempts": [
{
"id": "…",
"notificationRequestId": "…",
"notificationJobId": "…",
"providerAccountId": "…",
"providerKind": "resend_email",
"providerDisplayName": "Resend",
"channel": "email",
"status": "success",
"failureCode": null,
"failureMessage": null,
"providerMessageId": "re_abc123",
"startedAt": "2026-07-11T09:00:00.000Z",
"finishedAt": "2026-07-11T09:00:01.200Z",
"request": {
"templateCode": "welcome",
"recipient": "user@example.com",
"variables": { "name": "홍길동" },
"renderedContent": { "title": "환영합니다", "html": "<p>…</p>" }
},
"response": { "httpStatus": 200, "durationMs": 850, "body": { "id": "re_abc123" } }
}
],
"cursor": null,
"hasNext": false
}status는success또는failure이며, 실패 시failureCode/failureMessage에 원인이 담깁니다.request.renderedContent에는 템플릿 변수가 치환된 실제 발송 본문(title/text/html)이 포함됩니다.response에는 공급자의 원문 응답(HTTP 상태, 소요 시간, 응답 본문·헤더)이 그대로 보존됩니다.hasNext가true이면 응답의cursor를 다음 요청의cursor파라미터로 전달해 이어서 조회합니다.
감사 로그
워크스페이스의 설정 변경 이력을 최신순으로 조회합니다. (역할: owner / admin / operator / viewer)
| 파라미터 | 타입 | 설명 |
|---|---|---|
action | string | 선택. 특정 액션만 조회 (예: api_key.rotate) |
targetType | string | 선택. 대상 리소스 타입으로 필터 |
limit | int | 선택. 1 ~ 200, 기본 100 |
cursor | string | 선택. 이전 응답의 cursor 값 |
{
"logs": [
{
"id": "…",
"actorUserId": "…",
"action": "api_key.rotate",
"targetType": "api_key_credential",
"targetId": "…",
"payload": { "name": "production" },
"createdAt": "2026-07-11T09:00:00.000Z"
}
],
"cursor": null,
"hasNext": false
}actorUserId는 작업을 수행한 대시보드 사용자이며, null이면 사용자 없이 시스템이 수행한 동작입니다.
액션 종류
| 분류 | 액션 |
|---|---|
| 워크스페이스 | workspace.updated |
| 공급자 | provider.create, provider.test_send |
| 라우팅 | route.replace |
| API 키 | api_key.create, api_key.update, api_key.rotate, api_key.revoke, api_key.suspend, api_key.resume |
| 템플릿 | template.create, template.version.create, template.version.publish |
| 웹훅 | webhook.create, webhook.update, webhook.delete, webhook.rotate_secret |
| 레이트리밋 | rate_limit.workspace.upsert, rate_limit.api_key.upsert |
| SES 연동 | ses.email_identity.verify, ses.domain.connect, ses.domain.adopt, ses.callback_secret.rotate, ses.callback_secret.finalize |
데드레터 큐
최대 재시도 횟수를 넘겨 데드레터 큐(DLQ)로 이동한 실패 잡을 조회합니다. (역할: owner / admin)
쿼리 파라미터는 없으며, items에는 최근 100건이 최신순으로 담기고 count는 DLQ 전체 건수입니다.
{
"items": [
{
"jobId": "1024",
"jobName": "dispatch-notification",
"data": {
"notificationRequestId": "…",
"workspaceId": "…",
"channel": "email"
},
"failedReason": "provider timeout",
"failedAt": "2026-07-11T08:55:00.000Z",
"attemptsMade": 5
}
],
"count": 3
}DLQ는 Redis에 최근 10,000건까지 보관되며, 초과분은 오래된 항목부터 잘려 나갑니다.
DLQ로 이동한 잡은 발송 큐 잡 목록에서 dead_letter 상태로도 확인할 수 있습니다.