{
  "openapi": "3.0.3",
  "info": {
    "title": "GO Delivery API",
    "version": "1.1.0",
    "description": "Request parcel deliveries from GO drivers for your commerce platform's users. Server to server only. Money is NGN (whole naira). Responses are wrapped as `{ \"success\": true, \"data\": ... }`; errors as `{ \"success\": false, \"error\": { \"code\", \"message\" } }`. The token endpoint returns a plain OAuth 2.0 body. See docs/GO_DELIVERY_API.md. v1.1: non-expiring go_live_/go_test_ keys (Authorization: Bearer or x-api-key), paid plans with feature gating (403 PLAN_FEATURE_REQUIRED, 402 SUBSCRIPTION_REQUIRED), vehicle types, binding quotes, scheduled delivery, per-plan rate limits and usage, signed webhooks (X-GO-Signature and GO-Signature). Public docs: https://go.mendifier.com/developers"
  },
  "servers": [
    {
      "url": "https://api.go.mendifier.com/api",
      "description": "Production (confirm the exact host with GO)"
    }
  ],
  "tags": [
    {
      "name": "Auth"
    },
    {
      "name": "Users"
    },
    {
      "name": "Deliveries"
    },
    {
      "name": "Webhooks"
    },
    {
      "name": "Billing"
    },
    {
      "name": "Developer dashboard",
      "description": "Sign-up, keys, plan and billing for partner companies. Used by https://go.mendifier.com/developers/dashboard; the bearer token is the dashboard token from /login."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "A go_live_\u2026 / go_test_\u2026 key (never expires; revoke it to stop it), an earlier gk_\u2026 key, or a 1-hour access token from POST /v1/oauth/token"
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "The same go_live_\u2026 / go_test_\u2026 key, as a header instead of Authorization: Bearer"
      }
    },
    "schemas": {
      "Place": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "example": "12 Herbert Macaulay Way, Yaba, Lagos"
          },
          "lat": {
            "type": "number",
            "example": 6.5095
          },
          "lng": {
            "type": "number",
            "example": 3.3711
          }
        },
        "required": [
          "address",
          "lat",
          "lng"
        ]
      },
      "Pickup": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Place"
          },
          {
            "type": "object",
            "properties": {
              "contact_name": {
                "type": "string",
                "example": "Ngozi at the counter"
              },
              "contact_phone": {
                "type": "string",
                "example": "08031234567"
              }
            }
          }
        ]
      },
      "Parcel": {
        "type": "object",
        "properties": {
          "size": {
            "type": "string",
            "example": "small",
            "description": "small = bike, medium = car, large = van",
            "enum": [
              "small",
              "medium",
              "large"
            ]
          },
          "description": {
            "type": "string",
            "example": "Two shirts"
          }
        },
        "required": [
          "size"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "external_user_id": {
            "type": "string",
            "example": "usr_8321"
          },
          "name": {
            "type": "string",
            "example": "Ngozi Okafor"
          },
          "phone": {
            "type": "string",
            "example": "08031234567"
          },
          "email": {
            "type": "string",
            "example": "ngozi@example.com"
          },
          "phone_verified": {
            "type": "boolean",
            "example": true
          },
          "verification_level": {
            "type": "string",
            "example": "phone",
            "enum": [
              "none",
              "phone",
              "email",
              "kyc"
            ]
          },
          "consent_accepted": {
            "type": "boolean",
            "example": true,
            "description": "Required (true) in live mode"
          },
          "consent_terms_ref": {
            "type": "string",
            "example": "terms-2026-10"
          },
          "consent_accepted_at": {
            "type": "string",
            "example": "2026-10-28T09:00:00Z",
            "format": "date-time"
          },
          "pickup_addresses": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Place"
                },
                {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "contact_name": {
                      "type": "string"
                    },
                    "contact_phone": {
                      "type": "string"
                    }
                  }
                }
              ]
            }
          }
        },
        "required": [
          "external_user_id",
          "name",
          "consent_accepted"
        ]
      },
      "Recipient": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Chinedu Eze"
          },
          "phone": {
            "type": "string",
            "example": "08091234567"
          }
        },
        "required": [
          "name",
          "phone"
        ]
      },
      "QuoteRequest": {
        "type": "object",
        "properties": {
          "pickup": {
            "$ref": "#/components/schemas/Place"
          },
          "dropoff": {
            "$ref": "#/components/schemas/Place"
          },
          "parcel": {
            "$ref": "#/components/schemas/Parcel",
            "description": "Optional. size small = motorcycle, medium = car, large = van."
          },
          "vehicle_type": {
            "type": "string",
            "description": "Quote just this vehicle. Must be in your plan (403 PLAN_FEATURE_REQUIRED otherwise)."
          },
          "scheduled_for": {
            "type": "string",
            "format": "date-time",
            "description": "Later pickup, 15 minutes to 30 days ahead. Plans with scheduled delivery only."
          }
        },
        "required": [
          "pickup",
          "dropoff"
        ]
      },
      "Quote": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "quote"
          },
          "price": {
            "type": "object",
            "properties": {
              "amount": {
                "type": "integer",
                "example": 2150
              },
              "currency": {
                "type": "string",
                "example": "NGN"
              }
            }
          },
          "distance_km": {
            "type": "number",
            "example": 14.2
          },
          "estimated_duration_min": {
            "type": "integer",
            "example": 43
          },
          "parcel_size": {
            "type": "string"
          },
          "surge": {
            "type": "number",
            "example": 1
          },
          "valid_for_seconds": {
            "type": "integer",
            "example": 600
          },
          "note": {
            "type": "string"
          },
          "id": {
            "type": "string",
            "example": "qte_a1b2c3d4e"
          },
          "binding": {
            "type": "boolean",
            "example": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "vehicle_type": {
            "type": "string"
          },
          "scheduled_for": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "vehicle_quotes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "vehicle_type": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "icon": {
                  "type": "string"
                },
                "available": {
                  "type": "boolean"
                },
                "quote_id": {
                  "type": "string"
                },
                "price": {
                  "type": "object",
                  "properties": {
                    "amount": {
                      "type": "integer"
                    },
                    "currency": {
                      "type": "string"
                    }
                  }
                },
                "estimated_duration_min": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "CreateDelivery": {
        "type": "object",
        "properties": {
          "partner_ref": {
            "type": "string",
            "example": "ORD-10492"
          },
          "pickup": {
            "$ref": "#/components/schemas/Pickup"
          },
          "dropoff": {
            "$ref": "#/components/schemas/Place"
          },
          "recipient": {
            "$ref": "#/components/schemas/Recipient"
          },
          "parcel": {
            "$ref": "#/components/schemas/Parcel"
          },
          "notify_recipient": {
            "type": "boolean",
            "example": true
          },
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "quote_id": {
            "type": "string",
            "description": "Book at this binding quote. Single use. QUOTE_EXPIRED, QUOTE_USED, QUOTE_MISMATCH otherwise."
          },
          "vehicle_type": {
            "type": "string"
          },
          "scheduled_for": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "partner_ref",
          "pickup",
          "dropoff",
          "recipient"
        ],
        "description": "Cash on delivery is not supported in v1; unknown fields are rejected."
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "dlv_abc123"
          },
          "object": {
            "type": "string",
            "example": "delivery"
          },
          "livemode": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "example": "assigned",
            "enum": [
              "pending",
              "assigned",
              "picked_up",
              "in_transit",
              "delivered",
              "cancelled",
              "failed"
            ]
          },
          "status_detail": {
            "type": "string",
            "example": "driver_on_the_way",
            "nullable": true
          },
          "partner_ref": {
            "type": "string"
          },
          "external_user_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "pickup": {
            "$ref": "#/components/schemas/Pickup"
          },
          "dropoff": {
            "$ref": "#/components/schemas/Place"
          },
          "recipient": {
            "$ref": "#/components/schemas/Recipient"
          },
          "parcel": {
            "$ref": "#/components/schemas/Parcel"
          },
          "price": {
            "type": "object",
            "properties": {
              "amount": {
                "type": "integer"
              },
              "currency": {
                "type": "string",
                "example": "NGN"
              },
              "quoted_amount": {
                "type": "integer"
              },
              "final": {
                "type": "boolean"
              },
              "cancellation_fee": {
                "type": "integer"
              }
            }
          },
          "distance_km": {
            "type": "number"
          },
          "estimated_duration_min": {
            "type": "integer"
          },
          "codes": {
            "type": "object",
            "properties": {
              "pickup": {
                "type": "string",
                "example": "4821",
                "description": "Give to the driver at pickup"
              },
              "dropoff": {
                "type": "string",
                "example": "7305",
                "description": "The recipient gives it to the driver at hand-over"
              }
            }
          },
          "driver": {
            "type": "object",
            "nullable": true,
            "properties": {
              "first_name": {
                "type": "string"
              },
              "rating": {
                "type": "number"
              },
              "vehicle": {
                "type": "object",
                "properties": {
                  "make": {
                    "type": "string"
                  },
                  "model": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  },
                  "plate": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "location": {
            "type": "object",
            "nullable": true,
            "properties": {
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "tracking_url": {
            "type": "string",
            "nullable": true,
            "description": "Public page for the recipient (live mode)"
          },
          "proof": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "stage": {
                  "type": "string",
                  "enum": [
                    "pickup",
                    "dropoff"
                  ]
                },
                "url": {
                  "type": "string"
                },
                "at": {
                  "type": "string"
                }
              }
            }
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string"
                },
                "at": {
                  "type": "string"
                }
              }
            }
          },
          "delivered_at": {
            "type": "string",
            "nullable": true
          },
          "cancellation": {
            "type": "object",
            "nullable": true
          },
          "failure": {
            "type": "object",
            "nullable": true
          },
          "vehicle_type": {
            "type": "string"
          },
          "quote_id": {
            "type": "string",
            "nullable": true
          },
          "scheduled_for": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "cancel_window": {
            "type": "object",
            "nullable": true,
            "properties": {
              "free_until": {
                "type": "string",
                "format": "date-time"
              },
              "free_now": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "DeliveryList": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Delivery"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "pages": {
                "type": "integer"
              }
            }
          }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_x"
          },
          "object": {
            "type": "string",
            "example": "event"
          },
          "type": {
            "type": "string",
            "example": "delivery.delivered",
            "enum": [
              "delivery.assigned",
              "delivery.picked_up",
              "delivery.in_transit",
              "delivery.delivered",
              "delivery.cancelled",
              "delivery.failed",
              "webhook.test"
            ]
          },
          "created": {
            "type": "string",
            "format": "date-time"
          },
          "livemode": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/Delivery"
              }
            }
          }
        },
        "description": "POSTed to your webhook URL with headers GO-Signature (t=<unix>,v1=<hmac_sha256(secret, t + '.' + rawBody)>), GO-Event-Id, GO-Event-Type. Reply 2xx; otherwise GO retries after 30s, 2m, 10m, 1h, 6h."
      },
      "Token": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "example": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "example": 3600
          },
          "mode": {
            "type": "string",
            "example": "live"
          }
        }
      },
      "UserLink": {
        "type": "object",
        "properties": {
          "external_user_id": {
            "type": "string"
          },
          "link": {
            "type": "string",
            "enum": [
              "created",
              "matched_phone",
              "unverified",
              "test"
            ]
          },
          "verified": {
            "type": "boolean"
          },
          "verification_level": {
            "type": "string"
          },
          "verification_source": {
            "type": "string"
          },
          "created": {
            "type": "boolean"
          }
        }
      },
      "Statement": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "livemode": {
            "type": "boolean"
          },
          "currency": {
            "type": "string",
            "example": "NGN"
          },
          "count": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "delivery_id": {
                  "type": "string"
                },
                "partner_ref": {
                  "type": "string"
                },
                "external_user_id": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "date": {
                  "type": "string"
                },
                "distance_km": {
                  "type": "number"
                },
                "amount": {
                  "type": "integer"
                },
                "currency": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "PLAN_FEATURE_REQUIRED"
              },
              "message": {
                "type": "string"
              },
              "feature": {
                "type": "string",
                "example": "scheduled"
              },
              "current_plan": {
                "type": "string"
              },
              "required_plan": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "VehicleType": {
        "type": "object",
        "properties": {
          "vehicle_type": {
            "type": "string",
            "example": "motorcycle"
          },
          "name": {
            "type": "string"
          },
          "icon": {
            "type": "string",
            "description": "Phosphor icon name"
          },
          "description": {
            "type": "string"
          },
          "max_weight_kg": {
            "type": "integer"
          },
          "volume_hint": {
            "type": "string"
          }
        }
      },
      "VehicleTypes": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "vehicle_types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VehicleType"
            }
          },
          "not_in_plan": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "vehicle_type": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "required_plan": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "scheduling": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "min_lead_minutes": {
                "type": "integer",
                "example": 15
              },
              "max_days_ahead": {
                "type": "integer",
                "example": 30
              },
              "free_cancel_until_minutes_before": {
                "type": "integer",
                "example": 60
              }
            }
          },
          "features": {
            "type": "object"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/oauth/token": {
      "post": {
        "summary": "Get a 1-hour access token (client credentials or signed JWT assertion)",
        "tags": [
          "Auth"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "example": "client_credentials",
                    "enum": [
                      "client_credentials",
                      "urn:ietf:params:oauth:grant-type:jwt-bearer"
                    ]
                  },
                  "client_id": {
                    "type": "string",
                    "example": "gcp_..."
                  },
                  "client_secret": {
                    "type": "string",
                    "example": "gk_live_..."
                  },
                  "assertion": {
                    "type": "string",
                    "description": "RS256/ES256 JWT: iss=sub=client_id, aud=go-delivery, exp<=5 min, unique jti"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ]
                  }
                },
                "required": [
                  "grant_type"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Token"
                }
              }
            }
          },
          "401": {
            "description": "invalid_client"
          }
        }
      }
    },
    "/v1/delivery/quotes": {
      "post": {
        "summary": "Quote: price and estimated time",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        }
      }
    },
    "/v1/delivery/users": {
      "post": {
        "summary": "Connect a platform user (GO creates or links their GO account)",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserLink"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/User"
              }
            }
          }
        }
      }
    },
    "/v1/delivery/users/{externalUserId}": {
      "get": {
        "summary": "Link status for a platform user",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserLink"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "parameters": [
          {
            "name": "externalUserId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/delivery/deliveries": {
      "post": {
        "summary": "Create a delivery",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDelivery"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "8-200 chars (a UUID). Retrying with the same key never creates a second delivery."
          },
          {
            "name": "X-GO-User",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Your platform user id (the delivery is booked for, and scoped to, that user)",
            "required": true
          }
        ]
      },
      "get": {
        "summary": "List deliveries",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "parameters": [
          {
            "name": "X-GO-User",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Your platform user id (the delivery is booked for, and scoped to, that user)"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "partner_ref",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ]
      }
    },
    "/v1/delivery/deliveries/{id}": {
      "get": {
        "summary": "Get a delivery: status, driver, vehicle, live location, tracking, proof",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dlv_abc123"
          },
          {
            "name": "X-GO-User",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Your platform user id (the delivery is booked for, and scoped to, that user)"
          }
        ]
      }
    },
    "/v1/delivery/deliveries/{id}/cancel": {
      "post": {
        "summary": "Cancel (until pickup, same rules as the GO app)",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dlv_abc123"
          },
          {
            "name": "X-GO-User",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Your platform user id (the delivery is booked for, and scoped to, that user)"
          }
        ]
      }
    },
    "/v1/delivery/deliveries/{id}/simulate": {
      "post": {
        "summary": "Test mode only: advance a test delivery and fire its webhook",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string",
                    "enum": [
                      "assigned",
                      "picked_up",
                      "in_transit",
                      "delivered",
                      "failed",
                      "cancelled"
                    ]
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dlv_abc123"
          },
          {
            "name": "X-GO-User",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Your platform user id (the delivery is booked for, and scoped to, that user)"
          }
        ]
      }
    },
    "/v1/delivery/webhook": {
      "get": {
        "summary": "Your webhook URL",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "secret_set": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        }
      },
      "put": {
        "summary": "Set the HTTPS webhook URL",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "example": "https://shop.example.com/hooks/go"
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/delivery/webhook/rotate-secret": {
      "post": {
        "summary": "New signing secret (shown once)",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        }
      }
    },
    "/v1/delivery/webhooks/test": {
      "post": {
        "summary": "Send a signed test event now",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "delivered": {
                      "type": "boolean"
                    },
                    "status_code": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "duration_ms": {
                      "type": "integer"
                    },
                    "event_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        }
      }
    },
    "/v1/delivery/webhook-events": {
      "get": {
        "summary": "Webhook delivery log with attempts",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "parameters": [
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "failed"
              ]
            }
          }
        ]
      }
    },
    "/v1/delivery/statement": {
      "get": {
        "summary": "Billing statement of delivered live deliveries (json or csv)",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Statement"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "429": {
            "description": "Rate limit exceeded (Retry-After header)"
          }
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ]
            }
          },
          {
            "name": "X-GO-User",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Your platform user id (the delivery is booked for, and scoped to, that user)"
          }
        ]
      }
    },
    "/v1/delivery/vehicle-types": {
      "get": {
        "summary": "Delivery vehicles your plan includes, what needs an upgrade, and the scheduling rules",
        "tags": [
          "Deliveries"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VehicleTypes"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "402": {
            "description": "SUBSCRIPTION_REQUIRED: live keys need an active plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "PLAN_FEATURE_REQUIRED: your plan does not include this",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED (Retry-After header)"
          }
        }
      }
    },
    "/v1/delivery/usage": {
      "get": {
        "summary": "Usage report: API calls per key and day, deliveries and fares for a period (plans with usage reports)",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid credential"
          },
          "402": {
            "description": "SUBSCRIPTION_REQUIRED: live keys need an active plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "PLAN_FEATURE_REQUIRED: your plan does not include this",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED (Retry-After header)"
          }
        }
      }
    },
    "/v1/developers/plans": {
      "get": {
        "summary": "Public: plans, vehicle catalogue and feature rows (the pricing page renders this)",
        "tags": [
          "Developer dashboard"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/signup": {
      "post": {
        "summary": "Create a company account with a free test key. Needs accept_terms. Rate limited.",
        "tags": [
          "Developer dashboard"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "company",
                  "name",
                  "email",
                  "password",
                  "accept_terms"
                ],
                "properties": {
                  "company": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 10
                  },
                  "website": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "accept_terms": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "201": {
            "description": "Created: token, test_key (shown once), webhook_secret (shown once)"
          }
        }
      }
    },
    "/v1/developers/login": {
      "post": {
        "summary": "Sign in. Returns a 12-hour dashboard token.",
        "tags": [
          "Developer dashboard"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/me": {
      "get": {
        "summary": "Plan, usage, keys, invoices, webhook and vehicles for the signed-in company",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/subscribe": {
      "post": {
        "summary": "Start a plan checkout (Paystack). Returns authorization_url.",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "plan_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/billing/verify": {
      "post": {
        "summary": "Confirm a payment by reference (idempotent)",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reference": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/invoices/{id}/pay": {
      "post": {
        "summary": "Pay an open invoice (Paystack)",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/subscription/cancel": {
      "post": {
        "summary": "Cancel at the end of the current period",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/keys": {
      "post": {
        "summary": "Issue a key. Live keys need an approved partner, a paid plan and room in the plan key allowance.",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ]
                  },
                  "label": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/keys/{id}/rotate": {
      "post": {
        "summary": "Replace a key. The old key stops at once. The new secret is shown once.",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/keys/{id}": {
      "delete": {
        "summary": "Revoke a key",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/webhook": {
      "put": {
        "summary": "Set the webhook URL (plans with webhooks)",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/developers/webhook/rotate-secret": {
      "post": {
        "summary": "New webhook signing secret, shown once",
        "tags": [
          "Developer dashboard"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}
