Quelle: https://spooly.eu/docs/api/spools

# Spulen

Spulen lesen, anlegen, ändern, wiegen, nachfüllen, archivieren und umlagern. Endgültig löschen geht nicht.

## Spulen auflisten

`GET /spools`

Sortiert nach Spulennummer. `fill_level` folgt den Warnschwellen des Kontos wie in der App: `low`, `crit` oder null. Jedes Feld, das du schreiben kannst, heißt beim Lesen gleich. Nur lesbar sind `id`, `number`, `title` (Anzeigename wie in der App), `fill_level`, `location` (Ort als Text wie in der App) und `archived`. `material` ist die Sorte mit Variante wie in der App, z. B. PLA Basic. `color_hex` trägt bei mehrfarbigen Spulen mehrere Farben, getrennt mit „; “.

Parameter:

- `limit` (Abfrage, optional): 1 bis 500, Standard 100
- `offset` (Abfrage, optional): 0 bis 1.000.000, Standard 0
- `archived` (Abfrage, optional): false: aktive Spulen (Standard), true: archivierte

```bash
curl "https://spooly.eu/api/v1/spools?limit=100" \
  -H "Authorization: Bearer $SPOOLY_KEY"
```

Antwort (200):

```
{
  "items": [
    {
      "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
      "number": 1,
      "title": "Jade White",
      "name": null,
      "manufacturer": "Bambu Lab",
      "material": "PLA Matte",
      "finish": "matt",
      "color_hex": "#E8E9DF",
      "color_name": "Jade White",
      "remaining_grams": 342,
      "spool_size_grams": 1000,
      "empty_spool_grams": 250,
      "fill_level": "low",
      "location": "Schrank 01 · Fach vorne · Platz 3",
      "location_id": "loc_3c9b7e1a5d60",
      "place": 3,
      "archived": false,
      "price": 19.99,
      "notes": null
    }
  ],
  "total": 23,
  "limit": 100,
  "offset": 0
}
```

## Eine Spule abrufen

`GET /spools/{spool_id}`

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer

```bash
curl "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21" \
  -H "Authorization: Bearer $SPOOLY_KEY"
```

Antwort (200):

```
{
  "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
  "number": 1,
  "title": "Jade White",
  "name": null,
  "manufacturer": "Bambu Lab",
  "material": "PLA Matte",
  "finish": "matt",
  "color_hex": "#E8E9DF",
  "color_name": "Jade White",
  "remaining_grams": 342,
  "spool_size_grams": 1000,
  "empty_spool_grams": 250,
  "fill_level": "low",
  "location": "Schrank 01 · Fach vorne · Platz 3",
  "location_id": "loc_3c9b7e1a5d60",
  "place": 3,
  "archived": false,
  "price": 19.99,
  "notes": null
}
```

## Spule anlegen

`POST /spools`

Antwortet mit 201. Ohne `remaining_grams` ist die Spule voll.

Parameter:

- `color_hex` (Body): #RRGGBB
- `material` (Body): 1 bis 40 Zeichen, die Sorte mit Variante wie in der App, z. B. PLA Basic, PLA+ oder PETG HF
- `spool_size_grams` (Body): Über 0 bis 20.000 g
- `name` (Body, optional): Bis 80 Zeichen
- `color_name` (Body, optional): Bis 60 Zeichen
- `manufacturer` (Body, optional): Bis 60 Zeichen
- `finish` (Body, optional): `matt`, `shiny`, `satin`, `silk`, `metallic`, `transparent`, `glow_in_dark`, `sparkle`, `marble`, `wood` oder `rainbow`
- `remaining_grams` (Body, optional): 0 bis 20.000 g, nicht mehr als die Spule
- `empty_spool_grams` (Body, optional): Tara, 0 bis 2.000 g
- `price` (Body, optional): 0 bis 100.000
- `notes` (Body, optional): Bis 1.000 Zeichen
- `location_id` (Body, optional): Kennung aus `GET /locations`
- `place` (Body, optional): Platz im Lagerort, 1 bis `places`, nur mit `location_id`
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X POST "https://spooly.eu/api/v1/spools" \
  -H "Authorization: Bearer $SPOOLY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: neu-petg-0001" \
  -d '{"color_hex":"#1B1B1D","material":"PETG HF","spool_size_grams":1000,"color_name":"Black"}'
