# service-kicad API contract

HTTP API for the `service-kicad` container. Every Adom tool that needs
headless KiCad or the stock library hits this surface.

## Version

- API version: `1.0.0` (matches `service.json::api_version`).
- Compatibility: clients check `/version` on startup and refuse to
  connect when **major** differs.
- Service is stateless — safe to restart at any time.

## Versioning

```
GET /version
→ { "service": "service-kicad", "version": "0.0.1", "api_version": "1.0.0" }

GET /health
→ { "ok": true, "service": "service-kicad", "version": "0.0.1",
    "kicad_version": "9.0.8" }
```

Consumers: `adom-cli carbon` watchdog, `aci doctor`, CI smoke.

## Auth

Per PLAN decision 17 (Adom-platform JWT). `Authorization: Bearer <jwt>`.
Service validates against `carbon.adom.inc`'s JWKS. Dev: no auth.

## kicad-cli PCB operations

```
POST /kicad/pcb/drc
  Request body:  <raw .kicad_pcb bytes>
  Content-Type:  application/octet-stream
  Response:      application/json — same shape as `kicad-cli pcb drc
                 --format json` output.

POST /kicad/pcb/export/svg?side=top|bottom
  Request body:  <raw .kicad_pcb bytes>
  Response:      image/svg+xml

POST /kicad/pcb/export/gerbers
  Request body:  <raw .kicad_pcb bytes>
  Response:      application/x-tar — the full fab layer set
                 (F.Cu, B.Cu, F.Mask, B.Mask, F.Silkscreen,
                  B.Silkscreen, Edge.Cuts).

POST /kicad/pcb/export/step
  Request body:  <raw .kicad_pcb bytes>
  Response:      model/step — with component 3D models substituted
                 (--subst-models --no-dnp).

POST /kicad/pcb/export/glb
  Request body:  <raw .kicad_pcb bytes>
  Response:      model/gltf-binary — with component 3D models.
```

## kicad-cli schematic operations

```
POST /kicad/sch/erc
  Request body:  <raw .kicad_sch bytes>
  Response:      application/json — same shape as `kicad-cli sch erc
                 --format json`.

POST /kicad/sch/export/svg
  Request body:  <raw .kicad_sch bytes>
  Response:      image/svg+xml

POST /kicad/sch/export/pdf
  Request body:  <raw .kicad_sch bytes>
  Response:      application/pdf

POST /kicad/sch/export/bom
  Request body:  <raw .kicad_sch bytes>
  Response:      text/csv
```

## Symbol + footprint lookup (by library + name)

Convenience wrappers for callers that know the canonical
library/name but don't ship a local copy of the source file.

```
GET /sym/export/svg/:library/:name
  Path params:   library (e.g. "Device"), name (e.g. "R")
  Response:      image/svg+xml — rendered via `kicad-cli sym export svg`
                 on /usr/share/kicad/symbols/<library>.kicad_sym.

GET /fp/export/svg/:library/:name
  Path params:   library (e.g. "Package_SO"), name (e.g. "SOT-23")
  Response:      image/svg+xml — rendered via `kicad-cli fp export svg`
                 on /usr/share/kicad/footprints/<library>.pretty/<name>.kicad_mod.
```

## Static library mounts

The ~5 GB kicad-packages3d library + the symbol/footprint trees are
served read-only as static files. Clients stream whatever they need
(most call sites only need a handful at a time).

```
GET /models/<path>        → static from /usr/share/kicad/3dmodels/
GET /footprints/<path>    → static from /usr/share/kicad/footprints/
GET /symbols/<path>       → static from /usr/share/kicad/symbols/
```

Example: `curl -o LM1117.step $KICAD_SERVICE_API/models/Package_TO_SOT_SMD.3dshapes/SOT-223.step`

## Rate limits

- **kicad-cli endpoints** (`/kicad/*`): 30 req/min/user, burst 10.
- **Static library** (`/models`, `/footprints`, `/symbols`): 600
  req/min/user, no burst cap — it's just disk reads.
- Exceeding → HTTP 429 with `Retry-After`.

## Error shape

```json
{ "error": "human-readable message", "code": 400 }
```

Body is always JSON for error responses; HTTP status carries the
primary signal.

## Port configuration

The binary honors `$PORT`. Default 8780 (matches the legacy service-
kicad container's port, so consumers that already point at 8780
migrate cleanly).

## Stability policy

- **Major bump**: any breaking change to an existing endpoint's
  request or response shape.
- **Minor bump**: new endpoints.
- **Patch bump**: bug fixes, dependency updates, no contract change.

Every bump edits `service.json::api_version` AND this doc's header.
