# REST API 시작하기

> 기본 URL, 토큰 인증, agent_id, 멱등 키, 커서, 오류 모양. 모든 API 페이지에 공통인 규칙입니다.

## 기본 URL

```text
https://api.atmark.ai
```

공개 신원 조회만 `https://id.atmark.ai`를 씁니다. [신원 조회](https://docs.atmark.ai/api/identity)

## 인증

모든 요청에 에이전트 토큰을 헤더로 보냅니다. 토큰을 쿼리 문자열이나 본문에 넣지 않습니다.

```http
Authorization: Bearer atk_agent_...
```

- 토큰이 없거나 틀리거나 폐기·만료됐으면 `401 unauthorized`입니다.
- 토큰에 그 권한이 없거나 다른 에이전트의 것을 요청하면 `403 forbidden`입니다.
- 조직 API 키(`atk_org_…`)는 여기서 쓸 수 없습니다. [조직 API 키](https://docs.atmark.ai/team/org-api-keys)

## agent_id

많은 요청이 `agent_id`(소문자 16진수 32자)를 본문이나 쿼리로 받습니다. 토큰의 에이전트 ID와 같아야 합니다. 에이전트 ID는 콘솔의 에이전트 개요나 **신원 › 식별자**에서 복사합니다.

## 멱등 키

메일을 보내는 요청과 예약을 만드는 요청에는 `Idempotency-Key` 헤더(1~255자)가 필요합니다. 없으면 `400 idempotency_key_required`입니다.

- 키는 에이전트마다 따로 셉니다. 정해진 만료는 없습니다. 메일 보내기·회신·전달은 같은 키 공간을 쓰고, 예약 만들기는 따로 셉니다.
- 같은 키로 같은 요청을 다시 보내면 메일이 또 나가지 않습니다. 대신 그 메일의 **지금 상태**를 `replayed: true`와 함께 돌려줍니다. [다시 보낸 요청의 응답](https://docs.atmark.ai/api/messages#replay)
- 같은 키로 다른 요청을 보내면 `409 idempotency_key_reused`입니다.
- 타임아웃, 네트워크 오류, `500`, `503` 뒤에는 잠시 기다렸다 **같은 키**로 다시 보냅니다. 이미 나갔다면 두 번 나가지 않습니다.
- `403 policy_denied`를 받은 키는 계속 거부로 남습니다. 원인을 고쳤거나 `retry_after_seconds`만큼 기다린 뒤에는 **새 키**로 보냅니다.

## 목록과 커서

목록은 `limit`과 `cursor`를 받고 `next_cursor`를 돌려줍니다. `next_cursor`가 `null`이면 끝입니다. 다음 쪽을 부를 때는 필터를 바꾸지 않습니다.

## 오류 모양

```json
{ "error": "invalid_request", "detail": "…" }
```

`error`만 코드에서 분기에 씁니다. `detail`은 사람이 읽는 영어 설명이라 문구가 바뀔 수 있습니다. 정책 거부(`403 policy_denied`)의 첫 응답에는 `detail` 대신 `message_id`와 `decision`이 옵니다. [메일 API](https://docs.atmark.ai/api/messages#results) 코드 목록은 [오류 코드](https://docs.atmark.ai/api/errors)에 있습니다.

## 시각

모든 시각은 ISO 8601 UTC 문자열입니다. 예: `2026-09-27T09:00:00.000Z`.

## 경로 목록

| 메서드 | 경로 | 문서 |
|---|---|---|
| `POST` | `/v1/messages` | [메일](https://docs.atmark.ai/api/messages) |
| `POST` | `/v1/threads/{threadId}/reply` | [메일](https://docs.atmark.ai/api/messages#reply) |
| `POST` | `/v1/messages/{messageId}/forward` | [메일](https://docs.atmark.ai/api/messages#forward) |
| `GET` | `/v1/messages/inbound` | [받은 메일](https://docs.atmark.ai/api/inbound) |
| `GET` | `/v1/messages/inbound/{messageId}` | [받은 메일](https://docs.atmark.ai/api/inbound#get) |
| `GET` | `/v1/messages/inbound/{messageId}/attachments/{index}` | [받은 메일](https://docs.atmark.ai/api/inbound#attachment) |
| `GET` | `/v1/threads/{threadId}` | [스레드](https://docs.atmark.ai/api/threads) |
| `GET` | `/v1/approvals/{approvalId}` | [승인](https://docs.atmark.ai/api/approvals) |
| `GET` | `/v1/agents/{agentId}/policy` | [정책](https://docs.atmark.ai/api/policy) |
| `POST` · `GET` | `/v1/messages/scheduled` | [예약](https://docs.atmark.ai/api/scheduled) |
| `GET` | `/v1/messages/scheduled/{scheduleId}` | [예약](https://docs.atmark.ai/api/scheduled#get) |
| `POST` | `/v1/messages/scheduled/{scheduleId}/cancel` | [예약](https://docs.atmark.ai/api/scheduled#cancel) |
| `GET` | `/v1/messages/verification-code` | [인증 코드](https://docs.atmark.ai/api/verification-code) |
| `GET` | `/v1/audit` | [감사 기록](https://docs.atmark.ai/api/audit) |
| `POST` · `GET` · `DELETE` | `/v1/agents/{agentId}/webhook-endpoints…` | [웹훅](https://docs.atmark.ai/api/webhooks) |
| `GET` · `POST` | `/v1/agents/{agentId}/webhook-deliveries…` | [웹훅](https://docs.atmark.ai/api/webhooks#deliveries) |
| `GET` | `https://id.atmark.ai/v1/identity/{address}` | [신원 조회](https://docs.atmark.ai/api/identity) |

---

원문: https://docs.atmark.ai/api/overview · 마지막 수정 2026-09-27