```

Antwort (201):

```
{
  "change_id": 381,
  "spool": {
    "id": "2c9e5a71-0d4b-4e3f-b862-91a7c4d0e5f3",
    "number": 24,
    "title": "Black",
    "name": null,
    "manufacturer": null,
    "material": "PETG HF",
    "finish": null,
    "color_hex": "#1B1B1D",
    "color_name": "Black",
    "remaining_grams": 1000,
    "spool_size_grams": 1000,
    "empty_spool_grams": null,
    "fill_level": null,
    "location": null,
    "location_id": null,
    "place": null,
    "archived": false,
    "price": null,
    "notes": null
  },
  "slot": null,
  "old_grams": null,
  "new_grams": null,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #24 Black angelegt"
}
```

## Spule ändern

`PATCH /spools/{spool_id}`

Nur die mitgeschickten Felder, mindestens eines. Unbekannte Felder ergeben 422. `color_hex`, `material` und `spool_size_grams` dürfen nicht null sein, die übrigen leerst du mit null. `place` null nimmt nur den Platz weg. Das Gewicht läuft über `/weight` und `/refill`.

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer
- `name, color_hex, color_name, material, manufacturer, finish, spool_size_grams, empty_spool_grams, price, notes, location_id, place` (Body, optional): Regeln wie beim Anlegen
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X PATCH "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21" \
  -H "Authorization: Bearer $SPOOLY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"notes":"Trocknen vor dem Druck"}'
```

Antwort (200):

```
{
  "change_id": 381,
  "spool": {
    "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
    "number": 1,
    "title": "Jade White",
    "name": null,
    "manufacturer": "Bambu Lab",
    "material": "PLA Matte",
    "finish": "matt",
    "color_hex": "#E8E9DF",
    "color_name": "Jade White",
    "remaining_grams": 342,
    "spool_size_grams": 1000,
    "empty_spool_grams": 250,
    "fill_level": "low",
    "location": "Schrank 01 · Fach vorne · Platz 3",
    "location_id": "loc_3c9b7e1a5d60",
    "place": 3,
    "archived": false,
    "price": 19.99,
    "notes": null
  },
  "slot": null,
  "old_grams": null,
  "new_grams": null,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #1 Jade White bearbeitet"
}
```

## Restgewicht setzen

`POST /spools/{spool_id}/weight`

Genau eines der beiden Gewichte. 0 g archiviert die Spule, wie in der App.

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer
- `grams` (Body, optional): 0 bis 20.000 g, nur das Filament
- `gross_grams` (Body, optional): 0 bis 40.000 g, Spule mit Tara. Die Tara muss bekannt sein.
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X POST "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21/weight" \
  -H "Authorization: Bearer $SPOOLY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: waage-2026-11-01-0815" \
  -d '{"gross_grams":542}'
```

Antwort (200):

```
{
  "change_id": 381,
  "spool": {
    "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
    "number": 1,
    "title": "Jade White",
    "name": null,
    "manufacturer": "Bambu Lab",
    "material": "PLA Matte",
    "finish": "matt",
    "color_hex": "#E8E9DF",
    "color_name": "Jade White",
    "remaining_grams": 300,
    "spool_size_grams": 1000,
    "empty_spool_grams": 250,
    "fill_level": "low",
    "location": "Schrank 01 · Fach vorne · Platz 3",
    "location_id": "loc_3c9b7e1a5d60",
    "place": 3,
    "archived": false,
    "price": 19.99,
    "notes": null
  },
  "slot": null,
  "old_grams": 342,
  "new_grams": 300,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #1 Jade White: 342 auf 300 g"
}
```

## Nachfüllen

`POST /spools/{spool_id}/refill`

Addiert Gramm. Das Ergebnis darf nicht über der Spulengröße liegen.

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer
- `grams` (Body): Über 0 bis 20.000 g
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X POST "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21/refill" \
  -H "Authorization: Bearer $SPOOLY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"grams":250}'
```

Antwort (200):

```
{
  "change_id": 381,
  "spool": {
    "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
    "number": 1,
    "title": "Jade White",
    "name": null,
    "manufacturer": "Bambu Lab",
    "material": "PLA Matte",
    "finish": "matt",
    "color_hex": "#E8E9DF",
    "color_name": "Jade White",
    "remaining_grams": 592,
    "spool_size_grams": 1000,
    "empty_spool_grams": 250,
    "fill_level": null,
    "location": "Schrank 01 · Fach vorne · Platz 3",
    "location_id": "loc_3c9b7e1a5d60",
    "place": 3,
    "archived": false,
    "price": 19.99,
    "notes": null
  },
  "slot": null,
  "old_grams": 342,
  "new_grams": 592,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #1 Jade White: 342 auf 592 g"
}
```

