{"openapi":"3.0.3","info":{"title":"Know Auto API","description":"Look up vehicles from the Danish vehicle register (DMR / Det Digitale Motorregister), and (with an account) subscribe to webhooks for new/changed vehicles. Vehicle lookups are free and open — no API key required. Account and webhook endpoints require a bearer token (see the bearerAuth security scheme below). An equivalent GraphQL API is also available for the read endpoints, plus webhook mutations; see /graphiql.","version":"1.0.0"},"servers":[{"url":"https://api.knowauto.dk"}],"paths":{"/vehicles":{"get":{"summary":"Search vehicles","description":"Search by registration number or chassis number (substring match, anywhere in the value), internal ID (koeretoej_ident, exact match), status (exact match), brand/vehicle type/fuel type (exact match), or a first-registration/leasing-expiry/estimated-next-inspection date range. At least one is required. estimated_next_inspection_on (on returned vehicles) is a computed heuristic from fixed Danish inspection-interval rules, not official DMR data. Identical search behavior to the GraphQL API's `vehicles` query.","parameters":[{"name":"registration_number","in":"query","schema":{"type":"string"},"description":"Substring match"},{"name":"chassis_number","in":"query","schema":{"type":"string"},"description":"Substring match"},{"name":"koeretoej_ident","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Exact match, e.g. Registreret, Afmeldt, Skrottet"},{"name":"brand_name","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"vehicle_type_name","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"fuel_type_name","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"first_registered_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"first_registered_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"leasing_valid_to_from","in":"query","schema":{"type":"string","format":"date"},"description":"Leasing period expiring on/after this date"},{"name":"leasing_valid_to_to","in":"query","schema":{"type":"string","format":"date"},"description":"Leasing period expiring on/before this date"},{"name":"estimated_next_inspection_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"estimated_next_inspection_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"vehicles":{"type":"array","items":{"$ref":"#/components/schemas/VehicleSummary"}},"total_count":{"type":"integer","description":"Capped — see count_capped"},"count_capped":{"type":"boolean","description":"True if total_count hit the cap (the real total is >= total_count)"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"description":"No filter provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/vehicles/{id}":{"get":{"summary":"Get a single vehicle by public_id or internal id, with full details","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Either public_id (a stable UUID, preferred -- unlike id, it survives the weekly re-import) or the legacy internal database id."}],"responses":{"200":{"description":"Vehicle detail","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/VehicleDetail"},{"type":"object","properties":{"equipment":{"type":"array","items":{"$ref":"#/components/schemas/VehicleEquipmentItem"}},"permits":{"type":"array","items":{"$ref":"#/components/schemas/VehiclePermit"}},"fuel_types":{"type":"array","items":{"$ref":"#/components/schemas/VehicleFuelType"}},"estimated_ownership_tax":{"$ref":"#/components/schemas/OwnershipTaxEstimate"}}}]}}}},"404":{"description":"No vehicle with that ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/vehicle_changes":{"get":{"summary":"Look up detected vehicle changes by time period","description":"New registrations and field-level updates, detected during each weekly import. No authentication required — open like the vehicle lookup endpoints. Identical search behavior to the GraphQL API's `vehicleChanges` query.","parameters":[{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"koeretoej_ident","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"change_type","in":"query","schema":{"type":"string","enum":["created","updated"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"vehicle_changes":{"type":"array","items":{"$ref":"#/components/schemas/VehicleChange"}},"total_count":{"type":"integer","description":"Capped — see count_capped"},"count_capped":{"type":"boolean"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}}}}},"/account/register":{"post":{"summary":"Create an account","description":"Also issues a dashboard session token and a first (\"Default\") API key, so no separate login call is needed right after registering. Rate-limited to 5 attempts/hour per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"201":{"description":"Account created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterResponse"}}}},"422":{"description":"Validation failed (e.g. email already taken)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/login":{"post":{"summary":"Log in, issuing a new dashboard session token","description":"Rate-limited to 10 attempts/hour per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Logged in","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"401":{"description":"Invalid email or password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/logout":{"delete":{"summary":"Log out, invalidating the dashboard session token used to authenticate this request","security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Logged out"},"401":{"description":"Invalid or expired session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/api_keys":{"get":{"summary":"List the authenticated account's API keys","description":"Requires a dashboard session token specifically — an API key can't be used to manage other API keys.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"API keys","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}},"401":{"description":"Invalid or expired session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a new API key","description":"Requires a dashboard session token specifically. The plaintext token is only ever returned here — only a digest is stored.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"401":{"description":"Invalid or expired session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/api_keys/{id}":{"delete":{"summary":"Revoke an API key","description":"Requires a dashboard session token specifically.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Revoked"},"401":{"description":"Invalid or expired session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No API key with that ID on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"summary":"List the authenticated account's webhook subscriptions","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Webhook subscriptions","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookSubscription"}}}}},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a webhook subscription","description":"url must be https and resolve to a public (non-private/loopback/link-local) address. target_koeretoej_ident is required for event_type specific_vehicle, disallowed otherwise.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","event_type"],"properties":{"url":{"type":"string"},"event_type":{"type":"string","enum":["created","any_change","specific_vehicle"]},"target_koeretoej_ident":{"type":"string"}}}}}},"responses":{"201":{"description":"Webhook created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionCreateResponse"}}}},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}}}}},"/webhooks/{id}":{"delete":{"summary":"Delete a webhook subscription","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No webhook with that ID on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{webhook_subscription_id}/deliveries":{"get":{"summary":"List a webhook subscription's delivery attempts (most recent 100)","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhook_subscription_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery attempts","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No webhook with that ID on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/saved_searches":{"get":{"summary":"List the authenticated account's saved searches","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Saved searches","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SavedSearch"}}}}},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a saved search, checked against newly-registered vehicles on every weekly import","description":"At least one filter is required. Filters are the same extended-search fields as GET /vehicles (not registration_number/chassis_number/koeretoej_ident/status -- a search for one already-known vehicle doesn't fit \"notify me when a new one appears\"). webhook_url is optional: when given, also creates a linked webhook subscription (event_type saved_search_match) delivered the same way as the other webhook event types (see POST /webhooks) -- the whole request rolls back together if the URL fails the SSRF safety check.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"brand_name":{"type":"string"},"vehicle_type_name":{"type":"string"},"fuel_type_name":{"type":"string"},"first_registered_from":{"type":"string","format":"date"},"first_registered_to":{"type":"string","format":"date"},"leasing_valid_to_from":{"type":"string","format":"date"},"leasing_valid_to_to":{"type":"string","format":"date"},"estimated_next_inspection_from":{"type":"string","format":"date"},"estimated_next_inspection_to":{"type":"string","format":"date"},"name":{"type":"string"},"webhook_url":{"type":"string"}}}}}},"responses":{"201":{"description":"Saved search created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedSearch"}}}},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"No filter given, or webhook_url failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}}}}},"/saved_searches/{id}":{"patch":{"summary":"Pause or resume a saved search","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedSearch"}}}},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No saved search with that ID on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete a saved search","description":"Also deletes its linked webhook subscription, if any.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Invalid or missing credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No saved search with that ID on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Either an API key (`Account::ApiKey`, from POST /account/api_keys or the register response) or a dashboard session token (from POST /account/login or the register response). /account/api_keys specifically requires a dashboard session token, not an API key — everything else under /account and /webhooks accepts either."}},"schemas":{"VehicleSummary":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"public_id":{"type":"string","nullable":true},"koeretoej_ident":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"registration_number":{"type":"string","nullable":true},"chassis_number":{"type":"string","nullable":true},"brand_name":{"type":"string","nullable":true},"model_type_name":{"type":"string","nullable":true},"variant_type_name":{"type":"string","nullable":true},"model_year":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"status":{"type":"string","nullable":true},"vehicle_type_name":{"type":"string","nullable":true},"fuel_type_name":{"type":"string","nullable":true},"leasing_valid_from":{"type":"string","format":"date","nullable":true},"leasing_valid_to":{"type":"string","format":"date","nullable":true},"estimated_next_inspection_on":{"type":"string","format":"date","nullable":true}}},"VehicleDetail":{"type":"object","properties":{"approved_category":{"type":"string","nullable":true},"axle_count":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"axle_distance":{"type":"string","nullable":true},"body_type_name":{"type":"string","nullable":true},"brand_name":{"type":"string","nullable":true},"brand_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"chassis_number":{"type":"string","nullable":true},"chassis_number_location":{"type":"string","nullable":true},"co2_g_per_km":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"color_name":{"type":"string","nullable":true},"color_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"combination_weight_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"comment":{"type":"string","nullable":true},"coupling_load_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"created_at":{"type":"string","format":"date-time","nullable":true},"created_from":{"type":"string","nullable":true},"curb_weight_max_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"curb_weight_min_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"door_count":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"driven_axles":{"type":"string","nullable":true},"emission_co":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"emission_hc_plus_nox":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"emission_nox":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_cylinder_count":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_displacement_cc":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_driving_noise_db":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_electric_consumption":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_fuel_cell":{"type":"boolean","nullable":true},"engine_innovative_tech":{"type":"string","nullable":true},"engine_innovative_tech_count":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_km_per_liter":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_marking":{"type":"string","nullable":true},"engine_max_power_kw":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_mileage_documented":{"type":"boolean","nullable":true},"engine_mileage_km":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"engine_norm_name":{"type":"string","nullable":true},"engine_norm_number":{"type":"string","nullable":true},"engine_stand_noise_db":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"eu_variant":{"type":"string","nullable":true},"eu_version":{"type":"string","nullable":true},"first_registered_on":{"type":"string","format":"date","nullable":true},"fuel_type_name":{"type":"string","nullable":true},"fuel_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"heavy_zero_emission":{"type":"boolean","nullable":true},"koeretoej_ident":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"last_inspection_on":{"type":"string","format":"date","nullable":true},"last_inspection_result":{"type":"string","nullable":true},"last_inspection_status":{"type":"string","nullable":true},"last_inspection_status_at":{"type":"string","format":"date-time","nullable":true},"last_inspection_type":{"type":"string","nullable":true},"leasing_valid_from":{"type":"string","format":"date","nullable":true},"leasing_valid_to":{"type":"string","format":"date","nullable":true},"max_axle_load_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"max_speed_kmh":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"model_type_name":{"type":"string","nullable":true},"model_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"model_year":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"ncap_test":{"type":"boolean","nullable":true},"net_load_value":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"other_equipment":{"type":"string","nullable":true},"particle_filter":{"type":"boolean","nullable":true},"particles":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"passenger_count":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"registration_expires_on":{"type":"string","format":"date","nullable":true},"registration_number":{"type":"string","nullable":true},"registration_right_valid_from":{"type":"string","format":"date","nullable":true},"registration_right_valid_to":{"type":"string","format":"date","nullable":true},"registration_status":{"type":"string","nullable":true},"registration_status_at":{"type":"string","format":"date-time","nullable":true},"seats_max":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"seats_min":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"semi_trailer_max_axle_load_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"smoke_density":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"standing_places_max":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"standing_places_min":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"status":{"type":"string","nullable":true},"status_at":{"type":"string","format":"date-time","nullable":true},"suitable_for_taxi":{"type":"boolean","nullable":true},"tax_axle_count":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"tax_axle_load_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"technical_total_weight_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"tires_description":{"type":"string","nullable":true},"total_weight_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"towing_possible":{"type":"boolean","nullable":true},"towing_weight_braked_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"towing_weight_unbraked_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"track_width_front":{"type":"string","nullable":true},"track_width_rear":{"type":"string","nullable":true},"traffic_damage":{"type":"string","nullable":true},"trailer_total_weight_kg":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"type_approval_number":{"type":"string","nullable":true},"type_notification_number":{"type":"string","nullable":true},"type_type_name":{"type":"string","nullable":true},"type_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"updated_at":{"type":"string","format":"date-time","nullable":true},"usage_name":{"type":"string","nullable":true},"usage_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"v_value_air":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"v_value_mechanical":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"variant_type_name":{"type":"string","nullable":true},"variant_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"vehicle_condition":{"type":"string","nullable":true},"vehicle_type_name":{"type":"string","nullable":true},"vehicle_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"veteran_original":{"type":"boolean","nullable":true},"estimated_next_inspection_on":{"type":"string","format":"date","nullable":true},"euro_norm_name":{"type":"string","nullable":true},"euro_norm_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"public_id":{"type":"string","nullable":true}}},"VehicleEquipmentItem":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"created_at":{"type":"string","format":"date-time","nullable":true},"equipment_type_name":{"type":"string","nullable":true},"equipment_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"shown_on_default_creation":{"type":"boolean","nullable":true},"shown_on_inquiry":{"type":"boolean","nullable":true},"shown_on_inspection":{"type":"boolean","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true}}},"VehiclePermit":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"comment":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"detail_choice":{"type":"string","nullable":true},"permit_type_name":{"type":"string","nullable":true},"permit_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"updated_at":{"type":"string","format":"date-time","nullable":true},"valid_from":{"type":"string","format":"date","nullable":true}}},"VehicleFuelType":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"created_at":{"type":"string","format":"date-time","nullable":true},"drivkraft_type_name":{"type":"string","nullable":true},"drivkraft_type_number":{"type":"string","nullable":true,"description":"Numeric, returned as a string to avoid precision loss on large values"},"updated_at":{"type":"string","format":"date-time","nullable":true}}},"OwnershipTaxEstimate":{"type":"object","description":"Not an official Skattestyrelsen/DMR figure -- reconstructed from Skatteministeriet's published bracket tables. Skattestyrelsen itself stopped showing the real billed amount in its own vehicle lookups in October 2021, since it can reveal personal/tax matters about the owner.","properties":{"applicable":{"type":"boolean","description":"False when no estimate could be computed -- see note for why."},"regime":{"type":"string","nullable":true,"enum":["co2_ejerafgift","groen_ejerafgift","vaegtafgift",null]},"half_yearly_dkk":{"type":"integer","nullable":true},"yearly_dkk":{"type":"integer","nullable":true},"note":{"type":"string","nullable":true}}},"VehicleChange":{"type":"object","properties":{"id":{"type":"integer"},"koeretoej_ident":{"type":"string"},"change_type":{"type":"string","enum":["created","updated"]},"changed_fields":{"type":"object","description":"field_name => {from:, to:} for each field that changed. For change_type=created, every field is present with from: null.","additionalProperties":{"type":"object","properties":{"from":{},"to":{}}}},"detected_at":{"type":"string","format":"date-time"}}},"User":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string"}}},"RegisterResponse":{"type":"object","description":"Also creates a dashboard session and a first API key (named \"Default\") in one step.","properties":{"user":{"$ref":"#/components/schemas/User"},"dashboard_token":{"type":"string"},"api_key":{"type":"string"}}},"LoginResponse":{"type":"object","properties":{"dashboard_token":{"type":"string"}}},"ApiKey":{"type":"object","description":"The token itself is never included here — only shown once, in ApiKeyCreateResponse.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"last_used_at":{"type":"string","format":"date-time","nullable":true},"revoked_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"ApiKeyCreateResponse":{"type":"object","properties":{"token":{"type":"string","description":"Shown once — store it now."}}},"WebhookSubscription":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string"},"event_type":{"type":"string","enum":["created","any_change","specific_vehicle","saved_search_match"],"description":"saved_search_match is only ever created via POST /saved_searches (webhook_url), never directly here"},"target_koeretoej_ident":{"type":"string","nullable":true,"description":"Set only for event_type specific_vehicle"},"active":{"type":"boolean","description":"Auto-set to false after repeated fully-exhausted deliveries"},"created_at":{"type":"string","format":"date-time"}}},"WebhookSubscriptionCreateResponse":{"allOf":[{"$ref":"#/components/schemas/WebhookSubscription"},{"type":"object","properties":{"secret":{"type":"string","description":"Shown once — used to verify the X-Webhook-Signature header on deliveries. Store it now."}}}]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"string","enum":["pending","delivered","failed"]},"attempt_count":{"type":"integer"},"last_attempted_at":{"type":"string","format":"date-time","nullable":true},"response_code":{"type":"integer","nullable":true},"response_body":{"type":"string","nullable":true,"description":"Truncated"},"next_retry_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"SavedSearch":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"filters":{"type":"object","description":"Snake_case keys matching the request params below (brand_name, first_registered_from, etc.)","additionalProperties":true},"confirmed":{"type":"boolean","description":"Always true for a search created here -- no email confirmation step, the account is already authenticated"},"active":{"type":"boolean"},"webhook_subscription_id":{"type":"integer","nullable":true},"webhook_url":{"type":"string","nullable":true,"description":"Set only if webhook_url was given at creation"},"created_at":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"error":{"type":"string"}}},"ValidationError":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"string"}}}}}}}