# Massalaskuri Partner API > Upload a construction blueprint PDF, run Massalaskuri AI symbol detection, and get back every detected > electrical/fire-alarm symbol with coordinates plus a quantity take-off (counts by symbol and Talo 2010 > code). REST + JSON. Async job model. Auth via `X-API-Key` header. Base URL: https://api.massalaskuri.com ## Core flow (async) 1. `POST /v1/jobs/init` with JSON `{ file_name, mime_type, size, models?, confidence?, external_ref?, callback_url? }` → `201 { job_id, upload: { method, url, content_type, max_bytes, expires_at } }`. 2. `PUT` the raw file bytes to `upload.url` (Content-Type = your mime_type; no API key on this request). 3. `POST /v1/jobs/{job_id}/start` → `202 { job_id, status:"queued", poll_url }`. 4. `GET /v1/jobs/{job_id}` → poll until `status:"done"` (statuses: awaiting_upload, queued, processing, done, failed, expired). When done, returns `summary` (take-off) + `pages[]`. Optional `?confidence=0..1`, `?include=detections`. 5. `GET /v1/jobs/{job_id}/pages/{page_index}/detections?limit=&offset=&confidence=` → paginated detections for one page (page_index is 0-based). Optional: pass `callback_url` on init to receive a signed webhook instead of polling. ## Other endpoints - `GET /v1/symbols` — catalog of detectable symbols (class → display_name → category → talo2010_code → icon_url). Cache it; map class/Talo to your products. - `GET /v1/symbols/{class}/icon` — 302 redirect to a symbol glyph image. ## Detection object `{ id, class, display_name, category, symbol_category, color, talo2010_code, icon_url, confidence, bbox_norm:{x,y,width,height}, bbox_px:{x,y,width,height}, source:{yolo,vector_matching} }`. - `bbox_norm` = fractions 0–1 of the page, top-left origin, DPI-independent. Place on your canvas: `x = bbox_norm.x * yourPageWidth` (etc.). This is the recommended coordinate. - `bbox_px` = 200-DPI raster pixels (reference). Each page reports `width_px`, `height_px`, `render_dpi`. ## Auth & errors - Header `X-API-Key: ` on every `/v1` request. Missing/invalid → `401`. - Error shape: `{ "error": { "code": "...", "message": "...", "details"?: ... } }`. Codes: unauthorized(401), not_found(404), conflict(409), unprocessable(422), rate_limited(429), upstream_error(502). - Rate limit: per-key requests/minute (default 120) → `429`. Each response carries `X-Request-Id`. ## Webhooks If `callback_url` is set, we POST the done payload signed with header `X-Massalaskuri-Signature: t=,v1=` where `v1 = HMAC_SHA256(your_webhook_secret, "." + rawBody)`. Verify before trusting; reject stale timestamps. ## Support Email info@massalaskuri.fi for a key, higher limits, or incidents — reply within 1 business day. Pilot SLA: 99.9% target uptime. ## Links - Interactive docs (OpenAPI + try-it): https://api.massalaskuri.com/docs - OpenAPI 3.1 spec (import into Postman/Bruno/Insomnia or generate SDKs): https://api.massalaskuri.com/openapi.json - Live visual demo: https://api.massalaskuri.com/playground - Full single-file reference (everything, AI-readable): https://api.massalaskuri.com/llms-full.txt - Integration kit (sample PDF, bash/Node/Python, webhook receiver, typed SDK, Postman collection): https://api.massalaskuri.com/examples