{
  "openapi": "3.1.1",
  "info": {
    "title": "Trackbay Integration API",
    "description": "REST API for integrating your own systems with Trackbay orders and deliveries.\n\n## Authentication\nSend your integration key in the `X-API-Key` header on every request:\n\n```\nX-API-Key: tbk_live_xxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nA key is created by a Tenant Admin (in the field app) or by Grafokett support. The full key is shown **once** at creation - store it securely. A revoked key stops working immediately. Every key is scoped to a single tenant; it can never read or change another tenant's data, and it cannot reach any admin/user-management endpoint.\n\n## Rate limiting\nUp to **60 requests per minute per key**. Exceeding it returns `429 Too Many Requests` with a `Retry-After` header (seconds to wait).",
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://trackbay-api-jyee.onrender.com/"
    }
  ],
  "paths": {
    "/api/public/v1/deliveries/{id}": {
      "get": {
        "tags": [
          "PublicDeliveries"
        ],
        "summary": "A single delivery with its full tracking history. 404 if it does not\nexist or belongs to a different tenant (indistinguishable by design).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDeliveryResponse"
                },
                "example": {
                  "id": "3c1a8f2e-1d4b-4c9a-9f2e-8a7b6c5d4e3f",
                  "orderId": "6f9619ff-8b86-d011-b42d-00cf4fc964ff",
                  "status": "Queued",
                  "isArchived": false,
                  "isPartial": false,
                  "createdAtUtc": "2026-09-02T11:00:00Z",
                  "updatedAtUtc": "2026-09-02T11:05:00Z",
                  "history": [
                    {
                      "status": "Queued",
                      "occurredAtUtc": "2026-09-02T11:05:00Z"
                    },
                    {
                      "status": "Queued",
                      "occurredAtUtc": "2026-09-02T11:00:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/orders/{orderId}/delivery": {
      "get": {
        "tags": [
          "PublicDeliveries"
        ],
        "summary": "The delivery for a given order (orders and deliveries are 1:1). 404 if\nthe order has no delivery, doesn't exist, or belongs to a different\ntenant (all indistinguishable by design).",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDeliveryResponse"
                },
                "example": {
                  "id": "3c1a8f2e-1d4b-4c9a-9f2e-8a7b6c5d4e3f",
                  "orderId": "6f9619ff-8b86-d011-b42d-00cf4fc964ff",
                  "status": "Queued",
                  "isArchived": false,
                  "isPartial": false,
                  "createdAtUtc": "2026-09-02T11:00:00Z",
                  "updatedAtUtc": "2026-09-02T11:05:00Z",
                  "history": [
                    {
                      "status": "Queued",
                      "occurredAtUtc": "2026-09-02T11:05:00Z"
                    },
                    {
                      "status": "Queued",
                      "occurredAtUtc": "2026-09-02T11:00:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/deliveries/{id}/status": {
      "patch": {
        "tags": [
          "PublicDeliveries"
        ],
        "summary": "Updates a delivery's status. 400 on an invalid transition, 404 if the\ndelivery doesn't exist/belongs to another tenant.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateDeliveryStatusRequest"
              },
              "example": {
                "status": "InTransit"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateDeliveryStatusRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateDeliveryStatusRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDeliveryResponse"
                },
                "example": {
                  "id": "3c1a8f2e-1d4b-4c9a-9f2e-8a7b6c5d4e3f",
                  "orderId": "6f9619ff-8b86-d011-b42d-00cf4fc964ff",
                  "status": "InTransit",
                  "isArchived": false,
                  "isPartial": false,
                  "createdAtUtc": "2026-09-02T11:00:00Z",
                  "updatedAtUtc": "2026-09-02T11:05:00Z",
                  "history": [
                    {
                      "status": "InTransit",
                      "occurredAtUtc": "2026-09-02T11:05:00Z"
                    },
                    {
                      "status": "Queued",
                      "occurredAtUtc": "2026-09-02T11:00:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/orders": {
      "get": {
        "tags": [
          "PublicOrders"
        ],
        "summary": "Lists every order for the key's tenant, newest first. Product lines are omitted here - fetch a single order for those.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicOrderResponse"
                  }
                },
                "example": [
                  {
                    "id": "6f9619ff-8b86-d011-b42d-00cf4fc964ff",
                    "orderNumber": "ORD-10432",
                    "status": "Registered",
                    "source": "Erp",
                    "isArchived": false,
                    "isBlocked": false,
                    "createdAtUtc": "2026-09-01T08:15:00Z",
                    "updatedAtUtc": "2026-09-01T08:15:00Z",
                    "products": null
                  }
                ]
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "PublicOrders"
        ],
        "summary": "Creates an order for the key's tenant. 409 if the order number is already used within that tenant.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateOrderRequest"
              },
              "example": {
                "orderNumber": "ORD-10432"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateOrderRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicCreateOrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicOrderResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/orders/{id}": {
      "get": {
        "tags": [
          "PublicOrders"
        ],
        "summary": "A single order, including its product lines with picked/remaining\nquantities. 404 if it does not exist or belongs to a different tenant\n(indistinguishable by design).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicOrderResponse"
                },
                "example": {
                  "id": "6f9619ff-8b86-d011-b42d-00cf4fc964ff",
                  "orderNumber": "ORD-10432",
                  "status": "Registered",
                  "source": "Erp",
                  "isArchived": false,
                  "isBlocked": false,
                  "createdAtUtc": "2026-09-01T08:15:00Z",
                  "updatedAtUtc": "2026-09-01T08:15:00Z",
                  "products": [
                    {
                      "productId": "SKU-4471",
                      "description": "Winter jacket, navy, L",
                      "identificationCode": "7350012340001",
                      "orderedQuantity": 12,
                      "registeredQuantity": 8,
                      "remainingQuantity": 4
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/orders/{id}/status": {
      "patch": {
        "tags": [
          "PublicOrders"
        ],
        "summary": "Updates an order's status. 400 on an invalid transition, 404 if the\norder doesn't exist/belongs to another tenant, 409 if the order is\ncurrently blocked or archived.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateOrderStatusRequest"
              },
              "example": {
                "status": "Confirmed"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateOrderStatusRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PublicUpdateOrderStatusRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicOrderResponse"
                },
                "example": {
                  "id": "6f9619ff-8b86-d011-b42d-00cf4fc964ff",
                  "orderNumber": "ORD-10432",
                  "status": "Confirmed",
                  "source": "Erp",
                  "isArchived": false,
                  "isBlocked": false,
                  "createdAtUtc": "2026-09-01T08:15:00Z",
                  "updatedAtUtc": "2026-09-01T08:15:00Z",
                  "products": null
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "DeliveryStatus": {
        "type": "integer"
      },
      "OrderStatus": {
        "type": "integer"
      },
      "PublicCreateOrderRequest": {
        "required": [
          "orderNumber"
        ],
        "type": "object",
        "properties": {
          "orderNumber": {
            "maxLength": 64,
            "type": "string",
            "description": "Human-readable order identifier, unique within the API key's tenant. The tenant is never taken from the body - it comes from the key."
          }
        },
        "description": "Body for `POST /api/public/v1/orders` - see MVP2-SCOPE.md section C (\"skapa ... Orders\")."
      },
      "PublicDeliveryResponse": {
        "required": [
          "id",
          "orderId",
          "status",
          "isArchived",
          "isPartial",
          "createdAtUtc",
          "updatedAtUtc",
          "history"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "orderId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "isArchived": {
            "type": "boolean"
          },
          "isPartial": {
            "type": "boolean",
            "description": "True if the delivery was created from an order that had not reached full ordered quantity."
          },
          "createdAtUtc": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAtUtc": {
            "type": "string",
            "format": "date-time"
          },
          "history": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicDeliveryStatusEventResponse"
            },
            "description": "Status history, newest first."
          }
        },
        "description": "Public integration API (v1) representation of a delivery, including its\ntracking-history \"Trace Line\" - see MVP2-SCOPE.md section C. Stable\nexternal contract, mapped from the domain deliberately (see\nPublicOrderResponse's remarks)."
      },
      "PublicDeliveryStatusEventResponse": {
        "required": [
          "status",
          "occurredAtUtc"
        ],
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "occurredAtUtc": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Public integration API (v1) representation of one tracking-history entry."
      },
      "PublicOrderProductResponse": {
        "required": [
          "productId",
          "description",
          "identificationCode",
          "orderedQuantity",
          "registeredQuantity",
          "remainingQuantity"
        ],
        "type": "object",
        "properties": {
          "productId": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "identificationCode": {
            "type": "string",
            "description": "The identifying value carried by the product's logistic-unit QR/barcode."
          },
          "orderedQuantity": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "registeredQuantity": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many logistic units have been scanned/registered against this product so far.",
            "format": "int32"
          },
          "remainingQuantity": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "int PublicOrderProductResponse.OrderedQuantity minus int PublicOrderProductResponse.RegisteredQuantity, never negative.",
            "format": "int32"
          }
        },
        "description": "Public integration API (v1) representation of a single product line on an order."
      },
      "PublicOrderResponse": {
        "required": [
          "id",
          "orderNumber",
          "status",
          "source",
          "isArchived",
          "isBlocked",
          "createdAtUtc",
          "updatedAtUtc"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "orderNumber": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Where the order originated: `Manual` or `Erp`."
          },
          "isArchived": {
            "type": "boolean",
            "description": "When true, status updates are rejected until an operator unarchives the order."
          },
          "isBlocked": {
            "type": "boolean",
            "description": "When true, status updates are rejected until an operator unblocks the order."
          },
          "createdAtUtc": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAtUtc": {
            "type": "string",
            "format": "date-time"
          },
          "products": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PublicOrderProductResponse"
            },
            "description": "The order's products with their picked/remaining quantities.\n`null` in the list representation (`GET /orders`);\npopulated (possibly empty) in the detail representation\n(`GET /orders/{id}`)."
          }
        },
        "description": "Public integration API (v1) representation of an order - see MVP2-SCOPE.md\nsection C. This is a STABLE EXTERNAL CONTRACT: it is mapped from the\ndomain deliberately (not the internal `OrderResponse`) so that\ninternal refactors cannot silently change what a customer integration\nsees. Add fields here only additively; never remove or repurpose one\nwithout versioning the surface (`/api/public/v2`)."
      },
      "PublicUpdateDeliveryStatusRequest": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "status": {
            "description": "Target status: `Queued`, `InTransit`, `Delivered` or `Exception`. Delivery status changes are closed (creating the delivery fulfils the order), so every request returns 400.",
            "$ref": "#/components/schemas/DeliveryStatus"
          }
        },
        "description": "Body for `PATCH /api/public/v1/deliveries/{id}/status` - see MVP2-SCOPE.md section C (\"uppdatera Delivery-status\")."
      },
      "PublicUpdateOrderStatusRequest": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "status": {
            "description": "Target status: `Registered`, `Confirmed`, `Fulfilled` or `Cancelled`. Invalid transitions return 400.",
            "$ref": "#/components/schemas/OrderStatus"
          }
        },
        "description": "Body for `PATCH /api/public/v1/orders/{id}/status` - see MVP2-SCOPE.md section C (\"uppdatera ... Orders\")."
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "description": "Your Trackbay integration key, sent as the `X-API-Key` request header.",
        "name": "X-API-Key",
        "in": "header"
      }
    }
  },
  "security": [
    {
      "ApiKey": [ ]
    }
  ],
  "tags": [
    {
      "name": "PublicDeliveries"
    },
    {
      "name": "PublicOrders"
    }
  ]
}