Power figures for your website
Show customers what their car could make.
Stock, Stage 1, 2 and 3 power and torque for 9,086 engines across 44 makes. Pick your colours, paste one block of code into your website, and it's done.
- 9,086 engines
- 44 makes
- £5 once, no subscription
Get a key
One payment of £5, with no subscription. Your key is made straight away and emailed to you. It allows 1,000 requests and 20 quote requests a day: plenty for a garage website. Busier than that? Email api@nightfallautomotive.co.uk about a monthly plan.
Already have a key? You don't need to pay again: put it in the code maker below to change your colours or settings any time.
Thank you! Save your key now:
Keep it somewhere safe, like a password manager or a note on your phone. You'll need it to come back and change your colours or settings. We've emailed it to too, and it's filled in for you in the code maker below.
Or bookmark this link, which opens the code maker with your key already in:
Registration lookups use your own DVSA MOT History API details, so they come out of your
DVSA allowance. Apply for free at the DVSA's MOT History API,
then tick Find by registration in the code maker below and paste in the details from their email.
Or look the car up with the DVSA yourself and use /api/v1/match.
Add it to your website
Make your code here. Put in your key, choose what to show and pick colours to match your website: the preview changes as you go. Then copy the code and paste it where you want the lookup to appear.
Preview with sample cars: recent BMW 3 Series and VW Golf. Nothing is sent from here.
<!-- RemapData power figures lookup. Change the colours in the lines just below. -->
<style>
#power-lookup {
--pl-bg: #2E3440; /* background */
--pl-surface: #3B4252; /* boxes and the results card */
--pl-border: #434C5E; /* lines and edges */
--pl-text: #ECEFF4;
--pl-muted: #A7B1C2; /* labels and small print */
--pl-accent: #88C0D0; /* stage tabs, gain bars, highlights */
--pl-bar: #4C566A; /* stock part of the bars */
--pl-button: #5E81AC;
--pl-button-text: #ECEFF4;
--pl-gain: #A3BE8C; /* "+bhp" gains */
--pl-radius: 12px; /* corner roundness */
--pl-font: inherit;
background: var(--pl-bg); color: var(--pl-text); font-family: var(--pl-font); border-radius: var(--pl-radius);
padding: 24px; line-height: 1.5;
}
#power-lookup * { box-sizing: border-box; }
#power-lookup label { display: block; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--pl-muted); margin: 0 0 6px; }
#power-lookup .pl-sel { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
#power-lookup select { width: 100%; margin: 0; padding: 13px 38px 13px 14px; background-color: var(--pl-surface); color: var(--pl-text);
border: 1px solid var(--pl-border); border-radius: calc(var(--pl-radius) * .75); font: inherit; font-size: 15px; line-height: 1.3;
appearance: none; -webkit-appearance: none; cursor: pointer;
background-image: linear-gradient(45deg, transparent 50%, var(--pl-muted) 50%), linear-gradient(135deg, var(--pl-muted) 50%, transparent 50%);
background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }
#power-lookup select:hover:not(:disabled) { border-color: var(--pl-accent); }
#power-lookup select:focus { outline: 2px solid var(--pl-accent); outline-offset: 1px; }
#power-lookup select:disabled { opacity: .45; cursor: not-allowed; }
#power-lookup select option { background: var(--pl-surface); color: var(--pl-text); }
#pl-msg { margin: 12px 0 0; font-size: 14px; color: var(--pl-muted); }
#pl-msg:empty { display: none; }
/* results card */
#pl-result { margin-top: 24px; background: var(--pl-surface); border: 1px solid var(--pl-border); border-radius: var(--pl-radius); padding: 28px; }
#pl-result:empty { display: none; }
#power-lookup .pl-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 16px; align-items: baseline; margin-bottom: 22px; padding-bottom: 18px; border-bottom: 1px solid var(--pl-border); }
#power-lookup .pl-title { font-size: 22px; font-weight: 800; }
#power-lookup .pl-meta { color: var(--pl-muted); font-size: 14px; }
#power-lookup .pl-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
#power-lookup .pl-tabs button { font: inherit; font-size: 16px; padding: 9px 18px; border-radius: calc(var(--pl-radius) * .6); border: 1px solid var(--pl-border); background: transparent; color: var(--pl-muted); cursor: pointer; }
#power-lookup .pl-tabs button span { display: inline-block; min-width: 1.4em; margin-left: 4px; padding: 0 4px; border: 1px solid currentColor; border-radius: 4px; font-size: .8em; line-height: 1.4; text-align: center; }
#power-lookup .pl-tabs button:hover { color: var(--pl-text); border-color: var(--pl-accent); }
#power-lookup .pl-tabs button[aria-selected=true] { background: var(--pl-accent); border-color: var(--pl-accent); color: var(--pl-bg); font-weight: 700; }
#power-lookup .pl-panel { background: var(--pl-bg); border: 1px solid var(--pl-border); border-radius: calc(var(--pl-radius) * .75); padding: 6px 20px; }
#power-lookup .pl-line { display: grid; grid-template-columns: 90px 1fr 30px 1.4fr 1.2fr; align-items: baseline; gap: 6px 10px; padding: 16px 0; }
#power-lookup .pl-line + .pl-line { border-top: 1px solid var(--pl-border); }
#power-lookup .pl-k { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--pl-muted); }
#power-lookup .pl-from { font-size: 22px; color: var(--pl-muted); font-variant-numeric: tabular-nums; }
#power-lookup .pl-arrow { color: var(--pl-muted); }
#power-lookup .pl-to { font-size: 28px; color: var(--pl-text); font-variant-numeric: tabular-nums; }
#power-lookup .pl-to small { font-size: 15px; font-weight: 400; font-style: italic; color: var(--pl-muted); }
#power-lookup .pl-gain { color: var(--pl-gain); font-weight: 700; font-size: 16px; text-align: right; }
#power-lookup .pl-gain small { font-weight: 400; opacity: .85; }
#power-lookup .pl-bar { grid-column: 1 / -1; height: 6px; background: var(--pl-border); border-radius: 99px; overflow: hidden; position: relative; }
#power-lookup .pl-bar i { position: absolute; top: 0; bottom: 0; left: 0; }
#power-lookup .pl-bar .st { background: var(--pl-bar); }
#power-lookup .pl-bar .up { background: var(--pl-accent); }
#power-lookup .pl-carnote { margin: 16px 0 0; padding: 12px 14px; border-left: 3px solid var(--pl-accent); background: var(--pl-bg); border-radius: 0 calc(var(--pl-radius) * .5) calc(var(--pl-radius) * .5) 0; font-size: 14px; }
#power-lookup .pl-ecu { margin-top: 20px; color: var(--pl-muted); font-size: 14px; }
#power-lookup .pl-ecu span { color: var(--pl-text); }
#power-lookup .pl-opts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
#power-lookup .pl-opts span { font-size: 12px; padding: 5px 11px; border: 1px solid var(--pl-border); border-radius: 99px; color: var(--pl-muted); }
#power-lookup .pl-btns { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }
#power-lookup .pl-btns:empty { display: none; }
#power-lookup .pl-cta { display: inline-flex; align-items: center; gap: 8px; padding: 13px 22px; background: var(--pl-button); color: var(--pl-button-text);
border: 0; border-radius: calc(var(--pl-radius) * .75); font: inherit; font-weight: 700; text-decoration: none; cursor: pointer; }
#power-lookup .pl-cta:hover, #power-lookup .pl-cta:focus { color: var(--pl-button-text); filter: brightness(1.12); }
#power-lookup .pl-cta:focus-visible, #power-lookup .pl-tabs button:focus-visible { outline: 2px solid var(--pl-accent); outline-offset: 2px; }
#power-lookup .pl-cta:disabled { opacity: .6; cursor: wait; }
#power-lookup .pl-cta.pl-alt { background: transparent; color: var(--pl-text); box-shadow: inset 0 0 0 1px var(--pl-button); }
#power-lookup .pl-cta.pl-alt:hover, #power-lookup .pl-cta.pl-alt:focus { color: var(--pl-button-text); background: var(--pl-button); filter: none; }
#power-lookup .pl-note { margin: 16px 0 0; font-size: 12px; color: var(--pl-muted); }
#power-lookup .pl-credit { margin: 16px 0 0; font-size: 12px; color: var(--pl-muted); text-align: right; }
#power-lookup .pl-credit a { color: inherit; }
/* registration box: a UK-style yellow plate */
#pl-plate { margin: 0 0 20px; }
#power-lookup .pl-prow { display: flex; gap: 10px; flex-wrap: wrap; }
#pl-reg { flex: 0 1 230px; min-width: 0; margin: 0; padding: 10px 14px; background: #F7D117; color: #111; border: 2px solid #111;
border-radius: calc(var(--pl-radius) * .75); font: inherit; font-size: 22px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; text-align: center; }
#pl-reg::placeholder { color: rgba(17, 17, 17, .45); }
#pl-reg:focus { outline: 2px solid var(--pl-accent); outline-offset: 2px; }
/* quote pop-up */
#pl-quote { width: min(780px, calc(100vw - 32px)); max-height: calc(100vh - 32px); background: var(--pl-surface); color: var(--pl-text); font-family: var(--pl-font);
border: 1px solid var(--pl-border); border-radius: var(--pl-radius); padding: 28px; line-height: 1.5; }
#pl-quote::backdrop { background: rgba(0, 0, 0, .65); }
#pl-quote h3 { margin: 0 0 4px; font-size: 22px; color: var(--pl-accent); }
#pl-qcar { margin: 0 0 18px; color: var(--pl-muted); font-size: 14px; }
#pl-quote .pl-x { position: absolute; top: 10px; right: 12px; background: none; border: 0; color: var(--pl-muted); font-size: 28px; line-height: 1; cursor: pointer; padding: 4px 8px; }
#pl-quote .pl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
#pl-quote .pl-wide { grid-column: 1 / -1; }
#pl-quote .pl-fld { display: block; margin: 0; text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 14px; color: var(--pl-text); }
#pl-quote .pl-fld > span { display: block; margin-bottom: 5px; color: var(--pl-muted); font-size: 13px; }
#pl-quote .pl-fld i { color: var(--pl-accent); font-style: normal; }
#pl-quote input, #pl-quote textarea, #pl-quote select { width: 100%; margin: 0; padding: 12px 14px; background-color: var(--pl-bg); color: var(--pl-text);
border: 1px solid var(--pl-border); border-radius: calc(var(--pl-radius) * .6); font: inherit; font-size: 15px; }
#pl-quote textarea { resize: vertical; min-height: 90px; }
#pl-quote form > .pl-fld { margin-top: 12px; }
#pl-qopts { margin: 14px 0 0; padding: 12px 16px 14px; border: 1px solid var(--pl-border); border-radius: calc(var(--pl-radius) * .6); background: var(--pl-bg); display: flex; flex-wrap: wrap; gap: 8px 18px; }
#pl-qopts[hidden] { display: none; }
#pl-qopts legend { padding: 0 6px; color: var(--pl-accent); font-size: 13px; font-weight: 700; }
#pl-qopts label { display: inline-flex; align-items: center; gap: 7px; margin: 0; font-size: 14px; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--pl-text); cursor: pointer; }
#pl-qopts input { width: 16px; height: 16px; margin: 0; padding: 0; accent-color: var(--pl-accent); }
#pl-quote .pl-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
#pl-qmsg { margin: 12px 0 0; font-size: 14px; }
#pl-qmsg:empty { display: none; }
@media (max-width: 520px) {
#power-lookup { padding: 16px; }
#pl-result, #pl-quote { padding: 20px; }
#pl-quote .pl-grid { grid-template-columns: 1fr; }
#power-lookup .pl-line { grid-template-columns: auto 1fr; gap: 4px 10px; }
#power-lookup .pl-k { grid-column: 1 / -1; }
#power-lookup .pl-from, #power-lookup .pl-arrow { display: none; }
#power-lookup .pl-panel { padding: 4px 14px; }
}
</style>
<div id="power-lookup">
<!-- Find by registration: needs your DVSA details on your key. To switch it on, delete the two lines marked DELETE. -->
<!-- DELETE
<form id="pl-plate">
<label for="pl-reg">Find by registration</label>
<div class="pl-prow">
<input id="pl-reg" placeholder="YOUR REG" maxlength="10" autocomplete="off">
<button type="submit" class="pl-cta">Find my car</button>
</div>
</form>
DELETE -->
<div class="pl-sel">
<div><label for="pl-make">Make</label><select id="pl-make"><option value="">Select make</option></select></div>
<div><label for="pl-model">Model</label><select id="pl-model" disabled><option value="">Select model</option></select></div>
<div><label for="pl-gen">Generation</label><select id="pl-gen" disabled><option value="">Select generation</option></select></div>
<div><label for="pl-engine">Engine</label><select id="pl-engine" disabled><option value="">Select engine</option></select></div>
</div>
<p id="pl-msg" aria-live="polite"></p>
<div id="pl-result" aria-live="polite"></div>
<!-- Quote form: requests are emailed to the address on your key. -->
<dialog id="pl-quote" aria-labelledby="pl-qh">
<form id="pl-qform">
<button type="button" class="pl-x" id="pl-qclose" aria-label="Close">×</button>
<h3 id="pl-qh">Get a quote</h3>
<p id="pl-qcar"></p>
<div class="pl-grid">
<label class="pl-fld"><span>Name <i>*</i></span><input name="name" required autocomplete="name"></label>
<label class="pl-fld"><span>Email <i>*</i></span><input name="email" type="email" required autocomplete="email"></label>
<label class="pl-fld"><span>Phone <i>*</i></span><input name="phone" type="tel" required autocomplete="tel"></label>
<label class="pl-fld"><span>Vehicle registration <i>*</i></span><input name="reg" required maxlength="12" style="text-transform:uppercase"></label>
<label class="pl-fld pl-wide"><span>Postcode <i>*</i></span><input name="postcode" required autocomplete="postal-code" maxlength="10" style="text-transform:uppercase"></label>
<label class="pl-fld pl-wide"><span>What would you like?</span><select name="solution"></select></label>
</div>
<fieldset id="pl-qopts"><legend>Options</legend></fieldset>
<label class="pl-fld"><span>Anything else?</span><textarea name="message" rows="3"></textarea></label>
<input name="website" class="pl-hp" tabindex="-1" autocomplete="off" aria-hidden="true">
<p id="pl-qmsg" aria-live="polite"></p>
<div class="pl-btns"><button type="submit" class="pl-cta">Send</button><button type="button" class="pl-cta pl-alt" id="pl-qback">← Back</button></div>
</form>
</dialog>
<p class="pl-credit">Powered by <a href="https://www.remapdata.app/" target="_blank" rel="nofollow noopener">RemapData</a></p> <!-- you can delete this line -->
</div>
<script>
(function () {
var KEY = 'pk_YOUR_KEY_HERE';
var BOOK = "", BOOK_TEXT = "Book now →"; // a second button beside "Get a quote" (leave BOOK as "" for none)
var NOTE = "Figures are estimates for a healthy, standard vehicle and can vary with condition, fuel and modifications."; // small print under the figures ("" for none)
var API = 'https://www.remapdata.app/api/v1/';
var $ = function (id) { return document.getElementById(id); };
var res = $('pl-result'), makes = [], make, model, engines = [], lastReg = '', opened = 0;
function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return '&#' + c.charCodeAt(0) + ';'; }); }
function get(path) {
return fetch(API + path, { headers: { 'X-API-Key': KEY } }).then(function (r) { return r.json(); })
.then(function (d) { if (!d.ok) throw new Error(d.message); return d; });
}
function fill(id, label, items, text) {
var el = $(id);
el.innerHTML = '<option value="">' + label + '</option>';
items.forEach(function (x, i) { el.add(new Option(text(x), i)); });
el.disabled = !items.length;
}
function clear(ids) { ids.forEach(function (id) { fill(id, $(id).options[0].text, [], null); }); res.innerHTML = ''; }
function show(msg) { $('pl-msg').textContent = msg; }
function years(name) { return name.replace(/\s*->\s*/, '–').replace(/present/i, 'on'); }
function showEngines(list, label, text) {
engines = list;
fill('pl-engine', label, list, text);
}
get('makes').then(function (d) {
makes = d.makes;
fill('pl-make', 'Select make', makes, function (m) { return m.name; });
}).catch(function (e) { show(e.message); });
$('pl-make').onchange = function () {
clear(['pl-model', 'pl-gen', 'pl-engine']);
show('');
if (this.value === '') return;
get('makes/' + makes[this.value].slug).then(function (d) {
make = d;
fill('pl-model', 'Select model', make.models, function (m) { return m.name; });
}).catch(function (e) { show(e.message); });
};
$('pl-model').onchange = function () {
clear(['pl-gen', 'pl-engine']);
if (this.value === '') return;
model = make.models[this.value];
fill('pl-gen', 'Select generation', model.generations, function (g) { return years(g.name); });
};
$('pl-gen').onchange = function () {
clear(['pl-engine']);
if (this.value === '') return;
showEngines(model.generations[this.value].engines, 'Select engine', function (e) { return e.variant + ' (' + e.fuel + ', ' + e.stock.bhp + ' bhp)'; });
};
// the results card: one tab per stage, each showing stock → stage for power and torque
$('pl-engine').onchange = function () {
if (this.value === '') { res.innerHTML = ''; return; }
var e = engines[this.value], st = e.stock || {};
var stages = [1, 2, 3].filter(function (n) { return e['stage' + n]; });
var maxB = Math.max.apply(null, [st.bhp || 0].concat(stages.map(function (n) { return e['stage' + n].bhp || 0; }))) || 1;
var maxN = Math.max.apply(null, [st.nm || 0].concat(stages.map(function (n) { return e['stage' + n].nm || 0; }))) || 1;
function line(label, unit, stock, val, max) {
var h = '<div class="pl-line"><span class="pl-k">' + label + '</span><span class="pl-from">' + (stock || '—') + '</span>' +
'<span class="pl-arrow" aria-hidden="true">→</span>';
if (!val) return h + '<b class="pl-to">—</b><span></span></div>';
var gain = val - stock, pct = stock ? Math.round(gain / stock * 100) : 0;
return h + '<b class="pl-to">' + val + ' <small>' + unit + '</small></b>' +
'<span class="pl-gain">' + (gain >= 0 ? '+' : '') + gain + ' ' + unit + (stock ? ' <small>(' + (pct >= 0 ? '+' : '') + pct + '%)</small>' : '') + '</span>' +
'<div class="pl-bar"><i class="st" style="width:' + (Math.min(stock, val) / max * 100) + '%"></i>' +
(val > stock ? '<i class="up" style="left:' + (stock / max * 100) + '%;width:' + ((val - stock) / max * 100) + '%"></i>' : '') + '</div></div>';
}
function panel(n) {
var s = e['stage' + n] || {};
return line('Power', 'bhp', st.bhp, s.bhp, maxB) + line('Torque', 'Nm', st.nm, s.nm, maxN);
}
var tabs = stages.length ? '<div class="pl-tabs" role="tablist">' + stages.map(function (n, i) {
return '<button type="button" role="tab" data-st="' + n + '" aria-selected="' + (i === 0) + '">Stage <span>' + n + '</span></button>';
}).join('') + '</div>' : '';
var cc = e.cc ? (e.cc / 1000).toFixed(1) + 'L ' : '';
res.innerHTML =
'<div class="pl-head"><div class="pl-title">' + esc(e.make + ' ' + e.model + ' ' + e.variant) + '</div>' +
'<div class="pl-meta">' + esc(years(e.generation).replace(/\s*\(.*\)$/, '') + ' · ' + cc + e.fuel + (e.hybrid ? ' ' + e.hybrid : '')) + '</div></div>' +
tabs + '<div class="pl-panel" role="tabpanel">' + panel(stages[0] || 0) + '</div>' +
(e.note ? '<p class="pl-carnote">' + esc(e.note) + '</p>' : '') +
(e.ecu ? '<div class="pl-ecu">ECU: <span>' + esc(e.ecu) + '</span></div>' : '') +
(e.options.length ? '<div class="pl-opts">' + e.options.map(function (o) { return '<span>' + esc(o) + '</span>'; }).join('') + '</div>' : '') +
'<div class="pl-btns">' +
($('pl-quote') ? '<button type="button" class="pl-cta" id="pl-qbtn">Get a quote</button>' : '') +
(/^https?:\/\//.test(BOOK) ? '<a class="pl-cta pl-alt" href="' + esc(BOOK) + '" target="_blank" rel="noopener">' + esc(BOOK_TEXT) + '</a>' : '') +
'</div>' +
(NOTE ? '<p class="pl-note">' + esc(NOTE) + '</p>' : '');
var stage = stages[0] || 1;
[].forEach.call(res.querySelectorAll('.pl-tabs button'), function (b) {
b.onclick = function () {
[].forEach.call(res.querySelectorAll('.pl-tabs button'), function (x) { x.setAttribute('aria-selected', x === b); });
stage = +b.getAttribute('data-st');
res.querySelector('.pl-panel').innerHTML = panel(stage);
};
});
if ($('pl-qbtn')) $('pl-qbtn').onclick = function () { openQuote(e, stages, stage); };
};
// quote form: only runs when it's switched on above
function openQuote(e, stages, stage) {
var f = $('pl-qform'), box = $('pl-qopts');
f.reset();
$('pl-qmsg').textContent = '';
f.querySelector('[type=submit]').disabled = false;
f.car = { name: e.make + ' ' + e.model + ' ' + e.variant + ' (' + e.stock.bhp + ' bhp)', gen: years(e.generation) };
$('pl-qcar').textContent = f.car.name + ' · ' + f.car.gen;
f.elements.namedItem('reg').value = lastReg;
var want = f.elements.namedItem('solution');
want.innerHTML = '';
stages.forEach(function (n) {
var s = e['stage' + n];
want.add(new Option('Stage ' + n + ' (' + [s.bhp ? s.bhp + ' bhp' : '', s.nm ? s.nm + ' Nm' : ''].filter(Boolean).join(' / ') + ')', 'Stage ' + n, false, n === stage));
});
['Options only', 'Not sure'].forEach(function (s) { want.add(new Option(s, s)); });
[].slice.call(box.querySelectorAll('label')).forEach(function (l) { box.removeChild(l); });
e.options.forEach(function (o) {
var l = box.appendChild(document.createElement('label')), c = l.appendChild(document.createElement('input'));
c.type = 'checkbox'; c.value = o;
l.appendChild(document.createTextNode(o));
});
box.hidden = !e.options.length;
opened = Date.now();
$('pl-quote').showModal();
}
if ($('pl-quote')) {
$('pl-qclose').onclick = $('pl-qback').onclick = function () { $('pl-quote').close(); };
$('pl-qform').onsubmit = function (ev) {
ev.preventDefault();
var f = this, btn = f.querySelector('[type=submit]'), body = { car: f.car, t: Date.now() - opened };
['name', 'email', 'phone', 'reg', 'postcode', 'solution', 'message', 'website'].forEach(function (k) { body[k] = f.elements.namedItem(k).value; });
body.options = [].map.call(f.querySelectorAll('#pl-qopts input:checked'), function (c) { return c.value; });
btn.disabled = true;
$('pl-qmsg').textContent = 'Sending…';
fetch(API + 'quote', { method: 'POST', headers: { 'X-API-Key': KEY, 'Content-Type': 'application/json' }, body: JSON.stringify(body) })
.then(function (r) { return r.json(); })
.then(function (d) {
$('pl-qmsg').textContent = d.message || (d.ok ? 'Sent. Thank you, we\'ll be in touch soon.' : 'Sorry, that could not be sent.');
if (!d.ok) btn.disabled = false;
})
.catch(function () { $('pl-qmsg').textContent = 'Sorry, that could not be sent. Please try again.'; btn.disabled = false; });
};
}
// registration box: only runs when it's switched on above
if ($('pl-plate')) $('pl-plate').onsubmit = function (ev) {
ev.preventDefault();
var reg = $('pl-reg').value.replace(/[^a-z0-9]/gi, '');
if (reg.length < 2) { show('Please type your registration.'); return; }
show('Searching…');
get('plate?reg=' + encodeURIComponent(reg)).then(function (d) {
var v = d.vehicle, found = [v.year, v.make, v.model].filter(Boolean).join(' ');
lastReg = v.reg || reg;
$('pl-make').value = '';
clear(['pl-model', 'pl-gen', 'pl-engine']);
if (!d.engines.length) { show('Found: ' + found + '. Please pick your vehicle below.'); return; }
$('pl-make').value = makes.map(function (m) { return m.name; }).indexOf(d.make);
showEngines(d.engines, 'Select engine (' + d.engines.length + ' match)', function (e) {
return e.model + ' ' + e.variant + ' (' + years(e.generation) + ', ' + e.stock.bhp + ' bhp)';
});
show('Found: ' + found + '.' + (d.engines.length > 1 ? ' Now pick your engine.' : ''));
if (d.engines.length === 1) { $('pl-engine').value = 0; $('pl-engine').onchange(); }
}).catch(function (e) { show(e.message); });
};
})();
</script>
Want to change something later? Come back here, or edit the colour lines at the top of the code. To switch the
registration box or quote button on by hand, delete the two lines marked DELETE around it.
A key in a web page can be seen by anyone who views the page's source, so ask us to lock your key to your website's address. Each visitor uses two requests: one for the list of makes and one for the make they pick. A registration search uses one request and one registration lookup. The quote form's emails show your business name, and pressing reply goes to your customer. Tell us your postcode and how far you travel, and each email will also say how far away the customer is.
For developers
The addresses, an example engine and the error codes. Everything above is all most people need.
Send your key in an X-API-Key header with every request:
curl -H "X-API-Key: pk_YOUR_KEY_HERE" https://www.remapdata.app/api/v1/makes
| Address | What you get |
|---|---|
/api/v1/makes | Every make, its slug and how many engines it has. |
/api/v1/makes/bmw | One make: models → generations → engines, with all figures. |
/api/v1/engines/1152 | One engine, by its id. |
/api/v1/plate?reg=AB12CDE | A UK registration's make, model, fuel, engine size and year, and the engines that fit it. Needs your DVSA details added to your key. |
/api/v1/match?make=BMW&model=320D%20M%20SPORT&fuel=Diesel&cc=1995&year=2017 | The engines that fit a car you've looked up with the DVSA yourself. Only make is required; the more you add, the closer the match. |
POST /api/v1/quote | Sends a quote request to your email address. The paste-in lookup's pop-up uses this. |
POST /api/v1/mot | Saves your DVSA details on your key. The code maker below uses this; it only works from this website. |
/api/v1/usage | Your plan, today's use and your limits. Doesn't count towards them. |
An engine
{
"id": 1152,
"make": "BMW", "model": "3 Series", "generation": "2011 -> 2015 (F3x)", "years": [2011, 2015],
"variant": "335i", "fuel": "Petrol", "hybrid": null, "cc": 2979, "ecu": "Bosch MEVD17.2.G / Bosch MEVD17.2.6",
"stock": {"bhp": 306, "nm": 400},
"stage1": {"bhp": 370, "nm": 520},
"stage2": null,
"stage3": null,
"options": ["DTC Delete", "Pops & Bangs", "Speed Limiter Removal"]
}
A stage is null when there are no figures for it. years ends in null for cars still on sale.
Some engines also have a note.
Limits and errors
Daily limits reset at midnight UTC. Every reply has "ok"; when it's false there's a
"message" saying why: 401 missing or unknown key, 403 not in your plan,
404 not found, 429 daily limit reached.