Carly Enterprise API (v1)
The Carly Enterprise API connects your systems to Carly Enterprise in two ways:
- Pull: you call our APIs whenever you need data.
- Push: Carly sends every new report to an HTTPS endpoint you provide (see Push API).
The pull API consists of two services:
| Service | Base URL | What it is for |
|---|---|---|
| User API | https://user.carly-enterprise.io |
Access tokens, users and organizations |
| Reports API | https://reports.carly-enterprise.io |
Vehicle reports, PDFs and inspection photos |
Both use the same access token: request it once from the User API (POST /public/generate-token) and send it in
the token header to either service. To get API credentials, contact us.
The full specification is available as OpenAPI (YAML) for code generators and API clients.
Integrate in two steps. Authorization uses a JWT access token sent in the token request header.
Step 1: Generate an access token
Before calling any other endpoint, generate a token with the User API:
POST https://user.carly-enterprise.io/public/generate-token
Send your API user ID and secret; the response contains the token. See Generate access token for the request and response.
Step 2: Call the API endpoints
Send the token in the token header (raw value, no Bearer prefix) to the endpoints of the
User API and the Reports API.
Best practices
- Cache the token until it expires. It is valid for one hour; the JWT's
expclaim holds the expiry time. Request a new token only when it has expired. - Handle
204 No Contentas a valid "no data" state. For example,POST /public/reports/vin/lookupanswers204when none of the VINs has a report. - Validate the VIN format before sending requests: 17 characters, uppercase letters and digits, without
I,OandQ(^[A-HJ-NPR-Z0-9]{17}$). - Store your secret securely and never expose it client-side. Generate tokens on your server only.
Manage the users and organizations of your Carly Enterprise account from your own systems.
Authentication
The API uses short-lived access tokens.
- Carly provides you with API credentials: an API user ID and an API secret. Keep the secret on your server and never ship it in client applications.
- Call
POST /public/generate-tokenwith these credentials. The response contains an access token that is valid for 1 hour. - Send the access token in the
tokenrequest header of every other request. Send the raw token value, without aBearerprefix. - When the token has expired (
401with error codeJwtExpiredError), request a new one.
curl -X POST https://user.carly-enterprise.io/public/generate-token \
-H 'Content-Type: application/json' \
-d '{"userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68", "secret": "YOUR_API_SECRET"}'
curl -X POST https://user.carly-enterprise.io/public/list \
-H 'Content-Type: application/json' \
-H 'token: YOUR_ACCESS_TOKEN' \
-d '{"enabled": true, "limit": 50}'
Access scope
Your API credentials are bound to one or more partners, optionally restricted to specific organizations. An organization grants access to all of its sub-organizations. Requests for organizations outside this scope are rejected.
Errors
All errors share the ErrorResponse format. code is a stable, machine-readable identifier;
text is a human-readable message and message gives technical details. text is localized
when you send the optional App-Language header (for example de); the default is English.
Note that most business errors (for example an unknown organization) are returned with
status 400; use error.code to tell them apart.
The Reports API gives you read access to the vehicle reports created with the Carly Enterprise app for the organizations your API user has access to. You can check which VINs have reports, list the reports for a VIN, download a report as PDF and fetch the photos taken during an inspection.
Authentication
Every request except the PDF download needs an access token in the token request header.
Get the token from the Carly Enterprise User API with POST /public/generate-token,
using the API credentials you received from Carly. A token is valid for one hour; request a
new one when it expires.
The token also defines what you can call:
- Scopes: each operation requires a scope (
reports,report-lookuporreport-images). Calls without the required scope are rejected with401. - Daily limit: operations marked with a daily limit count the distinct VINs you request
per scope and calendar day (UTC). Once the limit is reached, further calls for that scope
return
429until the next day.
Errors
Errors are returned as JSON with an error object (see ErrorResponse). code identifies the
error type, message and text describe it.
Generate an access token
Exchanges your API user ID and API secret for an access token. The token is valid for
1 hour and must be sent in the token header of all other requests.
Request Body schema: application/jsonrequired
| userId required | string non-empty Your API user ID, as provided by Carly. |
| secret required | string non-empty Your API secret, as provided by Carly. |
Responses
Response Schema: application/json
| token required | string Access token (JWT) for the |
Request samples
- Payload
{- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "secret": "YOUR_API_SECRET"
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "token": "YOUR_ACCESS_TOKEN"
}Register a user
Creates a user in one of your organizations. The user receives a welcome email with
their login details. If you omit password, a random password is generated.
The email address must not be in use by any user or organization yet, and must be deliverable (addresses with invalid syntax, no DNS entries or a non-existent mailbox are rejected).
Authorizations:
Request Body schema: application/jsonrequired
| organizationId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Organization the user belongs to. |
| email required | string <email> Login email address of the user. Stored in lower case. |
| firstName required | string [ 2 .. 100 ] characters |
| lastName required | string [ 2 .. 100 ] characters |
| title required | string [ 2 .. 100 ] characters Job title or salutation of the user. |
| locale required | string (Locale) ^[a-z]{2}-[A-Z]{2}$ Language and region of the user, as |
| password | string [ 6 .. 100 ] characters Initial password. If omitted, a random password is generated. Must contain at least one uppercase letter, one lowercase letter, one number and one special character. |
| expireDate | string <date> Date after which the user can no longer log in. Omit for no expiry. |
Responses
Response Schema: application/json
| success required | boolean |
Request samples
- Payload
{- "organizationId": "11111111-1111-1111-1111-111111111111",
- "email": "jane.doe@example.com",
- "firstName": "Jane",
- "lastName": "Doe",
- "title": "Service Advisor",
- "locale": "de-DE",
- "expireDate": "2027-12-31"
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "success": true
}Get user details
Returns a single user of one of your organizations.
Authorizations:
Request Body schema: application/jsonrequired
| userId required | string (UserId) non-empty Identifier of a user, assigned by Carly. Treat it as an opaque string and do not rely on its format. |
| organizationId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Organization the user belongs to. |
Responses
Response Schema: application/json
| userId | string (UserId) non-empty Identifier of a user, assigned by Carly. Treat it as an opaque string and do not rely on its format. |
| organizationId | string <uuid> (Uuid) ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... |
string <email> | |
| firstName | string |
| lastName | string |
| title | string |
| locale | string (Locale) ^[a-z]{2}-[A-Z]{2}$ Language and region of the user, as |
| enabled | boolean Whether the user can log in. |
| expireDate | string <date-time> Date after which the user can no longer log in. Absent if the user does not expire. |
| createdAt | string <date-time> |
Request samples
- Payload
{- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "organizationId": "11111111-1111-1111-1111-111111111111"
}Response samples
- 200
- 400
- 401
- 403
- 412
- 500
{- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "organizationId": "11111111-1111-1111-1111-111111111111",
- "email": "jane.doe@example.com",
- "firstName": "Jane",
- "lastName": "Doe",
- "title": "Service Advisor",
- "locale": "de-DE",
- "enabled": true,
- "expireDate": "2027-12-31T00:00:00.000Z",
- "createdAt": "2026-01-15T09:30:00.000Z"
}List users
Returns the users of all organizations you have access to, or of one organization and
its sub-organizations when organizationId is set. Users are sorted by last name.
Use offset and limit to page through the result; count is the total number of
matching users.
Authorizations:
Request Body schema: application/jsonrequired
| enabled required | boolean
|
| expiredUserOnly | boolean If |
| organizationId | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Restrict the result to this organization and its sub-organizations. |
| offset | integer >= 0 Number of users to skip. |
| limit | integer [ 1 .. 5000 ] Maximum number of users to return. If omitted, all matching users are returned. |
Responses
Response Schema: application/json
required | Array of objects (User) |
| count required | integer Total number of users matching the request, independent of |
Request samples
- Payload
{- "enabled": true,
- "organizationId": "11111111-1111-1111-1111-111111111111",
- "offset": 0,
- "limit": 50
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "users": [
- {
- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "organizationId": "11111111-1111-1111-1111-111111111111",
- "email": "jane.doe@example.com",
- "firstName": "Jane",
- "lastName": "Doe",
- "title": "Service Advisor",
- "locale": "de-DE",
- "enabled": true,
- "createdAt": "2026-01-15T09:30:00.000Z"
}
], - "count": 1
}Update a user
Replaces the user's profile data. Send all fields; optional fields you omit are cleared
(for example, omitting expireDate removes the expiry date).
- To move the user to another of your organizations, send that organization's ID as
organizationId. The user is then signed out of all sessions. - If
passwordis set, the password is changed and the user receives an email with the new password. enabledenables or disables the login of the user.
Authorizations:
Request Body schema: application/jsonrequired
| userId required | string (UserId) non-empty Identifier of a user, assigned by Carly. Treat it as an opaque string and do not rely on its format. |
| organizationId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Organization the user belongs to. Send a different organization ID to move the user to that organization. |
| enabled required | boolean Whether the user can log in. |
| firstName required | string [ 2 .. 100 ] characters |
| lastName required | string [ 2 .. 100 ] characters |
| title required | string [ 2 .. 100 ] characters |
| locale required | string (Locale) ^[a-z]{2}-[A-Z]{2}$ Language and region of the user, as |
| password | string [ 6 .. 30 ] characters New password. If set, the user receives an email with the new password. Omit to keep the current password. |
| expireDate | string <date> Date after which the user can no longer log in. Omit to remove the expiry date. |
Responses
Response Schema: application/json
| success required | boolean |
Request samples
- Payload
{- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "organizationId": "11111111-1111-1111-1111-111111111111",
- "firstName": "Jane",
- "lastName": "Doe",
- "title": "Workshop Manager",
- "locale": "de-DE",
- "enabled": true,
- "expireDate": "2027-12-31"
}Response samples
- 200
- 400
- 401
- 403
- 412
- 500
{- "success": true
}Enable or disable a user
Enables or disables a user. A disabled user can no longer log in; their data is kept.
Authorizations:
Request Body schema: application/jsonrequired
| userId required | string (UserId) non-empty Identifier of a user, assigned by Carly. Treat it as an opaque string and do not rely on its format. |
| organizationId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Organization the user belongs to. |
| enabled required | boolean
|
Responses
Response Schema: application/json
| success required | boolean |
Request samples
- Payload
{- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "organizationId": "11111111-1111-1111-1111-111111111111",
- "enabled": false
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "success": true
}Create, read, update and enable or disable organizations and browse the organization hierarchy.
Register an organization
Creates an organization under one of your partners, optionally as a sub-organization of
an existing organization (parentOrganizationId). The parent must belong to the same
partner and be within your access (the organizations your API credentials are limited to,
including their sub-organizations). Any parent that cannot be used (unknown, outside your
access, or of another partner) is rejected with the same OrganizationAccessDeniedError. Sub-organizations inherit settings such as prices and feature configuration
from their parent.
The organization name and email address must not be in use yet. If no email is given,
sendEmail is ignored and reports are not emailed to the organization.
If credits are managed at partner level, credits is ignored.
Authorizations:
Request Body schema: application/jsonrequired
| partnerId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Partner the organization belongs to. Must be one of your partners. |
| name required | string [ 3 .. 150 ] characters Organization name. Must be unique. |
| sendEmail required | boolean Send reports to the organization's email address. Requires |
| sendEmailToUser required | boolean Send reports to the email address of the user who created them. |
| parentOrganizationId | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Create the organization as a sub-organization of this organization. |
string <email> Contact email address of the organization. Must not be in use yet. | |
| credits | number [ 0 .. 100000 ] Initial credit balance. Ignored if credits are managed at partner level. |
| expireDate | string <date> Date after which the organization's users can no longer log in. Omit for no expiry. |
Responses
Response Schema: application/json
| success required | boolean |
| id required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... ID of the new organization. |
Request samples
- Payload
{- "partnerId": "22222222-2222-2222-2222-222222222222",
- "parentOrganizationId": "11111111-1111-1111-1111-111111111111",
- "name": "Example Garage GmbH",
- "email": "info@example.com",
- "credits": 100,
- "sendEmail": true,
- "sendEmailToUser": false,
- "expireDate": "2027-12-31"
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "success": true,
- "id": "33333333-3333-3333-3333-333333333333"
}Get organization details
Returns a single organization you have access to.
Authorizations:
Request Body schema: application/jsonrequired
| organizationId required | string <uuid> (Uuid) ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... |
Responses
Response Schema: application/json
| organizationId | string <uuid> (Uuid) ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... |
| partnerId | string <uuid> (Uuid) ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... |
| name | string |
string <email> Absent if the organization has no email address. | |
| credits | number Current credit balance. |
| enabled | boolean Whether users of the organization can log in. |
| createdAt | string <date-time> |
| sendEmail | boolean Reports are sent to the organization's email address. |
| sendEmailToUser | boolean Reports are sent to the email address of the user who created them. |
Request samples
- Payload
{- "organizationId": "11111111-1111-1111-1111-111111111111"
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "organizationId": "11111111-1111-1111-1111-111111111111",
- "partnerId": "22222222-2222-2222-2222-222222222222",
- "name": "Example Garage GmbH",
- "email": "info@example.com",
- "credits": 100,
- "enabled": true,
- "createdAt": "2026-01-10T08:00:00.000Z",
- "sendEmail": true,
- "sendEmailToUser": false
}Update an organization
Updates an organization. partnerId must be the organization's current partner; an
organization cannot be moved to another partner.
Sending no email removes the organization's email address.
If credits are managed at partner level, credits is ignored.
Authorizations:
Request Body schema: application/jsonrequired
| organizationId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Organization to update. |
| partnerId required | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... The organization's current partner. |
| name required | string [ 3 .. 50 ] characters Organization name. Must be unique. |
| sendEmail required | boolean Send reports to the organization's email address. |
| sendEmailToUser required | boolean Send reports to the email address of the user who created them. |
string <email> Contact email address. Omit to remove the organization's email address. | |
| credits | number [ 0 .. 100000 ] New credit balance. Ignored if credits are managed at partner level. |
| expireDate | string <date> Date after which the organization's users can no longer log in. |
Responses
Response Schema: application/json
| success required | boolean |
Request samples
- Payload
{- "organizationId": "33333333-3333-3333-3333-333333333333",
- "partnerId": "22222222-2222-2222-2222-222222222222",
- "name": "Example Garage GmbH",
- "email": "info@example.com",
- "credits": 250,
- "sendEmail": true,
- "sendEmailToUser": true
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "success": true
}Enable or disable an organization
Enables or disables an organization. Users of a disabled organization can no longer log in; the organization's data is kept.
Authorizations:
Request Body schema: application/jsonrequired
| organizationId required | string <uuid> (Uuid) ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... |
| enabled required | boolean
|
Responses
Response Schema: application/json
| success required | boolean |
Request samples
- Payload
{- "organizationId": "33333333-3333-3333-3333-333333333333",
- "enabled": false
}Response samples
- 200
- 400
- 401
- 403
- 500
{- "success": true
}Get the organization tree
Returns the organizations you have access to as a tree. Each node lists its
sub-organizations in children; nodes are sorted by name and level starts at 1 for
the top-level nodes of the result.
Set organizationId to return only that organization and its sub-organizations.
count is the total number of organizations in the tree.
Authorizations:
Request Body schema: application/jsonrequired
| organizationId | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Return only this organization and its sub-organizations. |
Responses
Response Schema: application/json
required | Array of objects (OrganizationNode) |
| count required | integer Total number of organizations in the tree. |
Request samples
- Payload
{ }Response samples
- 200
- 400
- 401
- 403
- 500
{- "organizations": [
- {
- "organizationId": "11111111-1111-1111-1111-111111111111",
- "partnerId": "22222222-2222-2222-2222-222222222222",
- "name": "Example Group AG",
- "email": "info@example.com",
- "credits": 0,
- "creditsLimit": 0,
- "enabled": true,
- "sendEmail": false,
- "sendEmailToUser": false,
- "createdAt": "2026-01-10T08:00:00.000Z",
- "level": 1,
- "children": [
- {
- "organizationId": "33333333-3333-3333-3333-333333333333",
- "partnerId": "22222222-2222-2222-2222-222222222222",
- "name": "Example Garage GmbH",
- "email": "garage@example.com",
- "address": {
- "street": "Example Street",
- "houseNumber": "1",
- "zipCode": "12345",
- "city": "Example City",
- "country": "DE"
}, - "credits": 100,
- "creditsLimit": 100,
- "enabled": true,
- "sendEmail": true,
- "sendEmailToUser": false,
- "createdAt": "2026-02-01T08:00:00.000Z",
- "level": 2,
- "children": [ ]
}
]
}
], - "count": 2
}List credit changes
Returns who changed the credits of an organization or partner, when, and from which value to which. A change is recorded when credits are set at registration, updated, or reset to 0 because an organization moved to a partner that pays the credits itself. Credits used by reports are not listed.
Changes are sorted newest first. Without filters you get every change within your access
scope. Changes of a partner's own credits (no organizationId) are only returned to
credentials with access to the whole partner. Set organizationId to return that
organization and its sub-organizations.
count is the total number of matching changes; page through them with offset and
limit.
Authorizations:
Request Body schema: application/jsonrequired
| partnerId | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Return only changes of this partner and its organizations. |
| organizationId | string <uuid> ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}... Return only changes of this organization and its sub-organizations. |
| from | string (DateOrDateTime) ^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d{1... ISO 8601 date ( |
| to | string (DateOrDateTime) ^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d{1... ISO 8601 date ( |
| offset | integer >= 0 Default: 0 Number of changes to skip. |
| limit | integer [ 1 .. 1000 ] Default: 100 Maximum number of changes to return. |
Responses
Response Schema: application/json
required | Array of objects (CreditChange) |
| count required | integer Total number of matching changes. |
Request samples
- Payload
{ }Response samples
- 200
- 400
- 401
- 403
- 500
{- "creditChanges": [
- {
- "changeId": "7d0c7a52-3b9e-4c55-9a1f-2e6b8f0c4d11",
- "partnerId": "00000000-0000-0000-0000-000000000000",
- "organizationId": "00000000-0000-0000-0000-000000000000",
- "previousCredits": 10,
- "currentCredits": 110,
- "reason": "update",
- "changedBy": {
- "source": "backend",
- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "email": "jane.doe@example.com"
}, - "changedAt": "2026-10-15T08:00:00.000Z"
}, - {
- "changeId": "0b6f1e2d-8c4a-4f3b-b7d9-5a1c9e3f2a77",
- "partnerId": "00000000-0000-0000-0000-000000000000",
- "organizationId": "00000000-0000-0000-0000-000000000000",
- "previousCredits": 0,
- "currentCredits": 10,
- "reason": "register",
- "changedBy": {
- "source": "publicApi",
- "userId": "3f9c2b7e-8a41-4d6f-9b0e-5c7d1a2e4f68",
- "apiUserName": "Example ERP"
}, - "changedAt": "2026-10-01T09:30:00.000Z"
}
], - "count": 2
}Check which VINs have reports
Checks a list of up to 500 VINs and returns, for each VIN that has at least one report, the
time of its latest report. VINs without a report are left out of the response. If none of
the VINs has a report, the response is 204 No Content.
VINs are matched exactly; send them in upper case.
Requires the report-lookup scope. This operation has no daily limit.
Authorizations:
header Parameters
| ac-id | string Example: customer-4711 Optional reference of your own, for example an account or customer ID in your system.
On |
Request Body schema: application/jsonrequired
| vins required | Array of strings (Vin) [ 1 .. 500 ] items [ items = 17 characters ^[A-HJ-NPR-Z0-9]{17}$ ] VINs to check. |
Responses
Response Schema: application/json
| vin required | string |
| latest required | integer <int64> Time the latest report for this VIN was created, Unix time in milliseconds. |
Request samples
- Payload
{- "vins": [
- "WVWZZZ1JZXW000001",
- "WVWZZZ1JZXW000002"
]
}Response samples
- 200
- 400
- 401
- 500
[- {
- "vin": "WVWZZZ1JZXW000001",
- "latest": 1760428800000
}
]List reports for a VIN
Returns all reports for a VIN that your API user has access to, in no guaranteed order
(sort by timestamp if you need one). If there are no reports, the response is
204 No Content.
Each report contains a download link (reportUrls.withFaults) that leads to the PDF via
Download a report PDF. The link is valid for 24 hours;
call this operation again to get a fresh one. For battery health reports
(batterySOHTest) a second link, reportUrls.withoutFaults, returns the PDF without the
fault code section.
Requires the reports scope. Counts towards the daily limit.
Authorizations:
query Parameters
| vin required | string (Vin) = 17 characters ^[A-HJ-NPR-Z0-9]{17}$ Example: vin=WVWZZZ1JZXW000001 Vehicle identification number, 17 characters, without I, O and Q. |
header Parameters
| ac-id | string Example: customer-4711 Optional reference of your own, for example an account or customer ID in your system.
On |
Responses
Response Schema: application/json
| locale required | string Language and region the report was created in. |
required | object Links to a preview of the report. |
required | object Download links for the full report PDF, valid for 24 hours. Open them with
|
| reportType required | string (ReportType) Type of the report. Known values: |
| timestamp required | integer <int64> Time the report was created, Unix time in milliseconds. |
| timezone required | string IANA time zone of the device that created the report. |
| inconsistenciesFound | boolean Whether the report found inconsistencies, for example between mileage values. |
| mileage | integer [ 0 .. 999999 ] Mileage in kilometres. Read off the odometer by the customer and typed into the app,
not read from the vehicle. |
| numberOfIssuesFound | integer Number of issues found in the report. |
| socScore | string Battery state of charge in percent, for battery reports. |
| sohScore | string Battery state of health in percent, for battery reports. |
| unitMode | string Enum: "metric" "imperial" Unit system used in the PDF ( |
| wasDeleted | boolean Whether the report was deleted by the organization. |
Response samples
- 200
- 400
- 401
- 429
- 500
[- {
- "inconsistenciesFound": false,
- "locale": "de-DE",
- "mileage": 128500,
- "numberOfIssuesFound": 3,
- "previewUrls": {
}, - "reportUrls": {
}, - "reportType": "carCheck",
- "timestamp": 1760428800000,
- "timezone": "Europe/Berlin",
- "unitMode": "metric",
- "wasDeleted": false
}, - {
- "locale": "de-DE",
- "mileage": 64200,
- "previewUrls": {
}, - "reportUrls": {
}, - "reportType": "batterySOHTest",
- "socScore": "78",
- "sohScore": "92",
- "timestamp": 1760515200000,
- "timezone": "Europe/Berlin",
- "unitMode": "metric"
}
]Download a report PDF
Opens the PDF of a report. You do not build this URL yourself: use a link from
reportUrls in List reports for a VIN. The token query
parameter in that link authorizes the download, so this operation needs no token header.
The response is a 308 Permanent Redirect to the PDF. The redirect target is valid for
5 minutes; follow it right away (most HTTP clients and browsers do this automatically).
The download link itself is valid for 24 hours after it was issued.
query Parameters
| token required | string Example: token=EXAMPLE_DOWNLOAD_TOKEN Download token, taken unchanged from the |
Responses
Response samples
- 400
- 401
- 500
{- "error": {
- "code": "BadRequestParameters",
- "text": "One or more request parameters are invalid.",
- "message": "Missing required request parameters: [token]"
}
}List inspection photos for a VIN
Returns the photos taken during inspections of a VIN, grouped by report. If there are no
photos, the response is 204 No Content.
Requires the report-images scope. Counts towards the daily limit.
Authorizations:
query Parameters
| vin required | string (Vin) = 17 characters ^[A-HJ-NPR-Z0-9]{17}$ Example: vin=WVWZZZ1JZXW000001 Vehicle identification number, 17 characters, without I, O and Q. |
Responses
Response Schema: application/json
| vin required | string |
| locale required | string |
| mileage required | string Mileage formatted for the report locale, with unit ( |
| reportType required | string (ReportType) Type of the report. Known values: |
| timestamp required | integer <int64> Time the report was created, Unix time in milliseconds. |
| timezone required | string |
| images required | Array of strings <uri> [ items <uri > ] Links to the photos. |
| sohScore | string Battery state of health in percent, for battery reports. |
Response samples
- 200
- 400
- 401
- 429
- 500
[- {
- "vin": "WVWZZZ1JZXW000001",
- "locale": "de-DE",
- "mileage": "128.500 km",
- "reportType": "carCheck",
- "timestamp": 1760428800000,
- "timezone": "Europe/Berlin",
}
]With the Push API, Carly sends the data of every new vehicle report to an HTTPS endpoint you run. You do not call Carly: Carly calls you.
- You give Carly the HTTPS URL of your endpoint (for example
https://api.example.com/carly/webhook) and the credentials Carly should use to call it (see Authentication). Carly sets up the integration for your organization. - Whenever a user of your organization finishes a report in the Carly Enterprise app and the
PDF has been created, Carly sends one
POSTrequest with the report data as JSON (Content-Type: application/json) to your endpoint. - Your endpoint confirms receipt with a
2xxstatus code.
There is one request per report. The reportType field in the body tells you which kind of
report it is and which schema applies (see Payload types). Carly only pushes newly created
reports; changes to or deletion of a report are not pushed.
The same report can arrive more than once (for example after a retry, or when Carly processes a
report again). Use reportId to recognise reports you have already processed.
If you restrict incoming traffic by IP address, Carly can give you the fixed IP addresses the requests come from.
You decide how Carly authenticates to your endpoint; Carly supports any method you choose and
agrees the details with you during onboarding. Common choices are a static key in a request
header (for example X-Api-Key: YOUR_WEBHOOK_SECRET), HTTP Basic authentication, or a bearer
token that Carly fetches from your token endpoint (for example with the OAuth 2.0 client
credentials flow) and reuses until it expires.
Credentials are only sent in headers or to your token endpoint, never in the payload.
- Return any
2xxstatus code once you have accepted the report. The response body is not evaluated. - Every other status code, and a response that takes longer than 25 seconds, counts as a failed delivery.
- Connection errors and timeouts are retried within the same delivery, up to three times with short, increasing pauses.
- If a delivery still fails, Carly tries again about two minutes later. After three failed deliveries the report is not sent again automatically and the Carly team is alerted.
- Process the request quickly and do the heavy work asynchronously, so that you answer within the timeout.
reportType |
Report | Report-specific data |
|---|---|---|
carCheck |
Car Check | categories: VIN and mileage values read from the vehicle's control units |
diagnostics |
Diagnostics | ecus: control units and their fault codes |
batterySOHTest |
Battery SOH Test | scanSummary: high-voltage battery measurements and faults |
privacyDataClearing |
Privacy Data Clearing | none, common fields only |
quickDiagnostics |
Quick Diagnostics | ecus: control units and their fault codes |
crashData |
Crash Data | none, common fields only |
inputForm |
Input Form | none, common fields only |
carHistory |
Car History | none, common fields only |
All payloads share the common fields (vehicle, report and user data, PDF download link) shown
in ReportBase. The PDF link in downloadUrl is valid for 14 days; download and store the
PDF if you need it later. For the report types with common fields only, the report content
is in the PDF.
A privacyDataClearing report confirms that personal data stored in the vehicle was cleared
with the Carly Enterprise app, for example before a vehicle is resold or returned from a
lease. The push contains the common fields only; the confirmation document itself is the
PDF behind downloadUrl.
Requests Carly sends to your endpoint. Each entry describes one report type: the request body Carly sends and the response your endpoint must return.
Car Check report created Webhook
Sent when a Car Check report has been created. A Car Check compares the VIN and mileage values stored in the vehicle's control units with reference values, to detect manipulated odometers or swapped parts.
Only data points with the status valid or inconsistent are sent; categories without
such data points are left out.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
required | Array of objects (CarCheckCategory) Car Check data, grouped by category. Only categories with at least one |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "categories": [
- {
- "categoryKey": "vin_reference",
- "data": [
- {
- "ecuName": "Engine",
- "dataPointName": "VIN reference",
- "value": "WVWZZZ1JZXW000001",
- "unit": "",
- "status": "valid"
}
]
}, - {
- "categoryKey": "vin",
- "data": [
- {
- "ecuName": "Engine",
- "dataPointName": "Engine VIN",
- "value": "WVWZZZ1JZXW000001",
- "unit": "",
- "status": "valid"
}, - {
- "ecuName": "Instrument cluster",
- "dataPointName": "Instrument cluster VIN",
- "value": "WVWZZZ1JZXW000001",
- "unit": "",
- "status": "valid"
}
]
}, - {
- "categoryKey": "mileage_reference",
- "data": [
- {
- "ecuName": "User input",
- "dataPointName": "Entered mileage",
- "value": "85362",
- "unit": "km",
- "status": "valid"
}
]
}, - {
- "categoryKey": "mileage",
- "data": [
- {
- "ecuName": "Engine",
- "dataPointName": "Mileage stored in engine ECU",
- "value": "85362",
- "unit": "km",
- "status": "valid"
}, - {
- "ecuName": "Instrument cluster",
- "dataPointName": "Instrument cluster odometer",
- "value": "79010",
- "unit": "km",
- "status": "inconsistent"
}
]
}
], - "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "carCheck",
- "reportId": "1234567890",
- "timestamp": "2026-06-02T09:02:59Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Kia",
- "series": "Ceed",
- "model": "Ceed III Gen (CD)",
- "buildYear": 2019,
- "fuelType": "gasoline",
- "mileage": 85362,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-06-02T09:03:22Z"
}Diagnostics report created Webhook
Sent when a Diagnostics report has been created. It lists every control unit (ECU) that
was scanned and the fault codes stored in it. An ECU without faults has an empty
faults list.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
required | Array of objects (DiagnosticsEcu) Control units (ECUs) that were scanned. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "ecus": [
- {
- "name": "ABS / ESP brake control",
- "faults": [ ]
}, - {
- "name": "BCM body control module",
- "faults": [
- {
- "code": "B16AB00",
- "text": "B16AB00 Rear bumper antenna failure"
}
]
}, - {
- "name": "TPMS tyre pressure monitoring system",
- "faults": [ ]
}
], - "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "diagnostics",
- "reportId": "1234567891",
- "timestamp": "2026-06-02T09:01:36Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Kia",
- "series": "Ceed",
- "model": "Ceed III Gen (CD)",
- "buildYear": 2019,
- "fuelType": "gasoline",
- "mileage": 85362,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-06-02T09:02:30Z"
}Battery SOH Test report created Webhook
Sent when a Battery SOH (state of health) Test report has been created for an electric or hybrid vehicle. It contains the measurements of the high-voltage battery, such as state of health, state of charge, temperatures and voltages, and the faults found in the battery-related control units.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
required | object (BatteryScanSummary) Results of the battery scan. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "scanSummary": {
- "diagnostics": {
- "systems": [
- {
- "title": "High-voltage system ECU",
- "faults": [
- {
- "code": "CAD714",
- "text": "CAD714 Message (vehicle state) missing"
}
]
}, - {
- "title": "Charging electronics",
- "faults": [ ]
}
]
}, - "measurements": {
- "title": "High-voltage system measurements",
- "data": [
- {
- "title": "State of health",
- "key": "SOH",
- "value": "98.24",
- "unit": "%",
- "status": "good"
}, - {
- "title": "State of charge",
- "key": "SOC",
- "value": "68.00",
- "unit": "%",
- "status": "neutral"
}, - {
- "title": "Battery temperature",
- "key": "BATT_TEMPERATURE",
- "value": "17.53",
- "unit": "°C",
- "status": "neutral"
}, - {
- "title": "Battery voltage",
- "key": "BATTERY_VOLTAGE",
- "value": "368.40",
- "unit": "V",
- "status": "neutral"
}
]
}
}, - "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "batterySOHTest",
- "reportId": "1234567892",
- "timestamp": "2026-05-28T13:05:14Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "BMW",
- "series": "iX3",
- "model": "G08 (iX3)",
- "buildYear": 2023,
- "fuelType": "electric",
- "mileage": 53618,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-05-28T13:06:19Z"
}Privacy Data Clearing report created Webhook
Sent when a Privacy Data Clearing report has been created, confirming that personal data stored in the vehicle was cleared. The request contains the common fields only.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "privacyDataClearing",
- "reportId": "1234567893",
- "timestamp": "2026-06-02T08:47:40Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Audi",
- "series": "Q5",
- "model": "Q5 (8R)",
- "buildYear": 2012,
- "fuelType": "diesel",
- "mileage": 206067,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "previewLinkImage": "https://reports.carly-enterprise.io/example/privacy-data-clearing-preview.jpg",
- "received": "2026-06-02T08:48:25Z"
}Quick Diagnostics report created Webhook
Sent when a Quick Diagnostics report has been created. Like a Diagnostics report, it
lists the control units (ECUs) that were scanned and the fault codes stored in them; an
ECU without faults has an empty faults list.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
required | Array of objects (DiagnosticsEcu) Control units (ECUs) that were scanned. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "ecus": [
- {
- "name": "Engine control unit",
- "faults": [
- {
- "code": "P0300",
- "text": "P0300 Random/multiple cylinder misfire detected"
}
]
}, - {
- "name": "Airbag control unit",
- "faults": [ ]
}
], - "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "quickDiagnostics",
- "reportId": "1234567894",
- "timestamp": "2026-06-03T07:41:12Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Volkswagen",
- "series": "Golf",
- "model": "Golf VII (5G)",
- "buildYear": 2017,
- "fuelType": "gasoline",
- "mileage": 112480,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-06-03T07:41:58Z"
}Crash Data report created Webhook
Sent when a Crash Data report has been created. The request contains the common fields
only; the crash data read from the vehicle (recorded crashes, deployed airbags) is in the
PDF behind downloadUrl.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "crashData",
- "reportId": "1234567895",
- "timestamp": "2026-06-03T10:15:03Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Volkswagen",
- "series": "Passat",
- "model": "Passat B8 (3G)",
- "buildYear": 2018,
- "fuelType": "diesel",
- "mileage": 143210,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-06-03T10:16:01Z"
}Input Form report created Webhook
Sent when an Input Form report has been created, a report based on a form the user fills
in in the app. The request contains the common fields only; the form content is in the
PDF behind downloadUrl. No preview is created for this report type, so
previewLinkImage and previewLinkPdf are never sent.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
Responses
Request samples
- Payload
{- "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "inputForm",
- "reportId": "1234567896",
- "timestamp": "2026-06-04T12:30:45Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Opel",
- "series": "Corsa",
- "model": "Corsa F",
- "buildYear": 2021,
- "fuelType": "gasoline",
- "mileage": 38950,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-06-04T12:31:20Z"
}Car History report created Webhook
Sent when a Car History report has been created. The request contains the common fields
only; the vehicle history is in the PDF behind downloadUrl.
Request Body schema: application/jsonrequired
| reportId required | string Unique identifier of the report. Use it to recognise a report you have already received. |
| reportType required | string Enum: "carCheck" "diagnostics" "batterySOHTest" "privacyDataClearing" "quickDiagnostics" "crashData" "inputForm" "carHistory" Kind of report. Determines which report-specific fields are present. |
| timestamp required | string Date and time the report was created, in UTC ( |
| timezone required | string Time zone of the device that created the report (IANA name). |
| received required | string Date and time Carly prepared this request, in UTC ( |
| locale required | string Language and region of the app when the report was created, in BCP 47 format. Texts such as ECU names and fault texts are in this language. |
| brandName required | string Vehicle brand. |
| series required | string Vehicle series. |
| model required | string Vehicle model. |
| buildYear required | integer Year the vehicle was built. |
| fuelType required | string Enum: "gasoline" "diesel" "electric" "hybrid" "other" Fuel type of the vehicle. |
| vin required | string Vehicle Identification Number (17 characters). |
| mileageType required | string Enum: "Kilometers" "Miles" Unit of |
| reportSource required | string Product that created the report. |
| userEmail required | string Email address of the user who created the report. |
| userName required | string First and last name of the user who created the report. |
| userTitle required | string Title or role of the user as entered in the user's profile. |
| downloadUrl required | string <uri> Link to the report PDF. The link is signed and valid for 14 days after the request was sent; download the PDF if you need it later. |
| adapterBLEIdentifier | string Identifier of the Carly adapter used for the scan. Missing for reports made with older app versions. |
| mileage | integer Mileage of the vehicle, in the unit given in |
| organizationEmail | string Contact email address of your organization in Carly Enterprise. Missing if your organization has none. |
| previewLinkImage | string <uri> Preview of the report as JPG. Present when a preview was generated. |
| previewLinkPdf | string <uri> Preview of the report as PDF. Present when a preview was generated. |
Responses
Request samples
- Payload
{- "adapterBLEIdentifier": "Carly1A2B3C",
- "reportType": "carHistory",
- "reportId": "1234567897",
- "timestamp": "2026-06-05T08:05:30Z",
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "brandName": "Skoda",
- "series": "Octavia",
- "model": "Octavia III (5E)",
- "buildYear": 2016,
- "fuelType": "diesel",
- "mileage": 187340,
- "mileageType": "Kilometers",
- "vin": "WVWZZZ1JZXW000001",
- "reportSource": "OBCD - powered by Carly",
- "organizationEmail": "jane.doe@example.com",
- "userEmail": "jane.doe@example.com",
- "userName": "Jane Doe",
- "userTitle": "Inspector",
- "received": "2026-06-05T08:06:12Z"
}