Why does a JSON-LD date, URL or price need a particular format?
‘<field>’ should be a URL / an ISO 8601 date string / a positive number page
The issue
A JSON-LD value in the wrong format is there in the markup and still can’t be used as what it claims to be. A datePublished of “March 2, 2026” isn’t a date a parser can rely on, a relative image path doesn’t say which site it belongs to, and a price of “$19.99” isn’t a number. The property looks filled, so the gap is easy to miss.
The cause is usually a template that prints the value the way the page displays it: a formatted date, a path relative to the site, a price with its currency symbol.
Scope
Each field with a known format is checked on each object where it appears, including in nested objects of a type probeo knows. For URL fields holding a list, each value is checked; a value that is itself an object, such as an ImageObject, is left to its own checks. Each is a warning, so the block still counts as valid.
How to check you have it
- In probeo: the page reports one of three warnings, naming the field:
'url' should be a URL, forurl,image,logo,thumbnailUrl,contentUrl,embedUrlandscreenshot.'datePublished' should be an ISO 8601 date string (e.g. "2024-01-15"), fordatePublished,dateModified,startDate,endDate,uploadDate,datePostedandvalidThrough.'price' should be a positive number, forprice,ratingValue,reviewCountandratingCount.
- By hand: view the page source, find each
<script type="application/ld+json">block, and read those fields’ values against the formats below. - With a tool: the Schema Markup Validator shows each value as it was read, which makes a formatted date or a relative path easy to spot.
The fix
Write each value in its machine-readable format, separately from how the page displays it.
The page can still show “March 2, 2026” and “$19.99” to readers. The JSON-LD takes the same facts in the forms below, usually from the raw field the template formats for display.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Registered agent service",
"image": "https://example.com/images/registered-agent.png",
"offers": {
"@type": "Offer",
"price": "125.00",
"priceCurrency": "USD",
"priceValidUntil": "2026-12-31"
}
}Done when: every date, URL and number field is in the format below, and the check above comes back clean.
Do not
- Do not copy the displayed, formatted value into the markup.
- Do not put the currency symbol in
price; it belongs inpriceCurrency. - Do not use a relative path for an image or URL field.
The formats probeo accepts
| Kind | Accepted | Reported |
|---|---|---|
| URL | starts with https://, http:// or // |
/images/a.jpg, images/a.jpg, example.com/a.jpg |
| Date | 2026-03-02, or with a time: 2026-03-02T09:30:00Z, 2026-03-02T09:30:00-05:00 |
March 2, 2026, 03/02/2026, 2026-03 |
| Number | a number, or a string that reads as one: 125, "125.00" |
"$125", "free", a negative number |
FAQ
Why is a relative URL a problem when the browser understands it?
The browser resolves it against the page’s address. The JSON-LD is read as data, often apart from the page, and a path on its own doesn’t say which site it belongs to.
Does the date need a time?
No. A date alone, such as 2026-03-02, is accepted. A time can follow after a T, with a time zone.
Is a price of zero accepted?
Yes. Probeo reports a value that isn’t a number or is below zero. A free offer can carry a price of 0 with its currency.
Does probeo check duration or totalTime?
No. Probeo checks the date, URL and number fields listed above. Durations such as PT30M aren’t format-checked.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.