Draft reply API
The draft reply API lets the tools you already use for support ask Yamidoo for an answer. Send the customer’s message, get back a reply drafted the way the widget would answer it. Nothing is sent to the customer: you decide what to do with the draft, whether that’s pasting it into Help Scout, showing it to an agent, or sending it from your own code.
Available on the Plus and Pro plans. Each request counts as one conversation, the same as a chat.
Get an API key
Section titled “Get an API key”In the dashboard open your project → Integrations → API and click Create key. The key is shown once; store it somewhere safe. A site can have up to 5 active keys, and you can revoke any of them at any time.
Keys belong to a site and draft from that site’s content, settings and instructions.
Request
Section titled “Request”POST https://app.yamidoo.ai/api/v1/draftAuthorization: Bearer yk_live_…Content-Type: application/json| Field | Type | Description |
|---|---|---|
message |
string | Required. The customer’s latest message, the one to reply to. Up to 12,000 characters. |
subject |
string | The email subject, if there is one. Gives the draft context. |
history |
array | Earlier turns of the thread, oldest first, as { "role": "customer" | "agent", "content": "…" }. Up to 20. |
customer.name |
string | The customer’s name. Used sparingly in the draft. |
customer.email |
string | The customer’s email. With a store connected under Integrations → Customer data, and the AI switch on, the draft can use their orders, licenses and subscriptions. |
curl https://app.yamidoo.ai/api/v1/draft \ -H "Authorization: Bearer yk_live_…" \ -H "Content-Type: application/json" \ -d '{ "subject": "License question", "message": "Hi, when does my license expire and can I still get updates?", "customer": { "name": "Jane", "email": "jane@example.com" } }'Response
Section titled “Response”{ "needs_reply": true, "skip_reason": null, "draft": "Hi Jane,\n\nYour Inspiro license runs until 14 March 2027, so you'll keep getting updates until then. …\n\nBest regards,\nThe WPZOOM team", "sources": [ { "title": "License renewals – WPZOOM", "url": "https://www.wpzoom.com/docs/renewals/" } ], "grounded": true, "confidence": 0.82, "needs_human": false, "customer_data_used": true, "model": "claude-sonnet-5"}| Field | Description |
|---|---|
needs_reply |
false when the message should not get a reply: a bounce notice, an auto-reply, a newsletter, a system notification or spam. draft is empty then and skip_reason says why. |
skip_reason |
A few words on why no reply was drafted, or null. |
draft |
Empty when needs_reply is false. Otherwise the reply, written as a complete email: a greeting (Hi Jane, or Hi there,), the answer, and Best regards, signed with your site name. First person as your team, light Markdown (bold, lists, links). |
sources |
The pages the draft was answered from. Show them to the agent, or leave them out of the reply. |
grounded |
true when relevant content was found. false means the draft could not be answered from your site. |
confidence |
How well your content matched the question, from 0 to 1. |
needs_human |
true when the draft isn’t grounded or confidence is low. Treat these as “read before sending”. |
customer_data_used |
true when the customer’s account data was included. |
model |
The model that wrote the draft. Depends on your plan. |
The draft follows the same rules as the widget: it answers from your content, quotes prices and figures exactly, and says when it doesn’t have the answer rather than guessing. Custom instructions under Settings → Behavior apply here too.
Errors
Section titled “Errors”| Status | Meaning |
|---|---|
400 |
The body is missing message or a field is invalid. The response names the field. |
401 |
Missing, invalid or revoked API key. |
402 |
The plan’s monthly conversation limit is reached. |
403 |
The site’s plan doesn’t include the API. |
429 |
More than 60 requests in a minute with this key. Retry after a minute. |
503 |
Drafting is temporarily unavailable. Retry. |
Limits
Section titled “Limits”- 60 requests per minute per key.
- Each request counts as one conversation against the plan, the same as a chat.
- A request takes a few seconds, since the reply is written on the spot. There is no streaming; the full draft comes back in one response.
Example: a Help Scout draft
Section titled “Example: a Help Scout draft”Using Help Scout? The built-in Help Scout integration does this for you, with no code. The script below is for when you want to run it yourself.
A small script that runs when a new conversation arrives, drafts a reply and saves it as a note so the agent sees it before replying:
const res = await fetch('https://app.yamidoo.ai/api/v1/draft', { method: 'POST', headers: { Authorization: `Bearer ${process.env.YAMIDOO_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ subject: conversation.subject, message: latestCustomerMessage.text, history: earlierThreads.map((t) => ({ role: t.createdBy.type === 'customer' ? 'customer' : 'agent', content: t.text, })), customer: { name: conversation.customer.firstName, email: conversation.customer.email }, }),});const { draft, needs_human, sources } = await res.json();
await helpscout.addNote(conversation.id, [ needs_human ? '⚠️ Low confidence — check before sending.' : '', draft, sources.length ? '\nSources: ' + sources.map((s) => s.url).join(', ') : '',].join('\n'));