{
  "openapi": "3.1.0",
  "info": {
    "title": "TrackLogy API",
    "version": "1.0.0",
    "description": "REST API for TrackLogy — a shipment tracking platform for ecommerce brands.\n\nBase URL: `https://api.tracklogy.com/v1`\n\nFull documentation: https://docs.tracklogy.com/api-reference\n\n**Authentication**\n\nAll authenticated endpoints require an API key from the TrackLogy dashboard (my.tracklogy.com → Settings → API Keys). Send it as the `X-API-Key` request header.\n\n```\nX-API-Key: tlg_your_api_key_here\n```\n\n**Response envelope**\n\nEvery response is a JSON object:\n```json\n{ \"success\": true, \"data\": { ... } }\n```\nor on error:\n```json\n{ \"success\": false, \"error\": { \"code\": 422, \"message\": \"tracking_number is required\" } }\n```\n\n**Rate limits**\n\n600 requests per 10-minute window per API key. Every response includes:\n- `RateLimit-Limit` — max requests in window\n- `RateLimit-Remaining` — requests left\n- `RateLimit-Reset` — Unix timestamp when window resets\n\nOn `429 Too Many Requests`, a `Retry-After` header gives seconds to wait.\n\n**Versioning**\n\nURL path versioning (`/v1`, `/v2`…). Minimum 12-month deprecation notice. Deprecated endpoints carry `Deprecation` and `Sunset` headers (RFC 8594). Policy: https://tracklogy.com/legal/api-versioning/",
    "contact": {
      "name": "TrackLogy Support",
      "url": "https://tracklogy.com/contact",
      "email": "info@tracklogy.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://tracklogy.com/legal/terms/"
    },
    "x-deprecation-policy": "https://tracklogy.com/legal/api-versioning/",
    "x-versioning-policy": "URL path versioning (/v1, /v2…). Minimum 12-month deprecation notice. Sunset and Deprecation headers on deprecated endpoints (RFC 8594)."
  },
  "servers": [
    {
      "url": "https://api.tracklogy.com/v1",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Shipments",
      "description": "Create, list, retrieve, and update shipments."
    },
    {
      "name": "Carriers",
      "description": "Browse and detect supported carriers."
    },
    {
      "name": "Public",
      "description": "Unauthenticated endpoints — no API key required."
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key from TrackLogy dashboard → Settings → API Keys."
      },
      "ScopedAccess": {
        "type": "oauth2",
        "description": "Named permission scopes. TrackLogy authenticates via X-API-Key; these scopes declare least-privilege access.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://api.tracklogy.com/oauth/token",
            "scopes": {
              "shipments:read": "Read shipment list and tracking events",
              "shipments:write": "Create and update shipments",
              "carriers:read": "Read the supported carrier directory",
              "notifications:write": "Trigger delivery notification emails to customers"
            }
          }
        }
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Maximum requests allowed in the current window.",
        "schema": { "type": "integer", "example": 600 }
      },
      "RateLimitRemaining": {
        "description": "Requests remaining in the current window.",
        "schema": { "type": "integer", "example": 598 }
      },
      "RateLimitReset": {
        "description": "Unix timestamp when the rate-limit window resets.",
        "schema": { "type": "integer", "example": 1756147200 }
      },
      "Sunset": {
        "description": "ISO 8601 date after which this endpoint version is removed. Present only on deprecated endpoints.",
        "schema": { "type": "string", "format": "date", "example": "2027-09-01" }
      },
      "Deprecation": {
        "description": "ISO 8601 date when this endpoint was deprecated. See https://tracklogy.com/legal/api-versioning/",
        "schema": { "type": "string", "format": "date", "example": "2026-09-01" }
      }
    },
    "responses": {
      "TooManyRequests": {
        "description": "Rate limit exceeded. Back off until Retry-After elapses.",
        "headers": {
          "Retry-After": { "description": "Seconds to wait before retrying.", "schema": { "type": "integer", "example": 60 } },
          "RateLimit-Limit":     { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset":     { "$ref": "#/components/headers/RateLimitReset" }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean", "example": false },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": { "type": "integer", "example": 429 },
                    "message": { "type": "string", "example": "Rate limit exceeded. Retry after 60 seconds." }
                  }
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Shipment": {
        "type": "object",
        "description": "A tracked shipment record.",
        "properties": {
          "id": { "type": "integer", "example": 1234 },
          "tracking_number": { "type": "string", "example": "1Z999AA10123456784" },
          "tracking_provider": { "type": "string", "nullable": true, "example": "ups" },
          "status": {
            "type": "string",
            "enum": ["pending", "unknown", "pre_transit", "in_transit", "available_for_pickup", "out_for_delivery", "delivered", "failure", "on_hold", "exception", "return_to_sender", "cancelled", "expired"],
            "example": "in_transit"
          },
          "carrier_name": { "type": "string", "nullable": true, "example": "UPS" },
          "order_id": { "type": "string", "nullable": true, "example": "ORD-5001" },
          "customer_email": { "type": "string", "format": "email", "nullable": true },
          "est_delivery_date": { "type": "string", "format": "date", "nullable": true, "example": "2026-09-05" },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": { "type": "string", "example": "in_transit" },
                "description": { "type": "string", "example": "Package arrived at facility" },
                "location": { "type": "string", "nullable": true, "example": "Chicago, IL" },
                "event_at": { "type": "string", "format": "date-time" }
              }
            }
          },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Carrier": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 7 },
          "name": { "type": "string", "example": "FedEx" },
          "slug": { "type": "string", "example": "fedex" },
          "website": { "type": "string", "nullable": true, "example": "https://www.fedex.com" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "integer", "example": 422 },
              "message": { "type": "string", "example": "tracking_number is required" }
            }
          }
        }
      }
    }
  },
  "security": [
    { "ApiKeyAuth": [], "ScopedAccess": ["shipments:read"] }
  ],
  "paths": {
    "/api/shipments": {
      "post": {
        "tags": ["Shipments"],
        "operationId": "createShipment",
        "summary": "Create a shipment",
        "description": "Add a new shipment for tracking. TrackLogy auto-detects the carrier if `tracking_provider` is omitted.",
        "security": [{ "ApiKeyAuth": [], "ScopedAccess": ["shipments:write"] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tracking_number", "store_name"],
                "properties": {
                  "tracking_number": { "type": "string", "example": "1Z999AA10123456784" },
                  "store_name": { "type": "string", "example": "My Store" },
                  "tracking_provider": { "type": "string", "example": "ups", "description": "Carrier slug. Auto-detected if omitted." },
                  "order_id": { "type": "string", "example": "ORD-5001" },
                  "customer_email": { "type": "string", "format": "email", "example": "customer@example.com" },
                  "est_delivery_date": { "type": "string", "format": "date", "example": "2026-09-05" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Shipment created.",
            "headers": {
              "RateLimit-Limit":     { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset":     { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "type": "object", "properties": { "shipment": { "$ref": "#/components/schemas/Shipment" } } }
                  }
                }
              }
            }
          },
          "422": { "description": "Validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      },
      "get": {
        "tags": ["Shipments"],
        "operationId": "listShipments",
        "summary": "List shipments",
        "description": "Returns a paginated list of all shipments for the authenticated account.",
        "security": [{ "ApiKeyAuth": [], "ScopedAccess": ["shipments:read"] }],
        "parameters": [
          { "name": "store_name", "in": "query", "required": true, "schema": { "type": "string" }, "example": "My Store" },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "maximum": 100 } }
        ],
        "responses": {
          "200": {
            "description": "Paginated shipment list.",
            "headers": {
              "RateLimit-Limit":     { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset":     { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "object",
                      "properties": {
                        "shipments": { "type": "array", "items": { "$ref": "#/components/schemas/Shipment" } },
                        "total": { "type": "integer", "example": 142 },
                        "page": { "type": "integer", "example": 1 }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/shipments/show": {
      "get": {
        "tags": ["Shipments"],
        "operationId": "getShipment",
        "summary": "Get a shipment",
        "description": "Retrieve a single shipment by tracking number or internal ID.",
        "security": [{ "ApiKeyAuth": [], "ScopedAccess": ["shipments:read"] }],
        "parameters": [
          { "name": "store_name", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "tracking_number", "in": "query", "schema": { "type": "string" }, "example": "1Z999AA10123456784" },
          { "name": "id", "in": "query", "schema": { "type": "integer" }, "example": 1234 }
        ],
        "responses": {
          "200": {
            "description": "Shipment found.",
            "headers": {
              "RateLimit-Limit":     { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset":     { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "type": "object", "properties": { "shipment": { "$ref": "#/components/schemas/Shipment" } } }
                  }
                }
              }
            }
          },
          "404": { "description": "Shipment not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/carriers": {
      "get": {
        "tags": ["Carriers"],
        "operationId": "listCarriers",
        "summary": "List supported carriers",
        "description": "Returns all carriers supported by TrackLogy.",
        "security": [{ "ApiKeyAuth": [], "ScopedAccess": ["carriers:read"] }],
        "parameters": [
          { "name": "q", "in": "query", "schema": { "type": "string" }, "example": "fedex" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "maximum": 200 } }
        ],
        "responses": {
          "200": {
            "description": "Carrier list.",
            "headers": {
              "RateLimit-Limit":     { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset":     { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "type": "object", "properties": { "carriers": { "type": "array", "items": { "$ref": "#/components/schemas/Carrier" } } } }
                  }
                }
              }
            }
          },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/public/carriers/detect": {
      "post": {
        "tags": ["Public"],
        "operationId": "detectCarrier",
        "summary": "Detect carrier from tracking number",
        "description": "Identify the carrier for a tracking number using pattern matching. No authentication required.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tracking_number"],
                "properties": {
                  "tracking_number": { "type": "string", "example": "1Z999AA10123456784" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Detection result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": { "type": "string", "enum": ["matched", "no_match"], "example": "matched" },
                        "carrier": { "$ref": "#/components/schemas/Carrier" }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
