{
  "openapi": "3.0.1",
  "info": {
    "title": "Treadx API",
    "description": "Koppla verkstadens egna system till Treadx.",
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://api.treadx.se"
    }
  ],
  "paths": {
    "/v1/customers": {
      "get": {
        "tags": [
          "Customers"
        ],
        "summary": "Lista kunder",
        "description": "Verkstadens kunder i ändringsordning, äldst först. Inaktiva och anonymiserade kunder ingår, så att en synk ser när de ändras.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Antal poster per sida, 1–200. Standard 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "`nextCursor` från föregående sida, oförändrad.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "description": "Bara poster som skapats eller ändrats från och med den här tiden. ISO 8601 med tidszon, t.ex. `2026-10-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "externalId",
            "in": "query",
            "description": "Bara posten med ditt eget id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email",
            "in": "query",
            "description": "Bara kunden med den här e-postadressen.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfIntegrationCustomer"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "customers.read"
            ]
          }
        ]
      },
      "post": {
        "tags": [
          "Customers"
        ],
        "summary": "Skapa kund",
        "description": "E-post är frivillig. Anges den måste den vara ledig i verkstaden, liksom `externalId`. Annars `409`.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateCustomer"
              },
              "example": {
                "externalId": "K-10482",
                "firstName": "Anna",
                "lastName": "Svensson",
                "email": "anna.svensson@example.se",
                "phone": "070-123 45 67",
                "address": "Storgatan 1",
                "postalCode": "791 30",
                "city": "Falun"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateCustomer"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateCustomer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Skapad. `Location` pekar på den nya posten.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationCustomer"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "customers.write"
            ]
          }
        ]
      }
    },
    "/v1/customers/{id}": {
      "get": {
        "tags": [
          "Customers"
        ],
        "summary": "Hämta kund",
        "description": "`404` om kunden inte finns eller hör till en annan verkstad.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Postens id.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationCustomer"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "customers.read"
            ]
          }
        ]
      },
      "patch": {
        "tags": [
          "Customers"
        ],
        "summary": "Ändra kund",
        "description": "Skicka bara de fält som ska ändras. `null` tömmer ett fält. `firstName` och `lastName` kan inte tömmas. Fält som inte finns i kontraktet ger `400`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Postens id.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateCustomer"
              },
              "example": {
                "phone": "070-765 43 21",
                "company": null
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateCustomer"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateCustomer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationCustomer"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "customers.write"
            ]
          }
        ]
      }
    },
    "/v1/packages": {
      "get": {
        "tags": [
          "Packages"
        ],
        "summary": "Lista paket",
        "description": "Verkstadens aktiva paket i verkstadens egen ordning, med aktiva tillägg. Kommer på en sida: `nextCursor` är alltid `null`.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfIntegrationPackage"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "packages.read"
            ]
          }
        ]
      }
    },
    "/v1/storage-locations": {
      "get": {
        "tags": [
          "StorageLocations"
        ],
        "summary": "Lista lagerplatser",
        "description": "Alla lagerplatser sorterade på namn, även inaktiva. Kommer på en sida: `nextCursor` är alltid `null`. Bara lagrade uppsättningar tar plats.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfIntegrationStorageLocationDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "storage.read"
            ]
          }
        ]
      }
    },
    "/v1/vehicles": {
      "get": {
        "tags": [
          "Vehicles"
        ],
        "summary": "Lista fordon",
        "description": "Verkstadens fordon i ändringsordning, äldst först. Inaktiva fordon och fordon hos anonymiserade kunder ingår.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Antal poster per sida, 1–200. Standard 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "`nextCursor` från föregående sida, oförändrad.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "description": "Bara poster som skapats eller ändrats från och med den här tiden. ISO 8601 med tidszon, t.ex. `2026-10-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "externalId",
            "in": "query",
            "description": "Bara posten med ditt eget id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "customerId",
            "in": "query",
            "description": "Bara den här kundens poster.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "registrationNumber",
            "in": "query",
            "description": "Bara fordon med det här registreringsnumret. Blanksteg och gemener spelar ingen roll.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfIntegrationVehicle"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "vehicles.read"
            ]
          }
        ]
      },
      "post": {
        "tags": [
          "Vehicles"
        ],
        "summary": "Skapa fordon",
        "description": "Fordonet kopplas till en av verkstadens kunder. Registreringsnumret sparas med versaler och utan blanksteg. `409` om `externalId` redan används.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateVehicle"
              },
              "example": {
                "customerId": "0d5c3e2a-8f41-4b7e-9a63-2c1f0e7d4b58",
                "registrationNumber": "ABC123",
                "make": "Volvo",
                "model": "V60",
                "year": 2019
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateVehicle"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateVehicle"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Skapad. `Location` pekar på den nya posten.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationVehicle"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "vehicles.write"
            ]
          }
        ]
      }
    },
    "/v1/vehicles/{id}": {
      "get": {
        "tags": [
          "Vehicles"
        ],
        "summary": "Hämta fordon",
        "description": "`404` om fordonet inte finns eller hör till en annan verkstad.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Postens id.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationVehicle"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "vehicles.read"
            ]
          }
        ]
      },
      "patch": {
        "tags": [
          "Vehicles"
        ],
        "summary": "Ändra fordon",
        "description": "Skicka bara de fält som ska ändras. `null` tömmer ett fält. Med `customerId` flyttas fordonet till en annan kund. Om fordonet är aktivt styrs från Treadx och kan inte ändras här.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Postens id.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateVehicle"
              },
              "example": {
                "registrationNumber": "XYZ789",
                "vin": null
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateVehicle"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateVehicle"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationVehicle"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "vehicles.write"
            ]
          }
        ]
      }
    },
    "/v1/wheelsets": {
      "get": {
        "tags": [
          "Wheelsets"
        ],
        "summary": "Lista hjuluppsättningar",
        "description": "Hjuluppsättningar i ändringsordning, äldst först. Avslutade uppsättningar ingår. `updatedAt` ändras också när ett hjul eller lagerplatsen ändras, så ett nytt mönsterdjup kommer med i synken.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Antal poster per sida, 1–200. Standard 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "`nextCursor` från föregående sida, oförändrad.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "description": "Bara poster som skapats eller ändrats från och med den här tiden. ISO 8601 med tidszon, t.ex. `2026-10-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "vehicleId",
            "in": "query",
            "description": "Bara det här fordonets uppsättningar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "customerId",
            "in": "query",
            "description": "Bara den här kundens poster.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "season",
            "in": "query",
            "description": "Bara uppsättningar för säsongen: `Summer`, `WinterStudded` eller `WinterNonStudded`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "externalId",
            "in": "query",
            "description": "Bara posten med ditt eget id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfIntegrationWheelset"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "wheelsets.read"
            ]
          }
        ]
      },
      "post": {
        "tags": [
          "Wheelsets"
        ],
        "summary": "Registrera hjuluppsättning",
        "description": "Registrerar en uppsättning på ett av verkstadens fordon. `InStorage` läggs i lager och kräver en lagerplats med ledigt. `Mounted` sitter på bilen, högst en per fordon, och får sin plats vid hjulskiftet.\n\nAlla fyra hjul skickas, varje position en gång. Fordonets andra uppsättningar ändras aldrig. `409` när platsen är full, fordonet redan har en monterad uppsättning eller `externalId` används.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateWheelset"
              },
              "example": {
                "externalId": "DH-2041",
                "vehicleId": "7b2e4f19-3c8a-4d6e-b015-9e4a2c7f1d63",
                "season": "WinterStudded",
                "status": "InStorage",
                "storageLocationId": "4e8a1c27-6b3f-4f9d-8a52-1d7c9e3b0f46",
                "wheels": [
                  {
                    "position": "FrontLeft",
                    "tyreBrand": "Nokian",
                    "tyreModel": "Hakkapeliitta 10",
                    "tyreWidth": 205,
                    "tyreProfile": 55,
                    "rimDiameter": 16,
                    "treadDepthMm": 7.8
                  },
                  {
                    "position": "FrontRight",
                    "tyreBrand": "Nokian",
                    "tyreModel": "Hakkapeliitta 10",
                    "tyreWidth": 205,
                    "tyreProfile": 55,
                    "rimDiameter": 16,
                    "treadDepthMm": 7.9
                  },
                  {
                    "position": "RearLeft",
                    "tyreBrand": "Nokian",
                    "tyreModel": "Hakkapeliitta 10",
                    "tyreWidth": 205,
                    "tyreProfile": 55,
                    "rimDiameter": 16,
                    "treadDepthMm": 8.2
                  },
                  {
                    "position": "RearRight",
                    "tyreBrand": "Nokian",
                    "tyreModel": "Hakkapeliitta 10",
                    "tyreWidth": 205,
                    "tyreProfile": 55,
                    "rimDiameter": 16,
                    "treadDepthMm": 8.1
                  }
                ]
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateWheelset"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCreateWheelset"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Skapad. `Location` pekar på den nya posten.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationWheelset"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "wheelsets.write"
            ]
          }
        ]
      }
    },
    "/v1/wheelsets/{id}": {
      "patch": {
        "tags": [
          "Wheelsets"
        ],
        "summary": "Ändra hjuluppsättning",
        "description": "Ändrar hjul, lagerplats, paket eller `externalId` på en lagrad eller monterad uppsättning. Hjul anges per position och bara de fält som skickas ändras.\n\nBara en lagrad uppsättning kan flyttas, och bara till en plats med ledigt. En monterad uppsättning byter plats vid hjulskiftet, så ett försök att flytta den ger `409`. Säsong och status kan inte ändras här.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Postens id.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateWheelset"
              },
              "example": {
                "wheels": [
                  {
                    "position": "FrontLeft",
                    "tyreBrand": "Michelin",
                    "tyreModel": "Primacy 4",
                    "treadDepthMm": 8
                  }
                ]
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateWheelset"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationUpdateWheelset"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationWheelset"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "wheelsets.write"
            ]
          }
        ]
      },
      "get": {
        "tags": [
          "Wheelsets"
        ],
        "summary": "Hämta hjuluppsättning",
        "description": "En uppsättning med hjul och lagerplats. `404` om den inte finns eller hör till en annan verkstad.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Postens id.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationWheelset"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "wheelsets.read"
            ]
          }
        ]
      }
    },
    "/v1/vehicles/{vehicleId}/tyre-swap": {
      "post": {
        "tags": [
          "Wheelsets"
        ],
        "summary": "Hjulskifte",
        "description": "`mountWheelsetId` är den lagrade uppsättning som sätts på bilen. Den som tas av läggs i lager på platsen som frigörs. Ska den till en annan plats anges `removed.storageLocationId`.\n\nVid fordonets första skifte i Treadx är uppsättningen som tas av inte registrerad. Skicka då `removed.season` och alla fyra hjul, så skapas den.\n\nAllt sker i en transaktion. Ett skifte som skickas igen får `409` eftersom uppsättningen redan är monterad, så ett omförsök efter en timeout byter aldrig tillbaka hjulen.",
        "parameters": [
          {
            "name": "vehicleId",
            "in": "path",
            "description": "Bara det här fordonets uppsättningar.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationTyreSwap"
              },
              "example": {
                "mountWheelsetId": "9c3f7a12-5e8b-4d21-a6f0-3b9e1c4d7a85",
                "removed": {
                  "wheels": [
                    {
                      "position": "FrontLeft",
                      "treadDepthMm": 3.1
                    },
                    {
                      "position": "FrontRight",
                      "treadDepthMm": 3.4
                    }
                  ]
                }
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationTyreSwap"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationTyreSwap"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationTyreSwapResult"
                }
              }
            }
          },
          "400": {
            "description": "Ogiltig begäran. `errors` anger vilka fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Finns inte",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Krock eller fel läge. `errors` anger vilket fält.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Nyckel saknas eller är ogiltig",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Nyckeln saknar behörighet, eller verkstadens konto är stängt",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "För många anrop. Vänta det antal sekunder som `Retry-After` anger.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": [
              "wheelsets.write"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "IntegrationCreateCustomer": {
        "required": [
          "firstName",
          "lastName"
        ],
        "type": "object",
        "properties": {
          "firstName": {
            "maxLength": 100,
            "type": "string",
            "description": "Förnamn.",
            "example": "Anna"
          },
          "lastName": {
            "maxLength": 100,
            "type": "string",
            "description": "Efternamn.",
            "example": "Svensson"
          },
          "email": {
            "maxLength": 256,
            "type": "string",
            "description": "E-post. Måste vara ledig i verkstaden.",
            "nullable": true,
            "example": "anna.svensson@example.se"
          },
          "phone": {
            "maxLength": 50,
            "type": "string",
            "description": "Telefonnummer.",
            "nullable": true,
            "example": "070-123 45 67"
          },
          "company": {
            "maxLength": 200,
            "type": "string",
            "description": "Företagsnamn.",
            "nullable": true,
            "example": "Svenssons Bygg AB"
          },
          "address": {
            "maxLength": 500,
            "type": "string",
            "description": "Gatuadress.",
            "nullable": true,
            "example": "Storgatan 1"
          },
          "address2": {
            "maxLength": 500,
            "type": "string",
            "description": "Adressrad 2.",
            "nullable": true,
            "example": "Lgh 1102"
          },
          "postalCode": {
            "maxLength": 20,
            "type": "string",
            "description": "Postnummer.",
            "nullable": true,
            "example": "791 30"
          },
          "city": {
            "maxLength": 100,
            "type": "string",
            "description": "Ort.",
            "nullable": true,
            "example": "Falun"
          },
          "country": {
            "maxLength": 100,
            "type": "string",
            "description": "Land.",
            "nullable": true,
            "example": "Sverige"
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för kunden. Måste vara ledigt i verkstaden.",
            "nullable": true,
            "example": "K-10482"
          }
        },
        "description": "En ny kund."
      },
      "IntegrationCreateVehicle": {
        "required": [
          "customerId",
          "registrationNumber",
          "make",
          "model"
        ],
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "description": "En av verkstadens kunder. Annars `400`.",
            "format": "uuid"
          },
          "registrationNumber": {
            "maxLength": 20,
            "type": "string",
            "description": "Registreringsnummer. Sparas med versaler och utan blanksteg.",
            "example": "ABC123"
          },
          "make": {
            "maxLength": 100,
            "type": "string",
            "description": "Märke.",
            "example": "Volvo"
          },
          "model": {
            "maxLength": 100,
            "type": "string",
            "description": "Modell.",
            "example": "V60"
          },
          "year": {
            "maximum": 2100,
            "minimum": 1900,
            "type": "integer",
            "description": "Årsmodell.",
            "format": "int32",
            "nullable": true,
            "example": 2019
          },
          "vin": {
            "maxLength": 30,
            "type": "string",
            "description": "Chassinummer.",
            "nullable": true,
            "example": "YV1ZW72V0K1012345"
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för fordonet. Måste vara ledigt i verkstaden.",
            "nullable": true,
            "example": "K-10482"
          }
        },
        "description": "Ett nytt fordon."
      },
      "IntegrationCreateWheel": {
        "required": [
          "position"
        ],
        "type": "object",
        "properties": {
          "position": {
            "enum": [
              "FrontRight",
              "FrontLeft",
              "RearRight",
              "RearLeft"
            ],
            "type": "string",
            "description": "Position på bilen."
          },
          "rimType": {
            "enum": [
              "AluminiumOriginal",
              "AluminiumAccessory",
              "SteelRim"
            ],
            "type": "string",
            "description": "Fälgtyp.",
            "nullable": true
          },
          "tyreBrand": {
            "maxLength": 100,
            "type": "string",
            "description": "Däckmärke.",
            "nullable": true,
            "example": "Nokian"
          },
          "tyreModel": {
            "maxLength": 100,
            "type": "string",
            "description": "Däckmodell.",
            "nullable": true,
            "example": "Hakkapeliitta 10"
          },
          "tyreWidth": {
            "type": "integer",
            "description": "Däckbredd i mm.",
            "format": "int32",
            "nullable": true,
            "example": 205
          },
          "tyreProfile": {
            "type": "integer",
            "description": "Profil, höjden i procent av bredden.",
            "format": "int32",
            "nullable": true,
            "example": 55
          },
          "tyreConstruction": {
            "maxLength": 5,
            "type": "string",
            "description": "Konstruktion, t.ex. `R`.",
            "nullable": true,
            "example": "R"
          },
          "rimDiameter": {
            "type": "integer",
            "description": "Fälgdiameter i tum.",
            "format": "int32",
            "nullable": true,
            "example": 16
          },
          "loadIndex": {
            "type": "integer",
            "description": "Belastningsindex.",
            "format": "int32",
            "nullable": true,
            "example": 94
          },
          "speedIndex": {
            "maxLength": 5,
            "type": "string",
            "description": "Hastighetsindex.",
            "nullable": true,
            "example": "T"
          },
          "treadDepthMm": {
            "maximum": 30,
            "minimum": 0,
            "type": "number",
            "description": "Mönsterdjup i mm.",
            "format": "double",
            "nullable": true,
            "example": 7.8
          }
        },
        "description": "Ett hjul i en ny uppsättning."
      },
      "IntegrationCreateWheelset": {
        "required": [
          "vehicleId",
          "season",
          "status",
          "wheels"
        ],
        "type": "object",
        "properties": {
          "vehicleId": {
            "type": "string",
            "description": "Ett av verkstadens aktiva fordon.",
            "format": "uuid"
          },
          "season": {
            "enum": [
              "Summer",
              "WinterStudded",
              "WinterNonStudded"
            ],
            "type": "string",
            "description": "Säsong."
          },
          "status": {
            "enum": [
              "InStorage",
              "Mounted"
            ],
            "type": "string",
            "description": "`InStorage` för en uppsättning i lager, `Mounted` för den som sitter på bilen."
          },
          "storageLocationId": {
            "type": "string",
            "description": "Krävs för `InStorage`. Platsen måste ha ledigt. Utelämnas för `Mounted`.",
            "format": "uuid",
            "nullable": true
          },
          "packageId": {
            "type": "string",
            "description": "Däckhotellpaket.",
            "format": "uuid",
            "nullable": true
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för uppsättningen. Måste vara ledigt i verkstaden.",
            "nullable": true,
            "example": "K-10482"
          },
          "wheels": {
            "maxItems": 4,
            "minItems": 4,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationCreateWheel"
            },
            "description": "Alla fyra hjul, varje position en gång."
          }
        },
        "description": "En ny hjuluppsättning."
      },
      "IntegrationCustomer": {
        "required": [
          "id",
          "externalId",
          "firstName",
          "lastName",
          "email",
          "phone",
          "company",
          "address",
          "address2",
          "postalCode",
          "city",
          "country",
          "isActive",
          "createdAt",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Kundens id i Treadx.",
            "format": "uuid"
          },
          "externalId": {
            "type": "string",
            "description": "Ditt eget id för kunden, t.ex. kundnumret i ekonomisystemet. Unikt inom verkstaden.",
            "nullable": true,
            "example": "K-10482"
          },
          "firstName": {
            "type": "string",
            "description": "Förnamn.",
            "example": "Anna"
          },
          "lastName": {
            "type": "string",
            "description": "Efternamn.",
            "example": "Svensson"
          },
          "email": {
            "type": "string",
            "description": "E-post. Unik inom verkstaden när den finns.",
            "nullable": true,
            "example": "anna.svensson@example.se"
          },
          "phone": {
            "type": "string",
            "description": "Telefonnummer.",
            "nullable": true,
            "example": "070-123 45 67"
          },
          "company": {
            "type": "string",
            "description": "Företagsnamn.",
            "nullable": true,
            "example": "Svenssons Bygg AB"
          },
          "address": {
            "type": "string",
            "description": "Gatuadress.",
            "nullable": true,
            "example": "Storgatan 1"
          },
          "address2": {
            "type": "string",
            "description": "Adressrad 2.",
            "nullable": true,
            "example": "Lgh 1102"
          },
          "postalCode": {
            "type": "string",
            "description": "Postnummer.",
            "nullable": true,
            "example": "791 30"
          },
          "city": {
            "type": "string",
            "description": "Ort.",
            "nullable": true,
            "example": "Falun"
          },
          "country": {
            "type": "string",
            "description": "Land.",
            "nullable": true,
            "example": "Sverige"
          },
          "isActive": {
            "type": "boolean",
            "description": "`false` när kunden tagits bort i Treadx. Efter 30 dagar anonymiseras kunden: namn och kontaktuppgifter töms, `id` och `externalId` finns kvar."
          },
          "createdAt": {
            "type": "string",
            "description": "När kunden skapades.",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "description": "Senaste ändringen. Samma som `createdAt` om kunden aldrig ändrats.",
            "format": "date-time"
          }
        },
        "description": "En kund."
      },
      "IntegrationPackage": {
        "required": [
          "id",
          "name",
          "description",
          "price",
          "includesWash",
          "addons"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Paketets id.",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Namn.",
            "example": "Däckhotell Bas"
          },
          "description": {
            "type": "string",
            "description": "Beskrivning.",
            "nullable": true,
            "example": "Förvaring en säsong"
          },
          "price": {
            "type": "number",
            "description": "Pris i kronor, som verkstaden angett det.",
            "format": "double",
            "nullable": true,
            "example": 595
          },
          "includesWash": {
            "type": "boolean",
            "description": "Om tvätt ingår."
          },
          "addons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationPackageAddon"
            },
            "description": "Tillägg som kan väljas till paketet."
          }
        },
        "description": "Ett däckhotellpaket."
      },
      "IntegrationPackageAddon": {
        "required": [
          "name",
          "description"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Namn.",
            "example": "Hjultvätt"
          },
          "description": {
            "type": "string",
            "description": "Beskrivning.",
            "nullable": true,
            "example": "Tvätt av fälgar före förvaring"
          }
        },
        "description": "Ett tillägg till ett paket."
      },
      "IntegrationStorageLocation": {
        "required": [
          "id",
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Lagerplatsens id.",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Lagerplatsens namn.",
            "example": "B2-H4"
          }
        },
        "description": "Lagerplatsen uppsättningen har tilldelats. Den ligger kvar medan uppsättningen är monterad, så hjulen står där bara när `status` är `InStorage`. `null` när ingen plats är tilldelad.",
        "nullable": true
      },
      "IntegrationStorageLocationDetails": {
        "required": [
          "id",
          "name",
          "description",
          "isActive",
          "maxWheelsets",
          "storedWheelsets",
          "freePlaces"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Lagerplatsens id.",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Namn. Kan ändras i Treadx, så använd alltid `id`.",
            "example": "B2-H4"
          },
          "description": {
            "type": "string",
            "description": "Beskrivning.",
            "nullable": true,
            "example": "Hylla 4, rad B2"
          },
          "isActive": {
            "type": "boolean",
            "description": "Om platsen används."
          },
          "maxWheelsets": {
            "type": "integer",
            "description": "Antal uppsättningar platsen rymmer.",
            "format": "int32",
            "example": 4
          },
          "storedWheelsets": {
            "type": "integer",
            "description": "Antal uppsättningar i lager på platsen.",
            "format": "int32",
            "example": 3
          },
          "freePlaces": {
            "type": "integer",
            "description": "Lediga platser.",
            "format": "int32",
            "example": 1
          }
        },
        "description": "En lagerplats."
      },
      "IntegrationTyreSwap": {
        "required": [
          "mountWheelsetId"
        ],
        "type": "object",
        "properties": {
          "mountWheelsetId": {
            "type": "string",
            "description": "Den lagrade uppsättning som sätts på bilen.",
            "format": "uuid"
          },
          "removed": {
            "$ref": "#/components/schemas/IntegrationTyreSwapRemoved"
          },
          "mounted": {
            "$ref": "#/components/schemas/IntegrationTyreSwapMounted"
          }
        },
        "description": "Ett hjulskifte."
      },
      "IntegrationTyreSwapMounted": {
        "type": "object",
        "properties": {
          "wheels": {
            "type": "array",
            "items": {
              "description": "Ett hjul som ändras. Bara de fält som skickas ändras."
            },
            "description": "Ny data för hjulen som sätts på, t.ex. nya däck på fälgarna."
          }
        },
        "description": "Uppsättningen som sätts på. Bara hjulen kan ändras här.",
        "nullable": true
      },
      "IntegrationTyreSwapRemoved": {
        "type": "object",
        "properties": {
          "season": {
            "enum": [
              "Summer",
              "WinterStudded",
              "WinterNonStudded"
            ],
            "type": "string",
            "description": "Bara vid fordonets första skifte, när uppsättningen inte finns i Treadx. Då krävs också alla fyra hjul. Annars `409`."
          },
          "storageLocationId": {
            "type": "string",
            "description": "En annan plats än den som frigörs. Platsen måste ha ledigt.",
            "format": "uuid"
          },
          "packageId": {
            "type": "string",
            "description": "Däckhotellpaket.",
            "format": "uuid",
            "nullable": true
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för uppsättningen.",
            "nullable": true,
            "example": "K-10482"
          },
          "wheels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationUpdateWheel"
            },
            "description": "Ny data för hjulen som tas av, t.ex. slitage."
          }
        },
        "description": "Uppsättningen som tas av. Kan utelämnas om den redan finns i Treadx och inget ska ändras.",
        "nullable": true
      },
      "IntegrationTyreSwapResult": {
        "required": [
          "mounted",
          "stored"
        ],
        "type": "object",
        "properties": {
          "mounted": {
            "$ref": "#/components/schemas/IntegrationWheelset"
          },
          "stored": {
            "$ref": "#/components/schemas/IntegrationWheelset"
          }
        },
        "description": "Båda uppsättningarna efter skiftet: `mounted` sitter på bilen, `stored` ligger i lager."
      },
      "IntegrationUpdateCustomer": {
        "type": "object",
        "properties": {
          "firstName": {
            "maxLength": 100,
            "type": "string",
            "description": "Förnamn. Kan inte tömmas.",
            "example": "Anna"
          },
          "lastName": {
            "maxLength": 100,
            "type": "string",
            "description": "Efternamn. Kan inte tömmas.",
            "example": "Svensson"
          },
          "email": {
            "maxLength": 256,
            "type": "string",
            "description": "E-post. Måste vara ledig i verkstaden.",
            "nullable": true,
            "example": "anna.svensson@example.se"
          },
          "phone": {
            "maxLength": 50,
            "type": "string",
            "description": "Telefonnummer.",
            "nullable": true,
            "example": "070-123 45 67"
          },
          "company": {
            "maxLength": 200,
            "type": "string",
            "description": "Företagsnamn.",
            "nullable": true,
            "example": "Svenssons Bygg AB"
          },
          "address": {
            "maxLength": 500,
            "type": "string",
            "description": "Gatuadress.",
            "nullable": true,
            "example": "Storgatan 1"
          },
          "address2": {
            "maxLength": 500,
            "type": "string",
            "description": "Adressrad 2.",
            "nullable": true,
            "example": "Lgh 1102"
          },
          "postalCode": {
            "maxLength": 20,
            "type": "string",
            "description": "Postnummer.",
            "nullable": true,
            "example": "791 30"
          },
          "city": {
            "maxLength": 100,
            "type": "string",
            "description": "Ort.",
            "nullable": true,
            "example": "Falun"
          },
          "country": {
            "maxLength": 100,
            "type": "string",
            "description": "Land.",
            "nullable": true,
            "example": "Sverige"
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för kunden. Måste vara ledigt i verkstaden.",
            "nullable": true,
            "example": "K-10482"
          }
        },
        "description": "Fälten som ska ändras."
      },
      "IntegrationUpdateVehicle": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "description": "Flyttar fordonet till en annan av verkstadens kunder.",
            "format": "uuid"
          },
          "registrationNumber": {
            "maxLength": 20,
            "type": "string",
            "description": "Registreringsnummer. Kan inte tömmas.",
            "example": "ABC123"
          },
          "make": {
            "maxLength": 100,
            "type": "string",
            "description": "Märke. Kan inte tömmas.",
            "example": "Volvo"
          },
          "model": {
            "maxLength": 100,
            "type": "string",
            "description": "Modell. Kan inte tömmas.",
            "example": "V60"
          },
          "year": {
            "maximum": 2100,
            "minimum": 1900,
            "type": "integer",
            "description": "Årsmodell.",
            "format": "int32",
            "nullable": true,
            "example": 2019
          },
          "vin": {
            "maxLength": 30,
            "type": "string",
            "description": "Chassinummer.",
            "nullable": true,
            "example": "YV1ZW72V0K1012345"
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för fordonet. Måste vara ledigt i verkstaden.",
            "nullable": true,
            "example": "K-10482"
          }
        },
        "description": "Fälten som ska ändras."
      },
      "IntegrationUpdateWheel": {
        "required": [
          "position"
        ],
        "type": "object",
        "properties": {
          "position": {
            "enum": [
              "FrontRight",
              "FrontLeft",
              "RearRight",
              "RearLeft"
            ],
            "type": "string",
            "description": "Vilket hjul."
          },
          "rimType": {
            "enum": [
              "AluminiumOriginal",
              "AluminiumAccessory",
              "SteelRim"
            ],
            "type": "string",
            "description": "Fälgtyp.",
            "nullable": true
          },
          "tyreBrand": {
            "maxLength": 100,
            "type": "string",
            "description": "Däckmärke.",
            "nullable": true,
            "example": "Nokian"
          },
          "tyreModel": {
            "maxLength": 100,
            "type": "string",
            "description": "Däckmodell.",
            "nullable": true,
            "example": "Hakkapeliitta 10"
          },
          "tyreWidth": {
            "minimum": 0,
            "type": "integer",
            "description": "Däckbredd i mm.",
            "format": "int32",
            "nullable": true,
            "example": 205
          },
          "tyreProfile": {
            "minimum": 0,
            "type": "integer",
            "description": "Profil, höjden i procent av bredden.",
            "format": "int32",
            "nullable": true,
            "example": 55
          },
          "tyreConstruction": {
            "maxLength": 5,
            "type": "string",
            "description": "Konstruktion, t.ex. `R`.",
            "nullable": true,
            "example": "R"
          },
          "rimDiameter": {
            "minimum": 0,
            "type": "integer",
            "description": "Fälgdiameter i tum.",
            "format": "int32",
            "nullable": true,
            "example": 16
          },
          "loadIndex": {
            "minimum": 0,
            "type": "integer",
            "description": "Belastningsindex.",
            "format": "int32",
            "nullable": true,
            "example": 94
          },
          "speedIndex": {
            "maxLength": 5,
            "type": "string",
            "description": "Hastighetsindex.",
            "nullable": true,
            "example": "T"
          },
          "treadDepthMm": {
            "maximum": 30,
            "minimum": 0,
            "type": "number",
            "description": "Mönsterdjup i mm.",
            "format": "double",
            "nullable": true,
            "example": 7.8
          }
        },
        "description": "Ett hjul som ändras. Bara de fält som skickas ändras."
      },
      "IntegrationUpdateWheelset": {
        "type": "object",
        "properties": {
          "storageLocationId": {
            "type": "string",
            "description": "Flyttar en lagrad uppsättning. Platsen måste ha ledigt. Kan inte tömmas.",
            "format": "uuid"
          },
          "packageId": {
            "type": "string",
            "description": "Däckhotellpaket. `null` tar bort kopplingen.",
            "format": "uuid",
            "nullable": true
          },
          "externalId": {
            "maxLength": 100,
            "type": "string",
            "description": "Ditt eget id för uppsättningen. Måste vara ledigt i verkstaden.",
            "nullable": true,
            "example": "K-10482"
          },
          "wheels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationUpdateWheel"
            },
            "description": "Hjul som ska ändras, per position. En position som saknas läggs till."
          }
        },
        "description": "Fälten som ska ändras."
      },
      "IntegrationVehicle": {
        "required": [
          "id",
          "externalId",
          "customerId",
          "registrationNumber",
          "make",
          "model",
          "year",
          "vin",
          "isActive",
          "createdAt",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Fordonets id i Treadx.",
            "format": "uuid"
          },
          "externalId": {
            "type": "string",
            "description": "Ditt eget id för fordonet. Unikt inom verkstaden.",
            "nullable": true,
            "example": "F-2210"
          },
          "customerId": {
            "type": "string",
            "description": "Kunden som äger fordonet.",
            "format": "uuid"
          },
          "registrationNumber": {
            "type": "string",
            "description": "Registreringsnummer med versaler och utan blanksteg. När kunden anonymiseras blir det `ANON-…`.",
            "example": "ABC123"
          },
          "make": {
            "type": "string",
            "description": "Märke.",
            "example": "Volvo"
          },
          "model": {
            "type": "string",
            "description": "Modell.",
            "example": "V60"
          },
          "year": {
            "type": "integer",
            "description": "Årsmodell.",
            "format": "int32",
            "nullable": true,
            "example": 2019
          },
          "vin": {
            "type": "string",
            "description": "Chassinummer.",
            "nullable": true,
            "example": "YV1ZW72V0K1012345"
          },
          "isActive": {
            "type": "boolean",
            "description": "Om fordonet är aktivt. Styrs från Treadx."
          },
          "createdAt": {
            "type": "string",
            "description": "När fordonet skapades.",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "description": "Senaste ändringen.",
            "format": "date-time"
          }
        },
        "description": "Ett fordon."
      },
      "IntegrationWheel": {
        "required": [
          "id",
          "position",
          "rimType",
          "tyreBrand",
          "tyreModel",
          "tyreWidth",
          "tyreProfile",
          "tyreConstruction",
          "rimDiameter",
          "loadIndex",
          "speedIndex",
          "treadDepthMm"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Hjulets id.",
            "format": "uuid"
          },
          "position": {
            "enum": [
              "FrontRight",
              "FrontLeft",
              "RearRight",
              "RearLeft"
            ],
            "type": "string",
            "description": "Position på bilen."
          },
          "rimType": {
            "enum": [
              "AluminiumOriginal",
              "AluminiumAccessory",
              "SteelRim"
            ],
            "type": "string",
            "description": "Fälgtyp.",
            "nullable": true
          },
          "tyreBrand": {
            "type": "string",
            "description": "Däckmärke.",
            "nullable": true,
            "example": "Nokian"
          },
          "tyreModel": {
            "type": "string",
            "description": "Däckmodell.",
            "nullable": true,
            "example": "Hakkapeliitta 10"
          },
          "tyreWidth": {
            "type": "integer",
            "description": "Däckbredd i mm.",
            "format": "int32",
            "nullable": true,
            "example": 205
          },
          "tyreProfile": {
            "type": "integer",
            "description": "Profil, höjden i procent av bredden.",
            "format": "int32",
            "nullable": true,
            "example": 55
          },
          "tyreConstruction": {
            "type": "string",
            "description": "Konstruktion, t.ex. `R`.",
            "nullable": true,
            "example": "R"
          },
          "rimDiameter": {
            "type": "integer",
            "description": "Fälgdiameter i tum.",
            "format": "int32",
            "nullable": true,
            "example": 16
          },
          "loadIndex": {
            "type": "integer",
            "description": "Belastningsindex.",
            "format": "int32",
            "nullable": true,
            "example": 94
          },
          "speedIndex": {
            "type": "string",
            "description": "Hastighetsindex.",
            "nullable": true,
            "example": "T"
          },
          "treadDepthMm": {
            "type": "number",
            "description": "Mönsterdjup i mm, en decimal.",
            "format": "double",
            "nullable": true,
            "example": 7.8
          }
        },
        "description": "Ett hjul."
      },
      "IntegrationWheelset": {
        "required": [
          "id",
          "externalId",
          "vehicleId",
          "season",
          "status",
          "isActive",
          "storageLocation",
          "checkedOutAt",
          "wheels",
          "createdAt",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Uppsättningens id i Treadx.",
            "format": "uuid"
          },
          "externalId": {
            "type": "string",
            "description": "Ditt eget id för uppsättningen, t.ex. numret i ett tidigare system. Unikt inom verkstaden.",
            "nullable": true,
            "example": "DH-2041"
          },
          "vehicleId": {
            "type": "string",
            "description": "Fordonet uppsättningen hör till.",
            "format": "uuid"
          },
          "season": {
            "enum": [
              "Summer",
              "WinterStudded",
              "WinterNonStudded"
            ],
            "type": "string",
            "description": "Säsong.",
            "example": "WinterStudded"
          },
          "status": {
            "enum": [
              "Unknown",
              "Mounted",
              "InStorage",
              "ReturnedToCustomer"
            ],
            "type": "string",
            "description": "`InStorage` i lager, `Mounted` på bilen, `ReturnedToCustomer` utlämnad.",
            "example": "InStorage"
          },
          "isActive": {
            "type": "boolean",
            "description": "`false` när uppsättningen är avslutad i däckhotellet."
          },
          "storageLocation": {
            "$ref": "#/components/schemas/IntegrationStorageLocation"
          },
          "checkedOutAt": {
            "type": "string",
            "description": "När uppsättningen avslutades. `null` så länge den är aktiv.",
            "format": "date-time",
            "nullable": true
          },
          "wheels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationWheel"
            },
            "description": "Hjulen, ett per position."
          },
          "createdAt": {
            "type": "string",
            "description": "När uppsättningen registrerades.",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "description": "Senaste ändringen av uppsättningen, något hjul eller lagerplatsen.",
            "format": "date-time"
          }
        },
        "description": "En hjuluppsättning."
      },
      "PageOfIntegrationCustomer": {
        "required": [
          "data",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationCustomer"
            },
            "description": "Kunderna på sidan."
          },
          "nextCursor": {
            "type": "string",
            "description": "Skicka som `cursor` för nästa sida. `null` på sista sidan.",
            "nullable": true,
            "example": "eyJ1IjoiMjAyNi0xMC0wM1QxNDowMjoxMFoifQ"
          }
        },
        "description": "En sida kunder."
      },
      "PageOfIntegrationPackage": {
        "required": [
          "data",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationPackage"
            },
            "description": "Paketen."
          },
          "nextCursor": {
            "type": "string",
            "description": "Alltid `null`.",
            "nullable": true,
            "example": "eyJ1IjoiMjAyNi0xMC0wM1QxNDowMjoxMFoifQ"
          }
        },
        "description": "Alla aktiva paket."
      },
      "PageOfIntegrationStorageLocationDetails": {
        "required": [
          "data",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationStorageLocationDetails"
            },
            "description": "Lagerplatserna."
          },
          "nextCursor": {
            "type": "string",
            "description": "Alltid `null`.",
            "nullable": true,
            "example": "eyJ1IjoiMjAyNi0xMC0wM1QxNDowMjoxMFoifQ"
          }
        },
        "description": "Alla lagerplatser."
      },
      "PageOfIntegrationVehicle": {
        "required": [
          "data",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationVehicle"
            },
            "description": "Fordonen på sidan."
          },
          "nextCursor": {
            "type": "string",
            "description": "Skicka som `cursor` för nästa sida. `null` på sista sidan.",
            "nullable": true,
            "example": "eyJ1IjoiMjAyNi0xMC0wM1QxNDowMjoxMFoifQ"
          }
        },
        "description": "En sida fordon."
      },
      "PageOfIntegrationWheelset": {
        "required": [
          "data",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationWheelset"
            },
            "description": "Uppsättningarna på sidan."
          },
          "nextCursor": {
            "type": "string",
            "description": "Skicka som `cursor` för nästa sida. `null` på sista sidan.",
            "nullable": true,
            "example": "eyJ1IjoiMjAyNi0xMC0wM1QxNDowMjoxMFoifQ"
          }
        },
        "description": "En sida hjuluppsättningar."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Feltyp, t.ex. `https://treadx.se/problems/not-found`.",
            "nullable": true,
            "example": "https://treadx.se/problems/not-found"
          },
          "title": {
            "type": "string",
            "description": "Kort beskrivning. Kan ändras.",
            "nullable": true,
            "example": "Finns inte"
          },
          "status": {
            "type": "integer",
            "description": "HTTP-status.",
            "format": "int32",
            "nullable": true,
            "example": 404
          },
          "detail": {
            "type": "string",
            "description": "Mer information när den finns.",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "description": "Används inte.",
            "nullable": true
          }
        },
        "description": "Ett fel enligt RFC 9457. Bygg felhanteringen på `type`."
      },
      "ValidationProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Feltyp, t.ex. `https://treadx.se/problems/not-found`.",
            "nullable": true,
            "example": "https://treadx.se/problems/not-found"
          },
          "title": {
            "type": "string",
            "description": "Kort beskrivning. Kan ändras.",
            "nullable": true,
            "example": "Finns inte"
          },
          "status": {
            "type": "integer",
            "description": "HTTP-status.",
            "format": "int32",
            "nullable": true,
            "example": 404
          },
          "detail": {
            "type": "string",
            "description": "Mer information när den finns.",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "description": "Används inte.",
            "nullable": true
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Fältnamn och felmeddelanden. Nästlade fält skrivs som `wheels[0].treadDepthMm`."
          }
        },
        "description": "Ett fel med fältfel."
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "description": "API-nyckel som verkstaden skapar i Treadx. Skicka som 'Authorization: Bearer trx_live_…' (eller 'X-API-Key: trx_live_…').",
        "scheme": "bearer",
        "bearerFormat": "trx_live_…"
      }
    }
  },
  "security": [
    {
      "ApiKey": [ ]
    }
  ],
  "tags": [
    {
      "name": "Customers",
      "description": "Verkstadens kunder. Används för synk mot ekonomisystem eller CRM.",
      "x-displayName": "Kunder"
    },
    {
      "name": "Vehicles",
      "description": "Fordon kopplade till kunder.",
      "x-displayName": "Fordon"
    },
    {
      "name": "Wheelsets",
      "description": "Hjuluppsättningar med däck, mönsterdjup och lagerplats, och hjulskifte.",
      "x-displayName": "Hjuluppsättningar"
    },
    {
      "name": "StorageLocations",
      "description": "Verkstadens lagerplatser. Hämta id:n här när en hjuluppsättning ska registreras eller flyttas.",
      "x-displayName": "Lagerplatser"
    },
    {
      "name": "Packages",
      "description": "Verkstadens däckhotellpaket. Hämta id:n här när en hjuluppsättning ska kopplas till ett paket.",
      "x-displayName": "Paket"
    }
  ]
}
