/api/v1/captureiq/analyzeAnalyze an audio recording or transcript and receive a structured list of observations (nonconformities, decisions, action items, etc.). Supports both audit and meeting session types.
Authentication
Requires captureiq:analyze permission. See Authentication.
Request — multipart — audio
curl -X POST https://api.myqateam.com/api/v1/captureiq/analyze \ -H "Authorization: Bearer myqa_..." \ -F "audio=@recording.mp3" \ -F "session_type=audit"Request — JSON — transcript
curl -X POST https://api.myqateam.com/api/v1/captureiq/analyze \ -H "Authorization: Bearer myqa_..." \ -H "Content-Type: application/json" \ -d '{ "transcript": "Auditor: Walk me through your cold-chain procedure...", "session_type": "audit" }'Request — Google Cloud Storage reference
Instead of uploading the recording, reference one you already hold in Cloud Storage. Recommended for long recordings: the audio is read directly from storage and never travels through the API request.
{ "gcs_uri": "gs://your-bucket/meetings/2026-08-07.mp3", "session_type": "meeting", "callback_url": "https://yourdomain.com/webhooks/captureiq"}Requires a one-time setup: grant the Storage Object Viewer role on your bucket to the service account we provide, and tell us the bucket name so it can be registered against your API key. References to buckets that are not registered are refused with 403 FORBIDDEN.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
audio | File | Either/or | Audio file (MP3, WAV, AAC, FLAC, OGG, WebM, M4A, MP4). Max 2 GB. |
gcs_uri | string | Either/or | gs://bucket/object reference to the recording. The bucket must be registered against your API key. |
transcript | string | Either/or | Raw transcript text. |
mime_type | string | No | Content type of the referenced object. Inferred from the file extension when omitted. |
session_type | enum | No | audit (default) or meeting. |
callback_url | string | No | HTTPS webhook. If set, the API returns a job ID immediately. Must be HTTPS and must not target localhost / private (RFC1918) / link-local IPs, or cloud-metadata services. |
callback_secret | string | No | HMAC-SHA256 secret used to sign the webhook payload. |
Response — synchronous
{ "success": true, "data": { "session_type": "audit", "transcript": "...", "summary": "...", "observations": [ { "content": "Cold-storage logs show a 2°C excursion on 2026-04-12 that was not escalated.", "category": "nonconformity", "display_order": 1 } ], "language": "en", "processing_time_ms": 45000, "token_usage": { "input_tokens": 500, "output_tokens": 1200 } }}Observation categories
Each observation is tagged with one of the following categories. The set depends on session_type; any unrecognised category returned by the model is normalised to general_note.
session_type | Allowed categories |
|---|---|
audit | nonconformity, opportunity_for_improvement, positive_finding, action_item, general_note |
meeting | decision, key_point, follow_up, action_item, general_note |
Response — async acknowledgement
{ "success": true, "data": { "job_id": "c4b2…", "status": "processing", "estimated_duration_sec": 120 }}Webhook payload
When the job completes we send an HTTP POST to your callback_url with Content-Type: application/json. The body is the JSON object shown below. If you supplied a callback_secret, the request also carries an X-Webhook-Signature header whose value is the HMAC-SHA256 of the raw request body. Webhook deliveries are best-effort and not retried — we record every attempt with the response status, duration, and any error.
We do not send a Bearer token to your endpoint. Either verify theX-Webhook-Signature header using callback_secret, or include a hard-to-guess token in the URL itself (e.g. https://example.com/webhooks/captureiq/<random-token>).
Successful job payload
{ "job_id": "c4b2…", "success": true, "data": { "session_type": "audit", "transcript": "…", "summary": "…", "observations": [ /* same shape as the sync response */ ], "language": "en", "processing_time_ms": 45000, "token_usage": { "input_tokens": 500, "output_tokens": 1200 } }}Failed job payload
{ "job_id": "c4b2…", "success": false, "error": { "code": "PROCESSING_ERROR", "message": "…" }}Your endpoint should respond with 2xx within ~10 seconds; non-2xx responses are recorded but not retried.
import crypto from 'node:crypto'
const expected = crypto .createHmac('sha256', process.env.CAPTUREIQ_SECRET) .update(rawBody) .digest('hex')
if (expected !== req.headers['x-webhook-signature']) { return res.status(401).send('bad signature')}Errors
See the full error code reference on the authentication page.