{
  "openapi": "3.1.0",
  "info": {
    "title": "Terra Drive Delivery API",
    "version": "1.0.0",
    "description": "Book local delivery by independent drivers on the Terra Drive network (A&A Terra Inc). Amounts are US dollars as decimal numbers; timestamps are ISO 8601 UTC. Human docs: /developers.",
    "contact": {
      "name": "A&A Terra Inc",
      "email": "support@aaterrainc.com"
    }
  },
  "servers": [
    {
      "url": "https://drive.aaterrainc.com",
      "description": "Production"
    },
    {
      "url": "http://localhost:4340",
      "description": "Local demo server"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Quotes"
    },
    {
      "name": "Deliveries"
    },
    {
      "name": "Webhooks"
    },
    {
      "name": "Zones"
    }
  ],
  "paths": {
    "/v1/quotes": {
      "post": {
        "tags": [
          "Quotes"
        ],
        "operationId": "createQuote",
        "summary": "Create a quote",
        "description": "Prices a delivery from your saved restaurant address to the drop-off. Valid for 10 minutes; pass `quote_id` when creating the delivery to lock the fee.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Quote created",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/deliveries": {
      "post": {
        "tags": [
          "Deliveries"
        ],
        "operationId": "createDelivery",
        "summary": "Create a delivery",
        "description": "`payment.collect=false`: dispatch starts now and fee + tip + $1.00 is charged to you. `payment.collect=true`: the response has a hosted `pay_url`; dispatch starts when the customer pays.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeliveryRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Delivery created (or an Idempotency-Key replay, flagged by `Idempotent-Replayed: true`)",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "get": {
        "tags": [
          "Deliveries"
        ],
        "operationId": "listDeliveries",
        "summary": "List deliveries",
        "description": "Newest first, only objects of the calling key's mode (test or live). Page with `starting_after` = the `next_starting_after` of the previous page until `has_more` is false.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "One status, a comma-separated list, or `active` (every not-finished state).",
            "example": "delivered"
          },
          {
            "name": "external_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "starting_after",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A delivery id from the previous page (cursor)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of deliveries",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/deliveries/{id}": {
      "get": {
        "tags": [
          "Deliveries"
        ],
        "operationId": "getDelivery",
        "summary": "Retrieve a delivery",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Our delivery id (`dlv_…`) or your `external_id` (newest match wins).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The delivery",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/deliveries/{id}/cancel": {
      "post": {
        "tags": [
          "Deliveries"
        ],
        "operationId": "cancelDelivery",
        "summary": "Cancel a delivery",
        "description": "Allowed until delivered. Before pickup: no fees. After pickup: the driver is still paid the delivery fee − $0.99 driver service fee. Already cancelled or delivered → 409 `invalid_state`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Our delivery id (`dlv_…`) or your `external_id` (newest match wins).",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 200,
                    "example": "customer_request"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The cancelled delivery",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/webhooks/test": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "sendTestWebhook",
        "summary": "Send a signed webhook.test event",
        "description": "Posts to the webhook URL saved in Portal → Webhooks and waits (up to ~12 s) for the first attempt. A failed test event is retried like any other event.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Attempt result",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTest"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/zones": {
      "get": {
        "tags": [
          "Zones"
        ],
        "operationId": "listZones",
        "summary": "List service zones",
        "description": "Public, no-key version: GET /api/zones.",
        "responses": {
          "200": {
            "description": "Zones",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "object",
                    "data"
                  ],
                  "properties": {
                    "object": {
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Zone"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "webhooks": {
    "deliveryEvent": {
      "post": {
        "summary": "Delivery event",
        "description": "Sent for delivery.created, delivery.assigned, delivery.picked_up, delivery.delivered, delivery.cancelled, delivery.no_driver and delivery.updated (paid, dispatching, at_pickup, at_dropoff…), plus webhook.test. Verify `TerraDrive-Signature` over the raw body. Answer 2xx within 10 s; otherwise we retry after 5 s, 30 s and 2 min (4 attempts). Events can repeat or arrive out of order: dedupe on `id`, and ignore a snapshot whose `data.updated_at` is older than the one you already hold.",
        "parameters": [
          {
            "name": "TerraDrive-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "t=1762452131,v1=5f2b0c…",
            "description": "v1 = hex HMAC-SHA256(secret, `${t}.${raw_body}`). Reject t older than 5 minutes."
          },
          {
            "name": "TerraDrive-Event",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "TerraDrive-Event-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "TerraDrive-Delivery-Attempt",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 4
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else (or no answer in 10 s) is retried."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`td_test_…` (simulated drivers, no money moves) or `td_live_…`. Create keys in Portal → API keys."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 255
        },
        "description": "Retry-safe POST. Same key + same body within 24 h replays the original response (header `Idempotent-Replayed: true`). Same key with a different body, method or path → 422 `idempotency_mismatch`; while the first request still runs → 409 `idempotency_in_progress`. Responses below 500 (other than 409/429) are replayed too."
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "schema": {
          "type": "integer"
        },
        "description": "Requests allowed per minute per key (120)."
      },
      "X-RateLimit-Remaining": {
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "schema": {
          "type": "integer"
        },
        "description": "Unix seconds when the oldest request in the 60 s window expires (one more slot frees up)."
      },
      "Retry-After": {
        "schema": {
          "type": "integer"
        },
        "description": "Seconds to wait."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "`invalid_json`, `invalid_request` or `missing_field`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "`unauthorized` — missing, invalid or revoked key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "`not_found` — no such object for this key (other restaurants' and other-mode objects are never visible).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "`invalid_state` or `idempotency_in_progress`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unprocessable": {
        "description": "`outside_service_area`, `out_of_range`, `geocode_failed`, `no_pickup_location`, `invalid_quote`, `quote_expired`, `quote_mismatch`, `idempotency_mismatch`, `no_webhook`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "`rate_limited`",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/X-RateLimit-Limit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/X-RateLimit-Remaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/X-RateLimit-Reset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ServerError": {
        "description": "`server_error` — safe to retry with the same Idempotency-Key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "missing_field"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "Point": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 300,
            "description": "Free-text address, geocoded with OpenStreetMap."
          },
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "description": "Either `address`, or both `lat` and `lng` (coordinates skip geocoding)."
      },
      "QuoteRequest": {
        "type": "object",
        "required": [
          "dropoff"
        ],
        "properties": {
          "dropoff": {
            "$ref": "#/components/schemas/Point"
          },
          "order_value": {
            "type": "number",
            "minimum": 0,
            "description": "Food + tax."
          },
          "pickup": {
            "type": "object",
            "description": "Reserved for multi-location accounts; ignored today (pickup = your saved address)."
          }
        }
      },
      "Quote": {
        "type": "object",
        "required": [
          "object",
          "quote_id",
          "fee",
          "distance_mi",
          "expires_at"
        ],
        "properties": {
          "object": {
            "const": "quote"
          },
          "quote_id": {
            "type": "string",
            "example": "qt_8mX2kQ0aB1cD3eF4"
          },
          "fee": {
            "type": "number",
            "example": 6.33
          },
          "distance_mi": {
            "type": "number"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "dropoff": {
            "type": "object",
            "properties": {
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              },
              "address": {
                "type": "string"
              }
            }
          },
          "restaurant_fee": {
            "type": "number",
            "example": 1
          },
          "fee_rule": {
            "type": "string"
          }
        }
      },
      "Item": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 99,
            "default": 1
          },
          "price": {
            "type": "number"
          }
        }
      },
      "DeliveryRequest": {
        "type": "object",
        "required": [
          "dropoff"
        ],
        "properties": {
          "quote_id": {
            "type": "string",
            "description": "Locks the quoted fee. The drop-off may then be omitted (the quote's is used) or must match it."
          },
          "external_id": {
            "type": "string",
            "maxLength": 100,
            "description": "Your order number. Never shown to drivers."
          },
          "pickup_notes": {
            "type": "string",
            "maxLength": 500
          },
          "dropoff": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Point"
              },
              {
                "type": "object",
                "required": [
                  "name",
                  "phone"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "phone": {
                    "type": "string",
                    "description": "E.164 or US format."
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            ]
          },
          "order_value": {
            "type": "number",
            "minimum": 0,
            "maximum": 10000,
            "description": "Food + tax. Required (> 0) when payment.collect is true."
          },
          "tip": {
            "type": "number",
            "minimum": 0,
            "maximum": 500,
            "description": "100% to the driver."
          },
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "payment": {
            "type": "object",
            "properties": {
              "collect": {
                "type": "boolean",
                "default": false
              }
            }
          }
        }
      },
      "Driver": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "first_name": {
            "type": "string"
          },
          "vehicle": {
            "type": "string"
          },
          "lat": {
            "type": [
              "number",
              "null"
            ],
            "description": "Live only while the delivery is active."
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "Delivery": {
        "type": "object",
        "required": [
          "object",
          "id",
          "status",
          "livemode",
          "fee",
          "tip",
          "tracking_url",
          "events",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "object": {
            "const": "delivery"
          },
          "id": {
            "type": "string",
            "example": "dlv_Q2w3E4r5T6y7U8i9"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "created",
              "paid",
              "dispatching",
              "assigned",
              "at_pickup",
              "picked_up",
              "at_dropoff",
              "delivered",
              "cancelled",
              "no_driver"
            ]
          },
          "livemode": {
            "type": "boolean"
          },
          "restaurant": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "address": {
                "type": "string"
              },
              "lat": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "lng": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "pickup_notes": {
            "type": "string"
          },
          "dropoff": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "phone_masked": {
                "type": "string",
                "example": "(•••) •••-0123"
              },
              "address": {
                "type": "string"
              },
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              },
              "notes": {
                "type": "string"
              }
            }
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "order_value": {
            "type": "number"
          },
          "fee": {
            "type": "number"
          },
          "tip": {
            "type": "number"
          },
          "driver_pay": {
            "type": ["number", "null"],
            "description": "fee + tip − driver_fee. null until a driver is assigned (it depends on whether the driver is a Founding Driver) — see driver_pay_status"
          },
          "driver_pay_status": {
            "type": "string",
            "enum": ["pending_assignment", "final"]
          },
          "restaurant_fee": {
            "type": "number"
          },
          "driver_fee": {
            "type": ["number", "null"],
            "description": "0.99, or 0 for a Founding Driver; null until a driver is assigned"
          },
          "distance_mi": {
            "type": "number"
          },
          "driver": {
            "$ref": "#/components/schemas/Driver"
          },
          "tracking_url": {
            "type": "string",
            "format": "uri"
          },
          "pay_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "paid": {
            "type": "boolean"
          },
          "proof": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "photo_url": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "gps_ok": {
                "type": "boolean"
              }
            }
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string"
                },
                "at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "enum": [
              "api",
              "portal",
              "phone",
              "sim"
            ]
          },
          "collect_payment": {
            "type": "boolean"
          },
          "payout_held": {
            "type": "boolean"
          },
          "cancel_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "\"<who>: <reason>\", e.g. \"api: customer_request\"."
          },
          "split": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "customer_total": {
                "type": "number"
              },
              "card_processing": {
                "type": "number"
              },
              "restaurant_card_fee": {
                "type": "number"
              },
              "restaurant_net": {
                "type": "number"
              },
              "restaurant_charge": {
                "type": "number"
              },
              "driver_pay": {
                "type": "number"
              }
            }
          }
        }
      },
      "DeliveryList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "has_more"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Delivery"
            }
          },
          "count": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_starting_after": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "WebhookTest": {
        "type": "object",
        "properties": {
          "object": {
            "const": "webhook_test"
          },
          "ok": {
            "type": "boolean"
          },
          "result": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "event_id": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "url": {
                "type": "string"
              },
              "status_code": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "ok": {
                "type": "boolean"
              },
              "attempts": {
                "type": "integer"
              },
              "error": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      },
      "Zone": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "status": {
            "enum": [
              "live",
              "coming_soon",
              "waitlist"
            ]
          },
          "center": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              }
            }
          },
          "radius_mi": {
            "type": [
              "number",
              "null"
            ]
          },
          "polygon": {
            "description": "GeoJSON polygon or null"
          }
        }
      },
      "Event": {
        "type": "object",
        "required": [
          "id",
          "object",
          "type",
          "livemode",
          "created",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_…"
          },
          "object": {
            "const": "event"
          },
          "type": {
            "type": "string",
            "example": "delivery.picked_up"
          },
          "livemode": {
            "type": "boolean"
          },
          "created": {
            "type": "integer",
            "description": "Unix seconds"
          },
          "data": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Delivery"
              },
              {
                "type": "object",
                "description": "webhook.test: {message, sent_at}"
              }
            ]
          }
        }
      }
    }
  }
}
