What you need
- A sandbox API key (
pk_sandbox_…) - An HTTP client (
curl, Postman, or your language’s HTTP library)
Step 1 — Mock fixture (free, ~1 second)
Submit a deterministic test analysis. No real audio required.Org and rep are created automatically if they don’t exist yet. You don’t need to call
POST /v1/orgs first for analyses to work.Step 2 — Poll until complete
status will progress: queued → processing → completed. Mock fixtures usually complete in under a second.
When status === "completed", the response includes the full analysis. The same shape comes back for mock://* fixtures and real audio — write your decoder once.
Decoding tips
- Six pillars:
clarity,influence,objection,discovery,delivery,close. Each appears as a flat*_scorefield (0–100) AND insidefeedback_v5.<pillar>withpositive+negativestrings. overall_scoreis the rounded average of the six pillars — computed server-side, not from the model.- KPIs (
questions_asked,filler_word_count,words_per_minute) are flat at the top ofanalysis. Not nested underkpis. feedback_v5+action_plan_v5keep the_v5suffix so future revisions can ship_v6without breaking decoders.ai_summaryandai_summary_v5carry the same string today. Use either.
Step 3 — Real audio
Replace the mock URL with a publicly reachable HTTPS URL to an audio file:- HTTPS (no plain HTTP)
- No additional auth headers required (pre-signed S3 / GCS URLs are perfect)
- Codec: MP3, WAV, M4A, or FLAC
- Length: 10 seconds to 60 minutes
Step 4 — Stop polling, use webhooks
Polling works for prototyping but isn’t sustainable for production. Register a webhook once and Parlay will notify you when each analysis completes:signing_secret (shown once — store it). Verify every webhook with HMAC-SHA256. See the webhooks guide.
Common pitfalls
`recording_url` returns 404 to Parlay
`recording_url` returns 404 to Parlay
Parlay fetches the file from the URL you provide. If the URL requires auth (Authorization header, custom token), it will fail. Use a pre-signed URL instead.
Same call submitted twice creates two analyses
Same call submitted twice creates two analyses
org_id + rep_id + recording_url does NOT deduplicate. Use Idempotency-Key with the same value on retries to avoid duplicates.Choosing org_id and rep_id values
Choosing org_id and rep_id values
Treat these like foreign keys, not display names. Pass stable opaque identifiers from your system:
Once you set
| Good | Why |
|---|---|
Salesforce User ID (0051a000001wQa3AAE) | Immutable, globally unique |
HubSpot Owner ID (12345678) | Same |
Your internal UUID (usr_a1b2c3d4) | Same |
Email (alex@acme.com) | Stable enough — but breaks on email change |
| Avoid | Why |
|---|---|
First names (alex, brooke) | Two reps with the same name collide; rename has no migration |
Display slugs (alex-smith) | Better than first names but still display-shaped — treat as last resort |
rep_id for a person, treat it as immutable. If it changes, all historical analyses still reference the old value — there’s no built-in “rename” operation today.Querying without org_id: GET /v1/analyses?rep_id=... resolves the rep partner-wide. If the same rep_id exists under multiple orgs, you’ll get a 400 ambiguous_rep_id — pass org_id to disambiguate. Solo-rep partners (one default org) never hit this.Status stuck on `processing` for >10 min
Status stuck on `processing` for >10 min
Likely the audio is corrupt or unreachable. Call
GET /v1/analyses/:id and check the error field. The crash recovery scanner marks stuck jobs failed automatically after 10 min.`recording_too_long` — splitting an audio file
`recording_too_long` — splitting an audio file
Parlay caps at 60 minutes. For longer calls, split before upload. There’s no built-in concatenation across analyses (yet).
What’s next
Rep intelligence
Persona, methodology, and synthesis at scale
Webhooks
Stop polling — get notified

