ConversAI Labs Documentation Audit
One thin API reference page carries the entire developer surface, and almost every consequential value in it — webhook events, lead status, the base URL, the voice provider — disagrees with itself or with the legal/pricing pages. The contradictions are the kind a human shrugs off and an automated agent fails on silently.
1. Base URL already ends in /api/v1, and every endpoint path repeats it (critical)
Location: /api-docs — "Environment Setup" and all endpoint listings
Problem: The documented Base URL is https://voice-ai-admin-api-762279639608.asia-south1.run.app/api/v1. Every endpoint is then written with the same prefix already attached: GET /api/v1/agents, POST /api/v1/leads/, POST /api/v1/calls/schedule, PUT /api/v1/webhooks/config. The page never says whether the listed path is relative to the base or absolute.
Consequence: The natural construction — base URL + listed path — yields .../api/v1/api/v1/agents, a 404. A human notices and trims it; an AI agent or a generated client concatenates exactly what's written and every call fails. There is no example of a fully-assembled request URL anywhere to disambiguate.
The fix: Pick one convention. Either set the base URL to .../ (no /api/v1) and keep the full paths, or keep /api/v1 in the base and list endpoints as /agents, /leads/, /calls/schedule. Show one complete, assembled curl example so there's no ambiguity.
2. The same page enumerates webhook events three different ways (critical)
Location: /api-docs — "Types of Webhook Events", "Configure Webhook → Available Events", "Send Test Webhook"
Problem: Three lists, three different sets, on one page:
- "Types of Webhook Events" lists
call.started,call.completed,call.analysed— nocall.failed. - "Configure Webhook → Available Events" lists all four:
call.started,call.completed,call.failed,call.analysed. - "Send Test Webhook" request body says
event_typeaccepts(call.started, call.completed, call.failed)— nocall.analysed.
Consequence: A developer wiring a webhook handler cannot tell whether call.failed fires at all, or whether call.analysed is testable. Subscribe to the wrong set and you either miss failure events in production or build a handler for events that never arrive — and you can't test call.analysed through the documented test endpoint because it isn't a listed option there.
The fix: Maintain one canonical event list and reference it everywhere. If the test endpoint genuinely can't emit call.analysed, say so explicitly rather than silently omitting it.
3. Three conflicting refund policies across three pages (critical)
Location: /refund, /term_and_conditions §6.5, /industries/hinglish
Problem: The Refund & Cancellation Policy promises "a full refund within 7 days of the initial purchase." The Terms & Conditions §6.5 say the opposite: "All subscription fees are non-refundable, except" breach-to-cure or where required by law. The Hinglish industry landing page advertises a "30-day money-back guarantee." Three documents, three incompatible answers.
Consequence: A customer disputing a charge can cite whichever page favors them; support has no defensible position; and the contradiction undermines the "honest communication, clear pricing" value claimed on the About page. This is a chargeback and trust problem, not a wording nitpick.
The fix: Decide the actual policy and state it identically on the refund page, in the Terms, and on every landing page. If "non-refundable" is the real rule, remove the 7-day and 30-day promises.
4. Pricing is quoted in USD on the cards and INR in the summary (critical)
Location: /pricing — plan cards vs "Quick Summary"
Problem: The plan cards are priced in dollars: Starter $99/month, Professional $299/month, Enterprise $999/month. The "Quick Summary" on the same page says "Pay-as-you-grow pricing: from ₹299/month for startups to enterprise plans at ₹2,999/month." ₹299 is roughly $3.60 — not $99 — so these are not currency conversions of each other; they're different numbers entirely.
Consequence: A prospect cannot tell what they will actually be charged, or in which currency Stripe will bill them. The gap between $99 and ₹299 (≈$3.60) is large enough that someone will feel misled at checkout regardless of which figure is correct.
The fix: Choose a single billing currency, make the cards and the summary match exactly, and if both USD and INR are offered, show two clearly-labeled price tables instead of mixing them in one paragraph.
5. The status field has two different value sets for leads (significant)
Location: /api-docs — "Add Lead" response vs "Get Lead" response
Problem: Add Lead documents status as "(new, contacted, scheduled, etc.)". Get Lead documents the same status field as "(new, in_progress, done, stopped)". Only new overlaps; contacted/scheduled vs in_progress/done/stopped don't reconcile, and the "etc." makes the first list explicitly non-exhaustive.
Consequence: Any code that branches on lead status — a common automation pattern — can't be written reliably. An agent that maps these enums will key off scheduled or done and find the value never appears. The "etc." guarantees the enum can't be fully handled.
The fix: Publish one authoritative, complete enum of status values, drop "etc.", and use it in both the Add Lead and Get Lead responses (and anywhere else status is returned).
6. API docs require a "Retell AI integration"; the legal pages say telephony is Twilio (significant)
Location: /api-docs ("Initiate Call" troubleshooting) vs /term_and_conditions §11 and /privacy §4.1
Problem: The Initiate Call troubleshooting tells developers to verify that "Retell AI integration is properly configured." But the Terms (§11 Third-Party Services) list only "Twilio: Telephony and SMS" and "OpenAI / Anthropic," and the Privacy policy (§4.1) says "Twilio: Handles phone call routing and connectivity." Retell AI appears nowhere in the third-party/subprocessor disclosures.
Consequence: A developer debugging a failed call doesn't know whether the telephony stack is Twilio or Retell AI, or what "configuring the Retell AI integration" even entails since it's never documented. Separately, if call audio/transcripts flow through Retell AI, it's an undisclosed subprocessor — a real gap under the DPDP and GDPR commitments the privacy policy makes.
The fix: Reconcile the stack. Document what the developer actually configures, and if Retell AI processes call data, add it to the third-party/subprocessor lists in the Terms and Privacy policy.
7. Rate limits and error handling live in the Terms, not the API docs (significant)
Location: /api-docs vs /term_and_conditions §5
Problem: The Terms §5 impose hard limits — "Exceed 10,000 API calls per hour (unless on Enterprise plan)" and "Make more than 1,000 simultaneous calls" are prohibited — but the API reference never mentions rate limits, a 429 response, retry-after headers, or any error schema. The only error artifact in the docs is the literal string "Failed to initiate call" in a troubleshooting note. There is no list of HTTP status codes or error response body shape.
Consequence: Developers can't build throttling or backoff because the only place the limits exist is a legal page they'll never read while coding — and they can't even tell which tier the 10,000/hour ceiling applies to. With no documented error format, every failure is a guess, and an agent has nothing structured to branch on.
The fix: Add a "Rate Limits & Errors" section to the API docs: the per-hour and concurrency limits (including the Enterprise exception), the 429 behavior, and a canonical error response schema with the status codes each endpoint can return.
8. Marketing promises SDKs and a JS quick-start that the API docs don't support (significant)
Location: /integrations vs /api-docs
Problem: The Integrations page claims "Full documentation, SDKs in multiple languages, and dedicated developer support" and ships a quick-start snippet: const conversai = new ConversAI('YOUR_API_KEY'); ... conversai.integrations.create({ type: 'shopify', credentials: { ... } });. The API reference documents none of this — there's no SDK, no package name, no install command, no integrations.create endpoint, and auth is a raw X-API-Key header, not an SDK constructor. The snippet's credentials: { ... } is an unmarked placeholder.
Consequence: A developer (or an agent) following the quick-start can't npm install anything because no package is named, can't call conversai.integrations.create because that endpoint isn't documented, and can't fill { ... } because the required credential fields are never specified. The advertised "SDKs in multiple languages" appear not to exist in the docs at all.
The fix: Either publish the SDK(s) with install instructions and a runnable example, or replace the SDK snippet with the actual HTTP request the API supports. Mark every placeholder (YOUR_API_KEY, credential fields) explicitly.
9. Cancellation is "anytime, self-serve" on two pages and "30 days' notice" in the Terms (significant)
Location: /refund §1 and /pricing footer vs /term_and_conditions §6.2
Problem: The Refund & Cancellation Policy says "You may cancel your subscription at any time from your account dashboard… No further charges will be made after cancellation." The pricing page footer repeats "Cancel anytime." But the Terms §6.2 Auto-Renewal say "To cancel, you must provide notice at least 30 days before the renewal date."
Consequence: A customer who cancels in-dashboard the day before renewal — as both the refund page and the pricing footer invite — gets billed for another cycle under the Terms. Two customer-facing pages and the binding contract create directly opposing expectations about whether the next charge happens.
The fix: State one cancellation mechanism and timing everywhere. If the dashboard cancel is immediate and binding, remove the 30-day notice clause; if 30 days' notice is required, say so on the refund page and the pricing footer too.
10. "Unlimited calls" contradicts the metered, included-minutes plans (significant)
Location: /pricing — FAQ vs plan cards / add-ons
Problem: The FAQ says "Flat-rate subscriptions provide unlimited calls within your plan tier." But the cards cap usage — "1,000 minutes included (~100 calls)" on Starter, "2,000 minutes included" on Professional — and the add-ons charge "Extra Minutes $0.30/min" for going over. Metered minutes with paid overage is the opposite of unlimited.
Consequence: A buyer reads "unlimited," runs past the included minutes, and gets a surprise $0.30/min overage bill. The pricing model is genuinely metered; the FAQ misrepresents it.
The fix: Remove "unlimited" or qualify it precisely ("unlimited calls up to your included minutes; $0.30/min thereafter").
11. SLA is "99.9% guaranteed" in pricing and "99.5% targeted" in the Terms (significant)
Location: /pricing (Enterprise) vs /term_and_conditions §8.1
Problem: The Enterprise plan card promises "SLA guarantees (99.9% uptime)." The Terms §8.1 say "Target Uptime: ConversAI Labs targets 99.5% monthly uptime." Both the number and the strength of the commitment differ — a contractual "guarantee" vs an aspirational "target."
Consequence: 99.9% allows ~43 minutes of monthly downtime; 99.5% allows ~3.6 hours — roughly a 5x difference. An enterprise buyer who signs based on the 99.9% guarantee has no contractual basis for it, since the binding Terms only "target" a weaker number with no remedy specified.
The fix: Align the figure and the language. Put the real, contractual uptime commitment (and the service-credit remedy) in the Terms, and quote that exact number on the pricing page.
12. Privacy policy says the cookie banner isn't built yet, then describes the banner in use (significant)
Location: /privacy §5.3, cross-referenced with §4.4
Problem: §5.3 states "Note: Cookie banner implementation in progress. Until then, we use only essential cookies required for service functionality," and the very next lines describe a live banner: "When you first visit our website, you'll see a cookie consent banner: 🍪 … [Accept All] [Reject Non-Essential] [Customize]." Meanwhile §4.4 lists Google Analytics and Microsoft Clarity ("session recordings and heatmaps") as active — both non-essential tracking technologies.
Consequence: The page simultaneously claims the banner exists and doesn't, and claims "only essential cookies" while running analytics and session-recording that are by definition non-essential. For a company asserting DPDP and GDPR compliance, that's a consent gap a regulator or auditor would flag.
The fix: Reflect the actual state — if Analytics/Clarity run before consent, stop saying "only essential cookies"; if the banner is live, remove the "implementation in progress" note and document what each tool collects.
13. Free trial is "14 days" on pricing and "50 calls OR 14 days, whichever comes first" in the Terms (significant)
Location: /pricing vs /term_and_conditions §2.1
Problem: The pricing page repeatedly advertises a "14-day free trial—no credit card required to start," and the footer repeats "14-day free trial." The Terms §2.1 define the trial differently: "Duration: 50 free calls OR 14 days (whichever comes first)." The pricing page omits the 50-call cap entirely.
Consequence: A buyer who reads only the pricing page expects a full two weeks to evaluate, but a developer load-testing the voice API can burn through 50 calls in minutes and have the trial end on call count — with no warning anywhere in the pricing copy that the trial is call-capped at all.
The fix: State the trial terms identically everywhere: "50 calls or 14 days, whichever comes first" on the pricing page and footer, or drop the call cap from the Terms if it isn't actually enforced.
14. "SOC2 Type II certified" on pricing vs "SOC 2 compliant hosting" in privacy (significant)
Location: /pricing vs /privacy §8
Problem: The pricing page asserts the company is "SOC2 Type II Certified" (Enterprise feature and footer). The Privacy policy §8 only substantiates "SOC 2 Type II compliant cloud hosting" — i.e., the hosting provider's compliance, not a company-level certification.
Consequence: "We are SOC2 Type II certified" and "we run on SOC2-compliant hosting" are materially different claims in a security review. A prospect's procurement team will ask for the report; if only the hosting provider is certified, the marketing claim won't hold up — and a misstated certification is exactly the kind of thing that derails an enterprise deal at the security-questionnaire stage.
The fix: State precisely what's certified. If ConversAI Labs itself holds a SOC2 Type II report, reference it; if only the infrastructure is compliant, change the pricing-page and footer wording to match.
15. The production base URL is a raw, region-locked Cloud Run hostname (minor)
Location: /api-docs — "Base URL"
Problem: The documented base is https://voice-ai-admin-api-762279639608.asia-south1.run.app/... — an auto-generated Google Cloud Run hostname with the GCP project number embedded and the region (asia-south1) hard-coded into the domain.
Consequence: This style of hostname can change if the service is redeployed under a different revision or project, breaking every hard-coded integration; it also pins all traffic to a single India region with no documented failover, and exposes internal project metadata. There's no stable custom domain (e.g. api.conversailabs.com) to depend on.
The fix: Front the API with a stable custom domain and document that. Keep the Cloud Run URL internal.
16. Customer counts disagree across landing pages (minor)
Location: /pricing vs /industries/hinglish
Problem: The pricing page says "Join 50+ US businesses already using AI voice automation." The Hinglish industry page says "Join thousands of hinglish finance companies that have already revolutionized their operations."
Consequence: "50+" and "thousands" can't both be true, and the geographic framing flips (US businesses vs Indian Hinglish companies). Inconsistent social proof reads as boilerplate and erodes the credibility of every other number on the site.
The fix: Use one substantiated customer figure across all pages, or scope each claim to its real segment ("50+ businesses overall").
What they do well
- Authentication is unambiguous — a single
X-API-Key: <your-api-key>header is stated once and used consistently across every endpoint. - Webhook delivery semantics are spelled out — the retry schedule (1/5/15 min, max 4 attempts) and the "return 2xx" requirement are concrete reliability details many APIs omit.
- Concrete gotchas are flagged — the required trailing slash on
/api/v1/leads/, E.164 phone formatting, and the "you need an existing agent_id" prerequisite are exactly the parse-friendly notes that prevent first-call failures.
Top 3 recommendations
- Establish a single source of truth and kill the contradictions. One canonical list each for webhook events, lead
statusvalues, refund policy, cancellation terms, free-trial terms, pricing currency, and SLA uptime — and fix the base-URL/api/v1doubling so the very first request a developer constructs actually resolves. - Make the API docs machine-consumable. Publish an OpenAPI/Swagger spec, an errors-and-rate-limits section (429 behavior, status codes, error schema, the Enterprise rate-limit exception), and an
llms.txt, so agents can discover endpoints and handle failures instead of parsing prose and guessing. - Make the marketing match the product. Either ship the advertised "SDKs in multiple languages" with install steps and a runnable quick-start, or replace the SDK snippet with the real HTTP calls — reconcile Twilio-vs-Retell so developers configure the actual telephony provider, and align the SOC2 claim with what's actually certified.