CaptureIQ
POST/api/v1/captureiq/analyze

Analyze 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.

json
{
"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

FieldTypeRequiredDescription
audioFileEither/orAudio file (MP3, WAV, AAC, FLAC, OGG, WebM, M4A, MP4). Max 2 GB.
gcs_uristringEither/orgs://bucket/object reference to the recording. The bucket must be registered against your API key.
transcriptstringEither/orRaw transcript text.
mime_typestringNoContent type of the referenced object. Inferred from the file extension when omitted.
session_typeenumNoaudit (default) or meeting.
callback_urlstringNoHTTPS 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_secretstringNoHMAC-SHA256 secret used to sign the webhook payload.

Response — synchronous

json
{
"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_typeAllowed categories
auditnonconformity, opportunity_for_improvement, positive_finding, action_item, general_note
meetingdecision, key_point, follow_up, action_item, general_note

Response — async acknowledgement

json
{
"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

json
{
"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

json
{
"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.

API Documentation — myQA.team