ReplyWithCare API
Generate review responses from your own app, a Chrome extension, a CRM workflow, or anywhere else you can make an HTTPS request. Bearer-token auth, JSON in, JSON out. No SDK required.
Quick start
- Create a ReplyWithCare account if you don't have one.
- Email hello@replywithcare.com to be added to the Agency plan (API access lives there).
- Once we confirm, go to Dashboard → API Keys and click Generate key. Copy the key immediately — we only show it once.
- Send a POST request to the endpoint below.
Endpoint
https://replywithcare.com/api/v1/generateAll API requests must use HTTPS. Plain HTTP requests are rejected by Vercel before they reach the function.
Authentication
Send your API key in the Authorization header as a Bearer token. Keys look like rwc_live_… and are tied to your account.
Authorization: Bearer rwc_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxNever embed your key in client-side code that ships to end users (a public website or a published mobile app). For Chrome extensions, store the key in chrome.storage.local after the user pastes it into your extension's settings.
Request body
JSON with the following fields:
| Field | Type | Description |
|---|---|---|
| review | string | Required. Review text. 5-2000 characters. |
| tone | string | Optional. One of professional, friendly, apologetic, grateful. Default professional. |
| language | string | Optional. auto (detect from review) or a BCP-47 code like en, hi, es. Default auto. |
| length | string | Optional. short (~50w), medium (~100w), long (~150w). Pro-only; free-tier keys always receive medium. |
Response
{
"reply": "Thank you so much for the kind words, Maya — we're delighted...",
"model": "gemini-2.5-flash",
"requestId": "8b3c12d4-..."
}requestId is unique per request. Include it in any support ticket so we can look up the call in our logs.
Official SDK
Type-safe TypeScript wrapper with built-in retry-on-429 and typed errors. Zero runtime dependencies, works in Node 18+ and modern browsers (Chrome extensions included).
npm i @replywithcare/sdkimport { ReplyWithCare, ReplyWithCareError } from '@replywithcare/sdk';
const client = new ReplyWithCare({
apiKey: process.env.RWC_API_KEY!,
});
try {
const { reply, requestId } = await client.generate({
review: 'Loved the service! Coffee was perfect.',
tone: 'grateful',
language: 'en',
});
console.log(reply);
} catch (err) {
if (err instanceof ReplyWithCareError) {
if (err.code === 'rate_limited') {
// SDK auto-retries 429s up to 3 times — if this fires the
// backoff window was exhausted. Slow down upstream.
}
console.error(err.code, err.message, err.requestId);
}
}See the SDK README for the full options table, error codes, and Chrome-extension example.
Raw HTTP examples
curl
curl -X POST https://replywithcare.com/api/v1/generate \
-H "Authorization: Bearer rwc_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"review": "Great service! The team was so helpful and the coffee was perfect.",
"tone": "grateful",
"language": "en",
"length": "medium"
}'JavaScript (fetch)
const res = await fetch('https://replywithcare.com/api/v1/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.RWC_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
review: 'Great service! The team was so helpful and the coffee was perfect.',
tone: 'grateful',
language: 'en',
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`${err.error}: ${err.message}`);
}
const { reply, requestId } = await res.json();
console.log(reply);Python (requests)
import os, requests
resp = requests.post(
"https://replywithcare.com/api/v1/generate",
headers={"Authorization": f"Bearer {os.environ['RWC_API_KEY']}"},
json={
"review": "Great service! The team was so helpful and the coffee was perfect.",
"tone": "grateful",
"language": "en",
},
timeout=30,
)
resp.raise_for_status()
print(resp.json()["reply"])Errors
Errors return a JSON body with a machine-readable error code and a human-readable message.
| Status | error code | Meaning |
|---|---|---|
| 400 | invalid_review | Review is missing, empty, or out of length bounds (5-2000). |
| 400 | invalid_tone | Tone is not one of the allowed values. |
| 400 | invalid_json | Body could not be parsed as JSON. |
| 401 | missing_authorization | No Bearer token in the Authorization header. |
| 401 | invalid_api_key | Key not found or revoked. |
| 403 | agency_required | Key is valid but the owner's subscription is not on the Agency tier. Contact sales to upgrade. |
| 429 | rate_limited | Too many requests in the last minute. Limit is 15 requests per minute per API key. Response includes a Retry-After header (seconds) and X-RateLimit-* headers. |
| 429 | daily_limit_reached | Account's monthly generation quota is exhausted (3,000/mo on Agency). Resets on the 1st (UTC). |
| 500 | generation_failed | Upstream LLM failure. Retry with backoff. |
Quota
Agency accounts get 3,000 generations per month, shared across the in-app generator and the public API. Quota resets on the 1st of each month (UTC). If you need a higher ceiling, email hello@replywithcare.com for a custom plan.
Rate limit
Each API key is capped at 15 requests per minute to keep a leaked or runaway key from burning the entire monthly quota in seconds. Requests over the cap return 429 rate_limited with these headers:
Retry-After: <seconds until window resets>
X-RateLimit-Limit: 15
X-RateLimit-Remaining: <calls left in this minute>Honor Retry-After with exponential backoff if you batch — most SDKs (axios, ky, ofetch, requests) have a retry-with-backoff helper built in.
CORS
The endpoint sets Access-Control-Allow-Origin: * so Chrome extensions and third-party web apps can call it directly from the browser. Auth is enforced entirely by the Bearer token — never expose the key to untrusted code.
Ready to integrate?
Generate your first key in the dashboard. Takes ten seconds.
Get an API key