{
  "openapi": "3.0.3",
  "info": {
    "title": "InspectExpert API",
    "description": "Book vehicle inspections, read the completed inspection report, and cancel bookings. Interactive docs: https://developer.algodriven.xyz/inspectexpert\n\nAn inspection is booked for a customer and a vehicle at one of the rooftop's InspectExpert services. An inspector then completes it in the InspectExpert app, and the report becomes readable through `GET /axle-api/inspection`. There are no InspectExpert webhooks: poll the inspection and watch `status`.\n\n**Auth:** send your API key as the raw `Authorization` header (no `Bearer` prefix).\n\n**One key per rooftop.** InspectExpert keys are bound to a single rooftop and every call runs as that rooftop. `X-Dealer-Id` is not supported: inspection creation resolves the rooftop from the key alone, so a multi-rooftop partner key cannot book inspections. InspectExpert keys are issued by AlgoDriven rather than self-served from the Developer portal; contact support@algodriven.xyz.\n\n**No sandbox.** Every call reads and writes live inspections. Ask AlgoDriven for a test rooftop before integrating.\n\n**Service and location ids** (`serviceId`, `locationName`) come from the rooftop's InspectExpert setup in the AlgoDriven dashboard (Services and Locations pages).",
    "version": "1.0.0",
    "contact": {
      "name": "AlgoDriven",
      "url": "https://algodriven.xyz/developers/",
      "email": "support@algodriven.xyz"
    }
  },
  "servers": [
    {
      "url": "https://evalexpert.io/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Inspections",
      "description": "Book an inspection, read its report, or cancel it."
    },
    {
      "name": "Account",
      "description": "Check which rooftop a key acts as."
    }
  ],
  "paths": {
    "/axle-api/inspection": {
      "get": {
        "tags": [
          "Inspections"
        ],
        "summary": "Get an inspection",
        "description": "Return one inspection for the key's rooftop, including the report once the inspector has completed it.\n\nCanceled inspections are not returned (404). Timestamps (`bookingDate`, `createdAt`, `completed`) are Unix epoch **milliseconds**.\n\nThe report section (`categoryInformation`, `categoriesStatus`) is keyed by the category names configured on the rooftop's service, so its shape varies between rooftops.",
        "operationId": "getInspection",
        "parameters": [
          {
            "name": "inspectionId",
            "in": "query",
            "required": true,
            "description": "The `inspectionId` returned by `POST /axle-api/inspection`.",
            "schema": {
              "type": "string"
            },
            "example": "3f9c2a7be41d4c0e9a51b6d2f08e7c13"
          }
        ],
        "responses": {
          "200": {
            "description": "The inspection",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Inspection"
                }
              }
            }
          },
          "404": {
            "description": "No inspection with this id on the key's rooftop, or it was canceled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "error": "inspection not found",
                  "code": 404
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/InvalidKey"
          }
        }
      },
      "post": {
        "tags": [
          "Inspections"
        ],
        "summary": "Book an inspection",
        "description": "Create an inspection on the key's rooftop with status `Pending`.\n\nThe `c*` fields describe the customer who owns the vehicle; the `v*` contact fields describe the person who will be with the vehicle at the inspection (often the same person). Only the fields listed below are accepted; any other field is rejected with 400.\n\nPhone numbers are split into a country calling code without the `+` (`cPhCode`, `vPhCode`) and the local number (`cPhNumber`, `vPhNumber`), both digits only.\n\n`bookingDateTimestamp` is Unix epoch **seconds** (unlike the milliseconds returned by `GET`).",
        "operationId": "createInspection",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInspectionRequest"
              },
              "example": {
                "serviceId": "WCM2TtMCZOgxoFFMZfVH",
                "env": "PROD",
                "cName": "Jane Smith",
                "cEmail": "jane.smith@example.com",
                "cPhCode": "971",
                "cPhNumber": "501234567",
                "vName": "Jane Smith",
                "vEmail": "jane.smith@example.com",
                "vPhCode": "971",
                "vPhNumber": "501234567",
                "vVin": "JTMHV05J604123456",
                "vMake": "Toyota",
                "vModel": "Land Cruiser",
                "vYear": "2021",
                "vTrim": "GXR",
                "vPlate": "D 12345",
                "vColour": "White",
                "bookingDateTimestamp": 1793001600,
                "locationName": "Main branch"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Inspection booked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inspectionId": {
                      "type": "string",
                      "description": "Use this to read or update the inspection."
                    },
                    "inspectionRef": {
                      "type": "string",
                      "description": "Same value as `inspectionId`."
                    }
                  }
                },
                "example": {
                  "inspectionId": "3f9c2a7be41d4c0e9a51b6d2f08e7c13",
                  "inspectionRef": "3f9c2a7be41d4c0e9a51b6d2f08e7c13"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed: a missing or malformed field, an unsupported field, an unknown `locationName`, or an `InspectionId` that already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported": {
                    "value": {
                      "error": "unsupported params: odometer"
                    }
                  },
                  "location": {
                    "value": {
                      "error": "cant find location with the provided locationName"
                    }
                  },
                  "duplicate": {
                    "value": {
                      "error": "Inspection Already Exists"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/InvalidKey"
          },
          "500": {
            "description": "The inspection could not be saved. Also returned when `env` is omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Failed to create inspection"
                }
              }
            }
          }
        }
      }
    },
    "/axle-api/inspection-status": {
      "post": {
        "tags": [
          "Inspections"
        ],
        "summary": "Cancel an inspection",
        "description": "Cancel an inspection on the key's rooftop by setting `status` to `Canceled`. Parameters may be sent in the query string or as a JSON body.\n\n`Canceled` is the only status that can be set through the API; every other status is set by the inspector or by AlgoDriven's verification flow. An inspection that is already `Completed` or `Finished` cannot be canceled. Once canceled, `GET /axle-api/inspection` returns 404 for it.",
        "operationId": "updateInspectionStatus",
        "parameters": [
          {
            "name": "inspectionId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "Canceled"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Inspection canceled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "message": "Inspection Status Updated"
                }
              }
            }
          },
          "400": {
            "description": "A status other than `Canceled`, a missing or unknown `inspectionId`, or an inspection that is already completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "status": {
                    "value": {
                      "error": "Invalid Status, the only status that can be set through the API is Canceled"
                    }
                  },
                  "inspection": {
                    "value": {
                      "error": "Invalid inspectionId"
                    }
                  },
                  "completed": {
                    "value": {
                      "error": "Inspection is already Completed and can no longer be canceled"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/InvalidKey"
          }
        }
      }
    },
    "/axle-api/dealerId": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get the key's rooftop",
        "description": "Return the numeric DealerID the key acts as. Useful to confirm a key before booking inspections.",
        "operationId": "getInspectExpertDealerId",
        "responses": {
          "200": {
            "description": "The rooftop",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dealerId": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "dealerId": 1234
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/InvalidKey"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "InspectExpert API key issued by AlgoDriven for one rooftop. Send the raw key (not Bearer)."
      }
    },
    "responses": {
      "InvalidKey": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "InspectionStatus": {
        "type": "string",
        "enum": [
          "ACTION_REQUIRED",
          "AWAITING_VERIFICATION",
          "AWAITING_BOOKING",
          "AWAITING_INSPECTOR",
          "Pending",
          "In Progress",
          "Completed",
          "Finished",
          "Canceled"
        ],
        "description": "Values are case-sensitive and mix two naming styles. New bookings start as `Pending`."
      },
      "CreateInspectionRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "serviceId",
          "env",
          "cName",
          "cEmail",
          "cPhCode",
          "cPhNumber",
          "vName",
          "vEmail",
          "vPhCode",
          "vPhNumber",
          "vMake",
          "vModel",
          "vYear"
        ],
        "properties": {
          "serviceId": {
            "type": "string",
            "description": "The InspectExpert service (inspection package) to book."
          },
          "env": {
            "type": "string",
            "description": "Send `PROD`. Required: the booking fails with 500 when it is omitted.",
            "example": "PROD"
          },
          "cName": {
            "type": "string",
            "description": "Customer name"
          },
          "cEmail": {
            "type": "string",
            "format": "email",
            "description": "Customer email"
          },
          "cPhCode": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Customer country calling code, digits only (no `+`)"
          },
          "cPhNumber": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Customer phone number, digits only"
          },
          "vName": {
            "type": "string",
            "description": "Name of the person who will be with the vehicle"
          },
          "vEmail": {
            "type": "string",
            "format": "email",
            "description": "Email of the person who will be with the vehicle"
          },
          "vPhCode": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Country calling code of the person who will be with the vehicle, digits only"
          },
          "vPhNumber": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Phone number of the person who will be with the vehicle, digits only"
          },
          "vVin": {
            "type": "string",
            "minLength": 17,
            "maxLength": 17,
            "description": "17-character VIN. Optional; stored as `N/A` when omitted."
          },
          "vMake": {
            "type": "string"
          },
          "vModel": {
            "type": "string"
          },
          "vYear": {
            "type": "string",
            "pattern": "^[0-9]{4}$",
            "description": "Four-digit model year"
          },
          "vTrim": {
            "type": "string"
          },
          "vPlate": {
            "type": "string"
          },
          "vEngineNo": {
            "type": "string"
          },
          "vColour": {
            "type": "string"
          },
          "bookingDateTimestamp": {
            "type": "integer",
            "description": "Appointment time as Unix epoch seconds"
          },
          "locationName": {
            "type": "string",
            "description": "Nickname of one of the rooftop's InspectExpert locations. Unknown names are rejected with 400."
          },
          "InspectionId": {
            "type": "string",
            "description": "Optional id to use instead of a generated one, for example your own booking reference. Rejected with 400 if an inspection with this id already exists."
          }
        }
      },
      "Inspection": {
        "type": "object",
        "additionalProperties": true,
        "description": "The stored inspection. Fields not listed here may also be present and should be ignored.",
        "properties": {
          "inspectionRef": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/InspectionStatus"
          },
          "serviceId": {
            "type": "string",
            "nullable": true
          },
          "inspectionType": {
            "type": "string",
            "example": "Advanced"
          },
          "bookingDate": {
            "type": "integer",
            "nullable": true,
            "description": "Appointment time, Unix epoch milliseconds"
          },
          "createdAt": {
            "type": "integer",
            "nullable": true,
            "description": "Unix epoch milliseconds"
          },
          "completed": {
            "type": "integer",
            "nullable": true,
            "description": "When the inspection was completed, Unix epoch milliseconds. Absent until then."
          },
          "cName": {
            "type": "string"
          },
          "cEmail": {
            "type": "string"
          },
          "cPhCode": {
            "type": "string"
          },
          "cPhNumber": {
            "type": "integer"
          },
          "vName": {
            "type": "string"
          },
          "vEmail": {
            "type": "string"
          },
          "vPhCode": {
            "type": "string"
          },
          "vPhNumber": {
            "type": "integer"
          },
          "vVIN": {
            "type": "string",
            "description": "Note the capitalisation differs from the `vVin` request field."
          },
          "vMake": {
            "type": "string"
          },
          "vModel": {
            "type": "string"
          },
          "vYear": {
            "type": "string"
          },
          "vTrim": {
            "type": "string",
            "nullable": true
          },
          "vPlate": {
            "type": "string",
            "nullable": true
          },
          "vEngineNo": {
            "type": "string",
            "nullable": true
          },
          "vColour": {
            "type": "string",
            "nullable": true
          },
          "ADCode": {
            "type": "string",
            "nullable": true,
            "description": "GCC vehicle catalogue code decoded from the VIN, when one matches."
          },
          "locationName": {
            "type": "string",
            "nullable": true
          },
          "locationPosName": {
            "type": "string",
            "nullable": true
          },
          "carImages": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "iName": {
            "type": "string",
            "description": "Assigned inspector's name; empty until one is assigned."
          },
          "pdfURL": {
            "type": "string",
            "description": "Report PDF link; empty until the report is generated."
          },
          "notes": {
            "type": "string",
            "description": "Inspector notes. Empty unless the rooftop shows notes in reports."
          },
          "categoriesStatus": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Summary result per report category, for example `Verified` or `Faulty`."
          },
          "categoryInformation": {
            "type": "object",
            "additionalProperties": true,
            "description": "Detailed findings per report category and item. Keys follow the rooftop's service configuration."
          },
          "exteriorCatalog": {
            "type": "array",
            "description": "Exterior body diagram panels for this service, in display order.",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "countryCode": {
            "type": "string",
            "nullable": true
          },
          "primaryColor": {
            "type": "string",
            "nullable": true,
            "description": "Rooftop brand colour, for rendering the report."
          },
          "logo": {
            "type": "string",
            "nullable": true,
            "description": "Rooftop logo URL, for rendering the report."
          },
          "translations": {
            "type": "object",
            "additionalProperties": true,
            "description": "Report label translations keyed by language (`en`, `ar`)."
          }
        },
        "example": {
          "inspectionRef": "3f9c2a7be41d4c0e9a51b6d2f08e7c13",
          "status": "Completed",
          "serviceId": "WCM2TtMCZOgxoFFMZfVH",
          "inspectionType": "Advanced",
          "bookingDate": 1793001600000,
          "createdAt": 1792915200000,
          "completed": 1793005200000,
          "cName": "Jane Smith",
          "cEmail": "jane.smith@example.com",
          "cPhCode": "971",
          "cPhNumber": 501234567,
          "vVIN": "JTMHV05J604123456",
          "vMake": "Toyota",
          "vModel": "Land Cruiser",
          "vYear": "2021",
          "vPlate": "D 12345",
          "ADCode": "TOLC21GXR",
          "iName": "Ahmed Ali",
          "pdfURL": "https://example.com/report.pdf",
          "categoriesStatus": {
            "Wheels and Tyres": "Verified"
          }
        }
      }
    }
  }
}
