> For the complete documentation index, see [llms.txt](https://help.clabassistant.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.clabassistant.com/engineering/backend-response-contracts.md).

# Backend Response Contracts

This frontend consumes multiple backend response contracts. Do not force every route into one JSON envelope.

## Sources

* `clab-assistant-v1` Django API returns successful application payloads as `{"status": "ok", ...}` for endpoints such as `/preview`, `/measures`, `/measurements/chart`, `/patterns/available`, `/pattern/editable`, `/pattern/groups`, `/materials`, `/piece-codes`, and `/genders`.
* `clab-assistant-v1` Django middleware can return auth errors as `{"error": "..."}`.
* `clab-estimator-v1` is the Nesting/Estimator service consumed through `NESTING_API_URL`; frontend proxy routes should preserve its job/result payloads.
* Internal Next.js API routes can use the local `successResponse` / `errorResponse` envelope when they are not acting as compatibility adapters or transparent proxies.

## Clab Estimator (`clab-estimator-v1`)

`src/app/api/fabric-layout/v2/**` proxies the estimator service. Keep these routes thin: authenticate the caller, issue the workspace-scoped estimator token, normalize local request fields only when needed, and preserve estimator success payloads.

Observed estimator shapes:

* `POST /api/v1/nesting/jobs` returns `{"job_id": "...", "status": "queued"}` with HTTP 201.
* `GET /api/v1/nesting/jobs/:jobId` returns job status fields such as `id`, `status`, `progress`, timestamps, `duration_seconds`, `is_terminal`, `meta`, `metrics`, `error_message`, and `result_url`.
* `POST /api/v1/nesting/jobs/:jobId/retry`, `POST /cancel`, and `POST /jobs/cancel-all` return job/cancel status payloads and can use non-200 statuses such as 202 or 409.
* `GET /api/v1/nesting/results` returns the estimator/S3 results list payload, including pagination fields controlled by `cursor` and `limit`.
* `GET /api/v1/nesting/results/:jobId` returns raw `result.json`.
* `GET /api/v1/nesting/results/:jobId/summary` returns the summary object with `job_id`, `run_id`, `materials`, `materials_count`, `has_multiple_materials`, `meta`, `fabric`, and `metrics`.
* `GET /api/v1/nesting/results/:jobId/export.hpgl` returns an HPGL attachment, not JSON.
* Estimator errors can be `{"error": "..."}`, `{"detail": "..."}`, `{"description": "..."}`, or `{"message": "..."}` with additional details that must be preserved for debugging.

Frontend guardrails:

* `src/lib/services/clabEstimatorApi.ts` owns `NESTING_API_URL` validation and estimator error parsing.
* `src/lib/services/clabEstimatorApi.test.ts` covers helper behavior.
* `src/app/api/fabric-layout/v2/estimator-contract.test.ts` covers the proxy contract for job detail, history list, summary, HPGL attachments, and retry conflict errors.

## Change Procedure

When a Django or Estimator response changes:

1. Update or add a contract case in `src/lib/services/clabApiClient.contract.test.ts`, `src/app/api/fabric-layout/v2/estimator-contract.test.ts`, or the relevant route test.
2. Update the frontend adapter/proxy boundary only. Do not change unrelated internal API envelopes.
3. Run `npm run check`, the affected route/client tests, and `npm run build`.
4. Keep backward-compatible parsing when existing saved projects or deployed backend versions can still send the old shape.
