Developer platform · v1
APIs, SDKs and hardware ingest
One deterministic scoring engine, reachable three ways: a REST API for platforms, language SDKs for product teams, and an MQTT/HTTP telemetry channel for metering hardware on the factory floor.
Endpoints
Every path is versioned in the URL. A released version is frozen: fields are only ever added, never removed or re-typed.
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/score | Score one product specification. Deterministic, synchronous. |
| POST | /v1/score/batch | Score up to 500 specifications in one call. Returns per-row results and errors. |
| GET | /v1/factors | The frozen emission-factor table for a methodology version. |
| GET | /v1/methodology/versions | Released versions, status and deprecation dates. |
| POST | /v1/devices/{device_id}/telemetry | Ingest metered energy / runtime samples from hardware. |
| GET | /v1/devices/{device_id} | Device registration, firmware, calibration and last-seen state. |
| POST | /v1/products/{sku}/attestations | Attach a supplier declaration or certificate to a SKU. |
| GET | /v1/scores/{score_id} | Retrieve a persisted score with its full input hash and version. |
Authentication
Server-to-server calls use a bearer key. Hardware and webhook traffic additionally carries an HMAC-SHA256 signature over the raw body, so a leaked key alone cannot forge a reading.
Authorization: Bearer ak_live_7c1f… # platform key X-AchiChiz-Timestamp: 1754899200 # unix seconds, ±300s window X-AchiChiz-Signature: v1=9f2b0c… # hex HMAC-SHA256 signature_base = timestamp + "." + raw_request_body v1 = HMAC_SHA256(device_secret, signature_base)
Scoring a specification
The same request body the calculator sends. Identical bodies against the same methodology version always return identical responses, so results are safe to cache on the request hash.
curl -X POST https://api.achichiz.in/v1/score \
-H "Authorization: Bearer $ACHICHIZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5f0c-…" \
-d '{
"materialKey": "mat_recycled_brass",
"weightG": 640,
"packagingKey": "pkg_kraft_recycled",
"originKm": 1180,
"transportKey": "log_road_in",
"recyclable": true,
"categoryBaselineCo2e": 6.0,
"methodologyVersion": "1.2"
}'{
"id": "scr_01J9K4M2X…",
"methodologyVersion": "1.2",
"inputHash": "sha256:41ab…",
"totalScore": 78,
"confidence": "estimated",
"netCo2e": 1.31,
"waterL": 47.2,
"plasticG": 0.0,
"breakdown": {
"materialCo2e": 1.09,
"packagingCo2e": 0.08,
"logisticsCo2e": 0.37,
"recyclabilityCredit": 0.23,
"grossCo2e": 1.54
},
"baseline": { "categoryCo2e": 6.0, "deltaPct": -78.2 },
"units": { "co2e": "kg", "water": "L", "plastic": "g" }
}Hardware ingest
Where a factory has real meters, measured energy replaces the factor-table estimate for the manufacturing stage — and only that stage. A device must be registered, calibrated and signing before its samples can lift a score above the estimated tier.
topic: achichiz/v1/{tenant}/{device_id}/telemetry
{
"ts": 1754899200,
"seq": 88412,
"line_id": "kiln-02",
"metrics": {
"energy_wh": 412.5,
"runtime_s": 3600,
"grid_region": "IN-NR",
"water_l": 6.4
},
"sig": "v1=9f2b0c…"
}| Class | Interface | What it feeds |
|---|---|---|
| Energy meter | Modbus RTU / RS-485 → gateway | Manufacturing kWh per production run, mapped to grid intensity for the region. |
| Smart plug | Wi-Fi, direct HTTPS | Bench-level energy for low-volume workshops and pilot lines. |
| Flow sensor | Pulse counter → ESP32 | Process water litres for the water metric. |
| Scale / bin sensor | HX711 load cell | Offcut and packaging waste mass for end-of-life allocation. |
Tier promotion rules
- Signed samples from a calibrated device promote the manufacturing stage from estimated to metered.
- A gap over 5% of the production window drops the run back to estimated for that period.
- Calibration certificates expire; an expired device keeps ingesting but stops contributing to tier.
- Hardware never mints a verified tier — that still requires third-party review.
Webhooks
Subscribe to score and device lifecycle events. Delivery is at-least-once with exponential backoff over 24 hours; handlers must be idempotent on event id.
POST https://your-app.example/hooks/achichiz
X-AchiChiz-Signature: v1=3ac1…
{
"id": "evt_01J9K…",
"type": "score.recomputed",
"created": 1754899200,
"data": {
"sku": "ACZ-BRS-018",
"from": { "version": "1.1", "totalScore": 74 },
"to": { "version": "1.2", "totalScore": 78 },
"reason": "methodology_release"
}
}| Event | Fires when |
|---|---|
| score.created | A specification is scored and persisted. |
| score.recomputed | A methodology release changes a published number. |
| attestation.accepted | A supplier document passes review and lifts confidence. |
| device.calibration_expiring | 14 days before a calibration certificate lapses. |
| device.offline | No signed sample for two consecutive expected windows. |
Errors, limits and guarantees
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_input | A field failed schema validation. `errors[]` names the path. |
| 401 | bad_signature | Bearer key or HMAC signature rejected, or timestamp outside the ±300s window. |
| 404 | unknown_factor_key | The factor key does not exist in the requested methodology version. |
| 409 | idempotency_conflict | Same Idempotency-Key replayed with a different body. |
| 422 | out_of_range | Input is physically implausible (e.g. mass > 50 kg for a giftable SKU). |
| 429 | rate_limited | Retry after the seconds given in `Retry-After`. |
| 503 | version_deprecated | Requested methodology version passed its sunset date. |
Rate limits
600 req/min per key on /v1/score, 60 req/min on /v1/score/batch, 10 000 samples/min per tenant on telemetry. Limits are returned on every response in X-RateLimit-Remaining.
Idempotency
Send Idempotency-Key on any POST. Replays within 24 hours return the original response body and status rather than recomputing or double-writing.
Versioning
A released methodology version is never mutated. New versions ship under a new value; the previous version keeps answering for a 180-day deprecation window announced through the changelog and the version endpoint.
Confidence ceiling
The API cannot mint a verified tier. Unverified specifications are always returned as estimated, metered inputs as metered — verification is a human process, not an API call.
SDKs
| Package | Install | Notes |
|---|---|---|
| @achichiz/sdk | npm i @achichiz/sdk | TypeScript types generated from the OpenAPI schema. Works in Node 20+ and edge runtimes; no Node-only dependencies. |
| achichiz | pip install achichiz | Sync and async clients, automatic retry with jitter, pydantic response models. |
| libachichiz | git submodule add … | Embedded C for ESP-IDF and STM32Cube. HMAC signing, offline spooling, no malloc. |
| openapi.json | GET /v1/openapi.json | Generate a client for any other language directly from the served schema. |
Factor keys come from the published table on the methodology page. The same computation runs interactively in the calculator and step by step in the measurement wizard.