{
  "openapi": "3.1.0",
  "info": {
    "title": "Zippex Delivery API",
    "version": "1.0.0-beta",
    "description": "REST API for requesting, tracking, and managing same-day deliveries via Zippex.",
    "contact": {
      "name": "Zippex Developer Support",
      "email": "support@zippex.com",
      "url": "https://docs.zippex.com"
    }
  },
  "servers": [
    { "url": "https://api.zippex.com", "description": "Production" },
    { "url": "https://sandbox.api.zippex.com", "description": "Sandbox (test mode)" }
  ],
  "security": [{ "bearerAuth": [] }],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key (zx_test_... or zx_live_...)"
      }
    },
    "schemas": {
      "Address": {
        "type": "object",
        "required": ["street", "city", "province", "postal_code"],
        "properties": {
          "street": { "type": "string" },
          "city": { "type": "string" },
          "province": { "type": "string" },
          "postal_code": { "type": "string" },
          "country": { "type": "string", "default": "CA" }
        }
      },
      "Quote": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "qt_r4s5t6u7" },
          "fee": { "type": "integer", "description": "Total fee in cents" },
          "currency": { "type": "string", "example": "cad" },
          "eta_minutes": { "type": "integer" },
          "distance_km": { "type": "number" },
          "expires_at": { "type": "string", "format": "date-time" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "del_m8n9o0p1" },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "pending",
              "driver_assigned",
              "driver_at_pickup",
              "picked_up",
              "in_transit",
              "delivered",
              "cancelled",
              "failed"
            ]
          },
          "fee": { "type": "integer" },
          "currency": { "type": "string", "example": "cad" },
          "pickup": {
            "type": "object",
            "properties": {
              "address": { "type": "string" },
              "name": { "type": "string" },
              "phone": { "type": "string" }
            }
          },
          "dropoff": {
            "type": "object",
            "properties": {
              "address": { "type": "string" },
              "name": { "type": "string" },
              "phone": { "type": "string" }
            }
          },
          "description": { "type": "string", "nullable": true },
          "metadata": {
            "type": "object",
            "additionalProperties": { "type": "string" }
          },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "Tracking": {
        "type": "object",
        "properties": {
          "delivery_id": { "type": "string" },
          "status": { "type": "string" },
          "driver": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "phone": { "type": "string" },
              "location": {
                "type": "object",
                "properties": {
                  "lat": { "type": "number" },
                  "lng": { "type": "number" }
                }
              }
            }
          },
          "eta_minutes": { "type": "integer" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "wh_abc123" },
          "url": { "type": "string", "format": "uri" },
          "events": {
            "type": "array",
            "items": { "type": "string" }
          },
          "secret": {
            "type": "string",
            "description": "HMAC-SHA256 signing secret. Returned once on creation."
          },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "type": { "type": "string" },
              "message": { "type": "string" },
              "request_id": { "type": "string" }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/merchants/register": {
      "post": {
        "summary": "Register a merchant account",
        "tags": ["Merchants"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["business_name", "email", "phone", "address"],
                "properties": {
                  "business_name": { "type": "string" },
                  "email": { "type": "string", "format": "email" },
                  "phone": { "type": "string" },
                  "address": { "$ref": "#/components/schemas/Address" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Created" },
          "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/v1/merchants/locations": {
      "get": {
        "summary": "List pickup locations",
        "tags": ["Merchants"],
        "responses": {
          "200": { "description": "OK" }
        }
      },
      "post": {
        "summary": "Add a pickup location",
        "tags": ["Merchants"],
        "responses": {
          "201": { "description": "Created" }
        }
      }
    },
    "/v1/quotes": {
      "post": {
        "summary": "Create a delivery quote",
        "tags": ["Quotes"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["pickup_address", "dropoff_address"],
                "properties": {
                  "pickup_address": { "type": "string" },
                  "dropoff_address": { "type": "string" },
                  "package_size": { "type": "string", "enum": ["small", "medium", "large"], "default": "small" },
                  "vehicle": { "type": "string", "enum": ["bike", "car", "van"] },
                  "scheduled_at": { "type": "string", "format": "date-time" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quote created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Quote" }
              }
            }
          },
          "400": { "description": "Bad request" },
          "401": { "description": "Unauthorized" }
        }
      }
    },
    "/v1/quotes/{quoteId}": {
      "get": {
        "summary": "Retrieve a quote",
        "tags": ["Quotes"],
        "parameters": [
          { "name": "quoteId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Quote",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Quote" } } }
          },
          "404": { "description": "Not found" },
          "410": { "description": "Quote expired" }
        }
      }
    },
    "/v1/deliveries": {
      "post": {
        "summary": "Create a delivery",
        "tags": ["Deliveries"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["quote_id", "pickup_name", "pickup_phone", "dropoff_name", "dropoff_phone"],
                "properties": {
                  "quote_id": { "type": "string" },
                  "pickup_name": { "type": "string" },
                  "pickup_phone": { "type": "string" },
                  "dropoff_name": { "type": "string" },
                  "dropoff_phone": { "type": "string" },
                  "description": { "type": "string" },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": { "type": "string" },
                    "maxProperties": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Delivery" } } }
          }
        }
      },
      "get": {
        "summary": "List deliveries",
        "tags": ["Deliveries"],
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "starting_after", "in": "query", "schema": { "type": "string" } },
          { "name": "status", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "OK" }
        }
      }
    },
    "/v1/deliveries/{deliveryId}": {
      "get": {
        "summary": "Retrieve a delivery",
        "tags": ["Deliveries"],
        "parameters": [
          { "name": "deliveryId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Delivery",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Delivery" } } }
          }
        }
      }
    },
    "/v1/deliveries/{deliveryId}/cancel": {
      "post": {
        "summary": "Cancel a delivery",
        "tags": ["Deliveries"],
        "parameters": [
          { "name": "deliveryId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Cancelled" },
          "409": { "description": "Cannot cancel — already in progress" }
        }
      }
    },
    "/v1/deliveries/{deliveryId}/tracking": {
      "get": {
        "summary": "Get delivery tracking",
        "tags": ["Tracking"],
        "parameters": [
          { "name": "deliveryId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Tracking snapshot",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Tracking" } } }
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "summary": "Register a webhook",
        "tags": ["Webhooks"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url", "events"],
                "properties": {
                  "url": { "type": "string", "format": "uri" },
                  "events": { "type": "array", "items": { "type": "string" } }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Webhook" } } }
          }
        }
      },
      "get": {
        "summary": "List webhooks",
        "tags": ["Webhooks"],
        "responses": { "200": { "description": "OK" } }
      }
    },
    "/v1/webhooks/{webhookId}": {
      "delete": {
        "summary": "Delete a webhook",
        "tags": ["Webhooks"],
        "parameters": [
          { "name": "webhookId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "204": { "description": "Deleted" } }
      }
    }
  }
}
