Skip to main content

Diagnostic Service

The Diagnostic Service exposes vehicle State of Health (SOH) diagnostics for EV batteries — a battery health score (0–100 %) together with the provider's report (PDF and image).

info

To activate the diagnostic service for your software, please contact us at https://openhive.eu/contact.

How It Works​

There are two ways to get a diagnostic:

  • 📖 Read — for everything that already exists. Look up a vehicle's diagnostics with GET /v1/diagnostic/soh-reports, filtered by VIN, status, type or date.
  • 🔔 Subscribe to the webhook — to receive every new diagnostic. A measurement is started out in the field by the customer, with or without a partner device plugged into the vehicle. When it is ready, the partner pushes it to OpenHive, OpenHive calls your webhook URI, and you read the report back.

Your application never triggers a measurement, and never waits on one. Both are scoped to your entitlement: you only ever see diagnostics attached to your own customer subscription.

Deprecated — the prior-request flow

The original flow rolled everything into one call: you submitted a VIN through POST /v1/diagnostic/soh-requests and waited on the answer, whether the vehicle had already been measured or not. That model is deprecated.

Use GET /v1/diagnostic/soh-reports to look up a pre-existing diagnostic, and rely on the webhook to pick up a diagnostic that has just been performed.

The endpoint still answers for existing integrations, but it will be removed — do not build on it. See Legacy flow below.

Looking up a diagnostic​

GET /v1/diagnostic/soh-reports returns the diagnostics your subscription is entitled to, most useful when filtered by VIN:

curl "https://api.openhive.eu/v1/diagnostic/soh-reports?vin=WVWZZZ1JZXW000001" \
-H "Authorization: Bearer <access_token>"

Filters​

Query parameterDescription
vin / vin[]Exact VIN, or any of several VINs.
status / status[]Exact status — success or error.
type / type[]Exact diagnostic type, or any of several.
performedAt[after] / performedAt[before]Measured on or after / on or before this date.
performedAt[strictly_after] / [strictly_before]Measured strictly after / strictly before this date.

Fetch a single diagnostic with GET /v1/diagnostic/soh-reports/{uid}.

Response fields​

FieldDescription
uidOpenHive identifier of the diagnostic.
vinVehicle VIN.
statussuccess or error.
sohValueBattery health score (0–100 %). Only on success.
pdfUrl / imageUrlProvider report and illustration. Only on success.
errorReasonWhy the diagnostic failed. Only on error.
providerPartner that performed the measurement.
typeDiagnostic type.
externalIdThe provider's own reference for this report.
performedAtWhen the measurement was taken.
expiresAtWhen the diagnostic stops being considered current, if applicable.
createdAtWhen OpenHive received it.

Webhook notification​

When a partner pushes a diagnostic for one of your vehicles, OpenHive sends an HTTP POST to your software's configured webhook URI:

{
"event": "diagnostic_soh.created",
"uid": "550e8400-e29b-41d4-a716-446655440000",
"vin": "WVWZZZ1JZXW000001",
"status": "success",
"url": "https://api.openhive.eu/v1/diagnostic/soh-reports/550e8400-e29b-41d4-a716-446655440000"
}

The webhook is a notification, not the report: it tells you a diagnostic exists and where to read it. Call the url it carries (or GET /v1/diagnostic/soh-reports/{uid}) to get the score, the PDF and the image.

tip

Answer 2xx quickly. A non-2xx response is retried, so treat the delivery as at-least-once and make your handler idempotent on uid.

Statuses​

StatusDescription
successMeasurement completed — sohValue, pdfUrl and imageUrl are set.
errorMeasurement failed — errorReason explains the cause.

Sandbox toolkit​

POST /v1/diagnostic/soh-reports/sandbox is integration tooling, not a business endpoint: it lets you simulate the arrival of a diagnostic so you can exercise your integration without a partner and a real vehicle.

OpenHive performs a genuine push through the very same connector a partner uses — so your webhook fires and the diagnostic becomes readable exactly as it would in production. The call is asynchronous and answers 202.

Sandbox starts out empty: there are no pre-seeded diagnostics, so this endpoint is what makes them exist. Trigger one, let your webhook fire, then read it back with GET /v1/diagnostic/soh-reports?vin=… — that exercises both halves of the integration in one go.

curl -X POST https://api.openhive.eu/v1/diagnostic/soh-reports/sandbox \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"vin": "SNDBXSUCCES95PUSH"}'

The VIN selects the scenario to simulate:

VINSimulated result
SNDBXSUCCES95PUSHsuccess — score 95, with PDF and image.
SNDBXSUCCES70PUSHsuccess — score 70, with PDF and image.
SNDBXERRPRVDRPUSHerror — provider error.
SNDBXUNKNVEHCPUSHerror — vehicle not recognized.

Every diagnostic carries an externalId — the reference the provider puts on its own report, which in the real flow you only ever read back (see Response fields). Here you stand in for the provider, so you may set it yourself; omit it and OpenHive generates one for you.

Setting it is only useful to rehearse idempotent replay: pushing the same externalId again with the same VIN is treated as a retry rather than a new diagnostic. Beware that every sandbox subscription shares a single provider identity, so this namespace is shared between integrators — an externalId already used with a different VIN is rejected with 409.

note

This endpoint requires an OpenHive Sandbox subscription — any other subscription gets a 403.

Putting it together​

Integration Steps​

  • 1️⃣ Get your API credentials from OpenHive.
  • 2️⃣ Obtain a JWT token from the OpenHive IDP.
  • 3️⃣ Expose a webhook endpoint and give us its URI.
  • 4️⃣ Look up existing diagnostics by VIN, and handle incoming webhook notifications.
  • 5️⃣ Rehearse the whole thing with the sandbox toolkit.

Legacy flow (deprecated)​

The original model went through a single call, which both looked up and waited:

  • Your application submitted a POST /v1/diagnostic/soh-requests with the vehicle VIN.
  • You got the diagnostic straight back when the vehicle had already been measured, otherwise a record in state NEW.
  • For a pending one, the result then reached you by webhook — carrying the full payload (state, score, pdfUri, imageUri) — or the diagnostic ended as ERROR if none ever arrived.

Calling it never caused a measurement to be taken: the vehicle still had to be measured in the field, exactly as today.

That flow used its own states — NEW, PENDING, DONE, ERROR — which are not the statuses of the current API.

It is kept working for existing integrations only. New integrations must use the lookup + webhook model described above.