IFS Analyzer
POST
/api/v1/ifs-analyzer/batchesQueue up to 100 observations and get the results by polling or as a signed webhook.
Authentication
Requires ifs-analyzer:analyze permission. See Authentication.
Request — JSON
curl -X POST https://api.myqateam.com/api/v1/ifs-analyzer/batches \ -H "Authorization: Bearer myqa_..." \ -H "Content-Type: application/json" \ -d '{ "items": [ { "requirement": "4.12.1", "scope": "Production de plats cuisinés réfrigérés", "observation": "Test du détecteur de métaux non réalisé au démarrage de 6h.", "validator_remark": "Risque de corps étrangers sur les lots de 6h à 10h.", "reference": "NC-2026-0042" }, { "requirement": "2.3.9.1", "scope": "Conditionnement sous atmosphère modifiée", "observation": "Fréquence de contrôle du taux d'\''O2 non respectée sur une journée.", "reference": "NC-2026-0043", "critic": false } ], "critic": true, "callback_url": "https://example.com/webhooks/ifs", "callback_secret": "whsec_..."}'Fields
| Field | Type | Required | Description |
|---|---|---|---|
items | array | Yes | 1 to 100 observations, each with the fields of POST /analyze: requirement, scope, observation, and optionally validator_remark, reference and critic. |
critic | boolean | No | Run (true) or skip (false) the critic for every item that doesn't set its own critic. Omit it to use the default, which is on. |
callback_url | string | No | HTTPS webhook called once the batch finishes. Must not target localhost, private (RFC1918) or link-local IPs, or cloud metadata services. |
callback_secret | string | No | Secret for the X-Webhook-Signature header (HMAC-SHA256 of the raw body, hex). Requires callback_url. ≤ 256 characters. |
Every item is checked before anything is queued, including that each requirement exists in IFS Food v8. One bad item rejects the batch with 400, and details.errors names each problem, e.g. items[3].observation is required.
Response — async acknowledgement
json
{ "success": true, "data": { "job_id": "94c52cc5-…", "status": "processing", "total": 2, "estimated_duration_sec": 20, "poll_url": "/api/v1/ifs-analyzer/jobs/94c52cc5-…" }}Then poll GET /api/v1/ifs-analyzer/jobs/:jobId. Finished observations show up there while the rest are still running.
Webhook payload
json
{ "job_id": "94c52cc5-…", "success": true, "data": { /* same payload as GET /api/v1/ifs-analyzer/jobs/:jobId */ }}Sent once when the batch finishes, with no retries. If your endpoint was down, poll the job instead. Verify the signature against the raw request body before parsing it.
Limits
- 100 observations per batch, analysed 3 at a time (about 20 seconds per round).
- 2 running batches per organization. A third returns
429 CONCURRENCY_LIMIT_EXCEEDED. - Each observation is billed like a single
/analyzecall. - Observations that hit an AI rate limit are retried once more, a minute after the rest of the batch. If they still fail, their result carries
AI_RATE_LIMITEDand can be resubmitted.
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_INPUT | Invalid JSON, empty or oversized items, or an invalid item. |
| 400 | INVALID_CALLBACK_URL | callback_url is not HTTPS or targets a forbidden host. |
| 402 | COIN_LIMIT_EXCEEDED | Your organization has used its coins for the month. |
| 429 | CONCURRENCY_LIMIT_EXCEEDED | Two batches are already running for your organization. |