## Archivieren

`POST /spools/{spool_id}/archive`

Die Spule verlässt den aktiven Bestand, ihr Druckverlauf bleibt. Während eines laufenden Drucks geht das nicht. Die API antwortet dann mit 409 `spool_in_print`.

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X POST "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21/archive" \
  -H "Authorization: Bearer $SPOOLY_KEY"
```

Antwort (200):

```
{
  "change_id": 381,
  "spool": {
    "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
    "number": 1,
    "title": "Jade White",
    "name": null,
    "manufacturer": "Bambu Lab",
    "material": "PLA Matte",
    "finish": "matt",
    "color_hex": "#E8E9DF",
    "color_name": "Jade White",
    "remaining_grams": 342,
    "spool_size_grams": 1000,
    "empty_spool_grams": 250,
    "fill_level": "low",
    "location": "Schrank 01 · Fach vorne · Platz 3",
    "location_id": "loc_3c9b7e1a5d60",
    "place": 3,
    "archived": true,
    "price": 19.99,
    "notes": null
  },
  "slot": null,
  "old_grams": null,
  "new_grams": null,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #1 Jade White archiviert"
}
```

## Zurückholen

`POST /spools/{spool_id}/restore`

Holt eine archivierte Spule zurück in den aktiven Bestand.

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X POST "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21/restore" \
  -H "Authorization: Bearer $SPOOLY_KEY"
```

Antwort (200):

```
{
  "change_id": 381,
  "spool": {
    "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
    "number": 1,
    "title": "Jade White",
    "name": null,
    "manufacturer": "Bambu Lab",
    "material": "PLA Matte",
    "finish": "matt",
    "color_hex": "#E8E9DF",
    "color_name": "Jade White",
    "remaining_grams": 342,
    "spool_size_grams": 1000,
    "empty_spool_grams": 250,
    "fill_level": "low",
    "location": "Schrank 01 · Fach vorne · Platz 3",
    "location_id": "loc_3c9b7e1a5d60",
    "place": 3,
    "archived": false,
    "price": 19.99,
    "notes": null
  },
  "slot": null,
  "old_grams": null,
  "new_grams": null,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #1 Jade White zurückgeholt"
}
```

## Umlagern

`POST /spools/{spool_id}/move`

Das Ziel kommt aus [GET /locations](https://spooly.eu/docs/api/locations). `location_id` null nimmt die Spule aus dem Ort. Mit `place` liegt sie auf diesem Platz, ohne `place` liegt sie im Ort ohne Platz.

Parameter:

- `spool_id` (Pfad): Die `id` der Spule, nicht ihre Nummer
- `location_id` (Body): Kennung des Lagerorts oder null
- `place` (Body, optional): Platznummer von 1 bis `places` des Lagerorts. Ist der Platz belegt, kommt 409 `place_taken`.
- `Idempotency-Key` (Kopf, optional): 1 bis 128 sichtbare ASCII-Zeichen. [Idempotency-Key](https://spooly.eu/docs/api#api-idempotenz)

```bash
curl -X POST "https://spooly.eu/api/v1/spools/7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21/move" \
  -H "Authorization: Bearer $SPOOLY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"location_id":"loc_3c9b7e1a5d60","place":3}'
```

Antwort (200):

```
{
  "change_id": 381,
  "spool": {
    "id": "7f3c2a10-5e1b-4c8e-9a44-2d6b1f0c7e21",
    "number": 1,
    "title": "Jade White",
    "name": null,
    "manufacturer": "Bambu Lab",
    "material": "PLA Matte",
    "finish": "matt",
    "color_hex": "#E8E9DF",
    "color_name": "Jade White",
    "remaining_grams": 342,
    "spool_size_grams": 1000,
    "empty_spool_grams": 250,
    "fill_level": "low",
    "location": "Schrank 01 · Fach vorne · Platz 3",
    "location_id": "loc_3c9b7e1a5d60",
    "place": 3,
    "archived": false,
    "price": 19.99,
    "notes": null
  },
  "slot": null,
  "old_grams": null,
  "new_grams": null,
  "replayed": false,
  "task": null,
  "printer": null,
  "stock_empty": null,
  "summary": "Spule #1 Jade White umgelagert"
}
```
