Retrieve Apple's displayed purchase-date and warranty/AppleCare coverage information for a device using its serial number.
Use Cases
Use when given an Apple device serial number and asked for its purchase date, coverage type or status, expiration date, or AppleCare+ status.
Automation Flow
- Navigate directly to
https://checkcoverage.apple.com/coverage?locale={locale}. Useen_CAfor Canadian English, or a requested supported locale. No homepage navigation is needed. - Wait for both
input#serial-number-inputandinput#captcha-input, then enter{serial-number}intoinput#serial-number-input. - Solve the currently visible CAPTCHA using the browser automation CAPTCHA solver. Enter only the answer for the currently displayed image into
input#captcha-input, dispatchinginputandchangeevents if the automation API does not do so itself. - If the CAPTCHA image is absent, blank, unreadable, the submit button remains disabled, or Apple reports a CAPTCHA validation failure, click
button#captcha-refresh-btn, wait for the replacement CAPTCHA, discard the old answer, and solve the new image. Make at most three CAPTCHA attempts; if it remains unreadable or rejected, stop and request human assistance. - Submit with
button[type='submit']:nth-of-type(1). Wait for visible coverage-result text or a visible validation error rather than a fixed delay. Do not treat a CAPTCHA error as a successful lookup. - On the result page, run this
evaluate()extractor. SetserialNumberfrom the caller-supplied{serial-number}when assembling the final response, because the result page may not retain the input field.
(() => {
const body = (document.body?.innerText || '')
.replace(/\u00a0/g, ' ')
.replace(/\r/g, '');
const lines = body.split(/\n+/).map(s => s.trim()).filter(Boolean);
const months = {
january: '01', february: '02', march: '03', april: '04', may: '05', june: '06',
july: '07', august: '08', september: '09', october: '10', november: '11', december: '12'
};
const dateRE = '(January|February|March|April|May|June|July|August|September|October|November|December)\\s+(\\d{1,2}),\\s+(\\d{4})';
const normalize = value => {
const m = value?.match(new RegExp(`^${dateRE}$`, 'i'));
return m ? `${m[3]}-${months[m[1].toLowerCase()]}-${m[2].padStart(2, '0')}` : null;
};
const textMatch = pattern => body.match(new RegExp(pattern, 'i'));
const purchaseMatch = textMatch(`\\b(Purchased\\s+${dateRE})`);
const endMatch = textMatch(`\\b((?:Expired|Expires\\s+on)\\s+${dateRE})`);
const coverageIndex = lines.findIndex(line => /^(AppleCare\+?|Coverage Expired)$/i.test(line));
const endIndex = lines.findIndex(line => new RegExp(`\\b(?:Expired|Expires\\s+on)\\s+${dateRE}\\b`, 'i').test(line));
const coverageType = coverageIndex >= 0 ? lines[coverageIndex] :
(/\bCoverage Expired\b/i.test(body) ? 'Coverage Expired' :
(textMatch('\\bAppleCare\\+?\\b')?.[0] ||
(endIndex > 0 && /coverage|care|repair|support/i.test(lines[endIndex - 1]) ? lines[endIndex - 1] : null)));
const coverageEndText = endMatch ? endMatch[1] : null;
const endDateMatch = coverageEndText?.match(new RegExp(dateRE, 'i'));
const coverageEndDate = endDateMatch ? normalize(endDateMatch[0]) : null;
const expired = /\bexpired\b/i.test(coverageEndText || '') || /coverage expired/i.test(coverageType || '');
return {
purchaseDateText: purchaseMatch ? purchaseMatch[1] : null,
purchaseDate: purchaseMatch ? normalize(purchaseMatch[1].replace(/^Purchased\s+/i, '')) : null,
coverageType,
coverageStatus: coverageType ? (expired ? 'expired' : 'active') : null,
coverageEndText,
coverageEndDate
};
})()Possible Friction Points
- The direct checker URL is
https://checkcoverage.apple.com/coverage?locale={locale}; coverage results cannot be safely constructed from a serial number in a URL. - The serial field is
input#serial-number-input, the CAPTCHA-answer field isinput#captcha-input, and the refresh control isbutton#captcha-refresh-btn. - CAPTCHA completion is mandatory. A refreshed image invalidates every prior answer; never reuse an answer after clicking New Code.
- The solver may not populate the CAPTCHA field or trigger the form's input handling automatically. Verify that the current answer is present and that the submit control is enabled before submitting.
- Apple may reject a solved CAPTCHA. Detect the resulting validation error, refresh the code, and retry rather than interpreting the page as a coverage result.
- Result wording varies by device, locale, and status. Preserve Apple's original purchase and expiration text separately from normalized ISO dates; do not infer coverage dates from the purchase date.
- The extractor intentionally reads rendered text rather than card-specific markup, since result-card layout can vary. It returns
nullwhen Apple does not display a requested field.