> For the complete documentation index, see [llms.txt](https://run.emailchaser.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://run.emailchaser.com/api-reference/replies.md).

# Replies

## Get a lead's conversation

> Returns the lead's full email thread in chronological order: outbound emails (sent, scheduled, and unsent drafts) and inbound replies. Each item carries direction (inbound/outbound), status, and, for categorized inbound emails, the AI response category. Unsent drafts - including AI-suggested replies awaiting human review - are marked with isDraft; they can be read and edited over REST but only a logged-in human can send one from the app.

```json
{"openapi":"3.1.1","info":{"title":"Emailchaser API","version":"1.0"},"servers":[{"url":"https://api.emailchaser.com/r"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"models.GetLeadConversationResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/models.ConversationItem"}},"leadId":{"type":"integer"},"total":{"type":"integer"}}},"models.ConversationItem":{"type":"object","properties":{"body":{"type":"string"},"campaignId":{"type":"integer"},"createdAt":{"type":"string"},"direction":{"description":"Direction is \"inbound\" (received from the prospect) or \"outbound\"\n(sent, scheduled, or drafted by the workspace).","type":"string"},"fromAddress":{"type":"string"},"id":{"type":"integer"},"isDraft":{"description":"IsDraft marks unsent drafts (status draft or followup_draft), including\nAI-suggested replies awaiting human review. Drafts cannot be sent\nthrough the REST API.","type":"boolean"},"responseCategory":{"description":"ResponseCategory is set on categorized inbound emails and null\neverywhere else.","type":"string"},"sentAt":{"description":"SentAt is the scheduled or actual send time and null when the email has\nnone (e.g. an AI draft that was never scheduled).","type":"string"},"status":{"type":"string"},"subject":{"type":"string"},"threadId":{"type":"string"}}},"models.ErrorInvalidLeadID":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorUnauthorized":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorNotFound":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}}}},"paths":{"/leads/{id}/conversation":{"get":{"description":"Returns the lead's full email thread in chronological order: outbound emails (sent, scheduled, and unsent drafts) and inbound replies. Each item carries direction (inbound/outbound), status, and, for categorized inbound emails, the AI response category. Unsent drafts - including AI-suggested replies awaiting human review - are marked with isDraft; they can be read and edited over REST but only a logged-in human can send one from the app.","tags":["Replies"],"summary":"Get a lead's conversation","parameters":[{"schema":{"type":"string"},"description":"Bearer <API_KEY>","name":"Authorization","in":"header","required":true},{"schema":{"type":"integer"},"description":"Lead ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"The lead's conversation thread","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.GetLeadConversationResponse"}}}},"400":{"description":"Invalid lead ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorInvalidLeadID"}}}},"401":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorUnauthorized"}}}},"404":{"description":"Lead not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorNotFound"}}}},"500":{"description":"Failed to retrieve conversation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}}}}}}}
```

## List replies

> Lists inbound emails (replies received from prospects) in the API key's workspace, newest first, 20 per page by default (?limit= up to 200). Filter by AI response category, campaign, lead, or a time floor. responseCategory is null while AI categorization is still pending; campaignId is null for standalone replies that could not be attributed to a campaign. Read-only: replying happens by editing the AI draft (PUT /reply-drafts/{id}) and sending it (POST /reply-drafts/{id}/send) - the draft's current subject and body are what goes out.

```json
{"openapi":"3.1.1","info":{"title":"Emailchaser API","version":"1.0"},"servers":[{"url":"https://api.emailchaser.com/r"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"models.ListRepliesResponse":{"type":"object","properties":{"hasMore":{"type":"boolean"},"limit":{"type":"integer"},"page":{"type":"integer"},"replies":{"type":"array","items":{"$ref":"#/components/schemas/models.ReplyItem"}},"total":{"type":"integer"}}},"models.ReplyItem":{"type":"object","properties":{"body":{"type":"string"},"campaignId":{"description":"CampaignID is null for standalone replies that could not be attributed\nto a campaign.","type":"integer"},"fromAddress":{"type":"string"},"id":{"type":"integer"},"leadId":{"type":"integer"},"receivedAt":{"type":"string"},"responseCategory":{"description":"ResponseCategory is null while AI categorization is still pending.","type":"string"},"subject":{"type":"string"},"threadId":{"type":"string"}}},"models.ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorUnauthorized":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorNotFound":{"type":"object","properties":{"error":{"type":"string"}}}}},"paths":{"/replies":{"get":{"description":"Lists inbound emails (replies received from prospects) in the API key's workspace, newest first, 20 per page by default (?limit= up to 200). Filter by AI response category, campaign, lead, or a time floor. responseCategory is null while AI categorization is still pending; campaignId is null for standalone replies that could not be attributed to a campaign. Read-only: replying happens by editing the AI draft (PUT /reply-drafts/{id}) and sending it (POST /reply-drafts/{id}/send) - the draft's current subject and body are what goes out.","tags":["Replies"],"summary":"List replies","parameters":[{"schema":{"type":"string"},"description":"Bearer <API_KEY>","name":"Authorization","in":"header","required":true},{"schema":{"type":"string"},"description":"Filter by response category (interested, not_interested, wrong_person, bounced, out_of_office, delivery_incomplete, dmarc_report, mixmax, warmup_email, unsubscribe)","name":"category","in":"query"},{"schema":{"type":"integer"},"description":"Filter by campaign ID","name":"campaignId","in":"query"},{"schema":{"type":"integer"},"description":"Filter by lead ID","name":"leadId","in":"query"},{"schema":{"type":"string"},"description":"Only replies received at or after this time (RFC3339 or YYYY-MM-DD)","name":"since","in":"query"},{"schema":{"type":"integer"},"description":"Page number (default: 1)","name":"page","in":"query"},{"schema":{"type":"integer"},"description":"Page size (default: 20, maximum: 200)","name":"limit","in":"query"}],"responses":{"200":{"description":"List of replies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ListRepliesResponse"}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorUnauthorized"}}}},"404":{"description":"Campaign or lead filter not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorNotFound"}}}},"500":{"description":"Failed to retrieve replies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}}}}}}}
```

## List AI reply drafts

> Lists AI-suggested reply drafts awaiting human review in the API key's workspace, newest first, 20 per page by default (?limit= up to 200). Each draft answers the inbound reply referenced by inReplyToEmailId. Drafts can be edited over REST (PUT /reply-drafts/{id}) and sent (POST /reply-drafts/{id}/send) - both require the read\_write scope.

```json
{"openapi":"3.1.1","info":{"title":"Emailchaser API","version":"1.0"},"servers":[{"url":"https://api.emailchaser.com/r"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"models.ListReplyDraftsResponse":{"type":"object","properties":{"drafts":{"type":"array","items":{"$ref":"#/components/schemas/models.ReplyDraftItem"}},"hasMore":{"type":"boolean"},"limit":{"type":"integer"},"page":{"type":"integer"},"total":{"type":"integer"}}},"models.ReplyDraftItem":{"type":"object","properties":{"body":{"type":"string"},"createdAt":{"type":"string"},"id":{"type":"integer"},"inReplyToEmailId":{"description":"InReplyToEmailID is the inbound reply this draft answers. It is null in\nthe rare case the draft's conversation can no longer be resolved (e.g.\nthe inbound email was deleted).","type":"integer"},"leadId":{"type":"integer"},"subject":{"type":"string"}}},"models.ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorUnauthorized":{"type":"object","properties":{"error":{"type":"string"}}}}},"paths":{"/reply-drafts":{"get":{"description":"Lists AI-suggested reply drafts awaiting human review in the API key's workspace, newest first, 20 per page by default (?limit= up to 200). Each draft answers the inbound reply referenced by inReplyToEmailId. Drafts can be edited over REST (PUT /reply-drafts/{id}) and sent (POST /reply-drafts/{id}/send) - both require the read_write scope.","tags":["Replies"],"summary":"List AI reply drafts","parameters":[{"schema":{"type":"string"},"description":"Bearer <API_KEY>","name":"Authorization","in":"header","required":true},{"schema":{"type":"integer"},"description":"Page number (default: 1)","name":"page","in":"query"},{"schema":{"type":"integer"},"description":"Page size (default: 20, maximum: 200)","name":"limit","in":"query"}],"responses":{"200":{"description":"List of AI reply drafts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ListReplyDraftsResponse"}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorUnauthorized"}}}},"500":{"description":"Failed to retrieve reply drafts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}}}}}}}
```

## Edit an AI reply draft

> Updates the subject and/or body of an AI reply draft awaiting human review. At least one field must be provided and provided fields must be non-empty. This endpoint never changes the draft's status or sends anything - use POST /reply-drafts/{id}/send once the wording is ready. Emails that are not AI reply drafts - sent or scheduled emails, inbound replies, campaign sequence templates - are refused with 409.

```json
{"openapi":"3.1.1","info":{"title":"Emailchaser API","version":"1.0"},"servers":[{"url":"https://api.emailchaser.com/r"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"models.ReplyDraftItem":{"type":"object","properties":{"body":{"type":"string"},"createdAt":{"type":"string"},"id":{"type":"integer"},"inReplyToEmailId":{"description":"InReplyToEmailID is the inbound reply this draft answers. It is null in\nthe rare case the draft's conversation can no longer be resolved (e.g.\nthe inbound email was deleted).","type":"integer"},"leadId":{"type":"integer"},"subject":{"type":"string"}}},"models.ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorUnauthorized":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorNotFound":{"type":"object","properties":{"error":{"type":"string"}}},"models.UpdateReplyDraftRequest":{"type":"object","properties":{"body":{"type":"string"},"subject":{"type":"string"}}}}},"paths":{"/reply-drafts/{id}":{"put":{"description":"Updates the subject and/or body of an AI reply draft awaiting human review. At least one field must be provided and provided fields must be non-empty. This endpoint never changes the draft's status or sends anything - use POST /reply-drafts/{id}/send once the wording is ready. Emails that are not AI reply drafts - sent or scheduled emails, inbound replies, campaign sequence templates - are refused with 409.","tags":["Replies"],"summary":"Edit an AI reply draft","parameters":[{"schema":{"type":"string"},"description":"Bearer <API_KEY>","name":"Authorization","in":"header","required":true},{"schema":{"type":"integer"},"description":"Reply draft ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"The updated reply draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ReplyDraftItem"}}}},"400":{"description":"Invalid draft ID or request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorUnauthorized"}}}},"404":{"description":"Reply draft not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorNotFound"}}}},"409":{"description":"Email exists but is not an editable AI reply draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"500":{"description":"Failed to update reply draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.UpdateReplyDraftRequest"}}},"description":"Fields to update","required":true}}}}}
```

## Send an AI reply draft

> Schedules an AI reply draft for delivery through the conversation's sender mailbox. The draft's current subject and body are what goes out, so edit first (PUT /reply-drafts/{id}) if needed. Emails that are not sendable AI reply drafts - already sent or scheduled emails, inbound replies, campaign sequence templates - are refused with 409. A draft whose conversation has no connected sender mailbox or no resolvable recipient is refused with 422.

```json
{"openapi":"3.1.1","info":{"title":"Emailchaser API","version":"1.0"},"servers":[{"url":"https://api.emailchaser.com/r"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"models.SendReplyDraftResponse":{"type":"object","properties":{"body":{"type":"string"},"id":{"type":"integer"},"leadId":{"type":"integer"},"recipient":{"type":"string"},"status":{"type":"string"},"subject":{"type":"string"}}},"models.ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorUnauthorized":{"type":"object","properties":{"error":{"type":"string"}}},"models.ErrorNotFound":{"type":"object","properties":{"error":{"type":"string"}}}}},"paths":{"/reply-drafts/{id}/send":{"post":{"description":"Schedules an AI reply draft for delivery through the conversation's sender mailbox. The draft's current subject and body are what goes out, so edit first (PUT /reply-drafts/{id}) if needed. Emails that are not sendable AI reply drafts - already sent or scheduled emails, inbound replies, campaign sequence templates - are refused with 409. A draft whose conversation has no connected sender mailbox or no resolvable recipient is refused with 422.","tags":["Replies"],"summary":"Send an AI reply draft","parameters":[{"schema":{"type":"string"},"description":"Bearer <API_KEY>","name":"Authorization","in":"header","required":true},{"schema":{"type":"integer"},"description":"Reply draft ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"The draft is scheduled for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.SendReplyDraftResponse"}}}},"400":{"description":"Invalid draft ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorUnauthorized"}}}},"404":{"description":"Reply draft not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorNotFound"}}}},"409":{"description":"Email exists but is not a sendable AI reply draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"422":{"description":"Draft cannot be delivered (no sender mailbox or no recipient)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}},"500":{"description":"Failed to send reply draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}}}}}}}}
```
