/ โ† AI Agent Compatibility Fixes / Agent Contact
In this guide
  1. Common ways contact details get hidden
  2. What agent-readable contact details look like
  3. Structured data that matches the page
  4. The fix, step by step
  5. Dealing with spam once your details are visible
  6. Platform notes
  7. Keeping details correct
  8. Questions and answers

Common ways contact details get hidden

Few site owners hide their details on purpose. It usually happens through design choices or anti-spam settings that seemed harmless at the time.

Where it hidesWhy it happensWhat an agent gets
Phone number in a header image or bannerThe designer wanted a particular fontAn image with, at best, alt text that may be out of date
Email protected by the CDNCloudflare Email Address Obfuscation rewrites addresses and decodes them with JavaScriptA placeholder such as [email protected] and a link to /cdn-cgi/l/email-protection
Email assembled by scriptOld anti-spam trick splitting the address into partsNothing, or broken fragments
Address only in a map embedThe map looked tidier than a text addressAn iframe from another domain it may not open
Opening hours in a graphic or PDFEasy to update in a design toolNo hours, or hours that it cannot read reliably
Contact only through a chat widgetWanting every enquiry in one inboxA widget that loads late and may need a person to type
Contact page with only a formAvoiding spam calls and emailsNo direct route for a customer who wanted to phone

Fetch-based agents, which read the HTML without running scripts, are hit hardest by the script-based hiding. Browser-based agents can often run the script, but they still cannot read a phone number that exists only as pixels in an image, and they may not be able to reach inside a map from another domain.

What agent-readable contact details look like

The target is simple: every detail a customer might ask for is written as text in the HTML your server sends, in a predictable place, with links that do the obvious thing. A footer block like this covers most small businesses:

<footer>
  <h2>Contact Hollybank Garden Rooms</h2>
  <address>
    Unit 4, Mill Lane Trading Estate<br>
    Chesterfield<br>
    S41 0AA<br>
    Phone: <a href="tel:+441246000000">01246 000000</a><br>
    Email: <a href="mailto:enquiries@example.co.uk">enquiries@example.co.uk</a>
  </address>
  <h3>Opening hours</h3>
  <ul>
    <li>Monday to Friday: 8am to 5:30pm</li>
    <li>Saturday: 9am to 1pm</li>
    <li>Sunday and bank holidays: closed</li>
  </ul>
  <p><a href="/contact">Contact page and enquiry form</a></p>
</footer>

A few points in that example are easy to get wrong:

The business name, the numbers and the address in this example are invented. Use your own, and keep them identical everywhere they appear.

Structured data that matches the page

Structured data gives agents the same details in a form they do not have to interpret. Use the most specific LocalBusiness subtype that fits, such as HomeAndConstructionBusiness, Dentist or Restaurant. Every value in the markup must also appear on the page, and they must agree.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "HomeAndConstructionBusiness",
  "@id": "https://www.example.co.uk/#business",
  "name": "Hollybank Garden Rooms",
  "url": "https://www.example.co.uk/",
  "telephone": "+441246000000",
  "email": "enquiries@example.co.uk",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Unit 4, Mill Lane Trading Estate",
    "addressLocality": "Chesterfield",
    "postalCode": "S41 0AA",
    "addressCountry": "GB"
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "17:30"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday",
      "opens": "09:00",
      "closes": "13:00"
    }
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "contactType": "customer service",
    "telephone": "+441246000000",
    "email": "enquiries@example.co.uk",
    "areaServed": "GB",
    "availableLanguage": "en"
  }
}
</script>

Days not listed in openingHoursSpecification are read as closed, which is why Sunday is missing. For holiday closures, add a separate specification with validFrom and validThrough dates covering the closure, and update the text on the page at the same time.

๐Ÿ’ก Keep your Google Business Profile hours in step with the website. Agents and search features compare sources, and different hours in two places give them a reason to doubt both.

The fix, step by step

Step 1

List where your contact details appear

Make a simple list of every place the phone number, email address, postal address and opening hours appear: the header, footer, contact page, individual service or branch pages, the Google Business Profile and any PDF menus or price lists. Note which version of each detail is shown in each place. Out-of-date numbers and old hours surviving on forgotten pages are common, and an agent may find the wrong one first. Decide on one correct set of details before changing anything.

Step 2

Check what the raw HTML contains

Run the AI Agent Compatibility audit on your home page and contact page, then open the page source with view-source or fetch it with curl -s and search it for your phone number and email address. If the number is missing, it is in an image or added by script. If you see [email protected] or /cdn-cgi/l/email-protection, your CDN is rewriting email addresses. Record what is missing on each page so you can check it again afterwards.

Step 3

Replace images and scripts with real text

Replace any phone number or hours that exist only in an image with real text, styled with CSS if the font matters. Remove scripts that assemble email addresses. If Cloudflare Email Address Obfuscation is on, either switch it off in the Scrape Shield settings or wrap the public contact address in <!--email_off--> and <!--/email_off--> comments so that address is left alone. Put the full postal address as text next to any map embed rather than relying on the map.

Step 4

Make phone and email into proper links

Wrap each phone number in a tel: link written in international format, such as tel:+441246000000, and each email address in a mailto: link whose visible text is the address itself. Avoid click-to-reveal buttons that hide part of the number until pressed. If you publish several numbers, label each one in text, such as sales, repairs or out of hours, so an agent can pick the right one for the task it was given.

Step 5

Publish opening hours as text and markup

Write your opening hours as a short list in plain words on the contact page and in the footer, including the days you are closed and how bank holidays are handled. Remove hours that exist only in images, PDFs or third-party widgets. When hours change for a holiday or a season, update the page, the structured data and your Google Business Profile on the same day, and take temporary notices down once the dates have passed.

Step 6

Add matching LocalBusiness structured data

Add a JSON-LD block using the most specific LocalBusiness type that fits, with telephone, email, a full PostalAddress and openingHoursSpecification, and a ContactPoint if you have separate departments. Make every value identical to the visible text. Test it with the Schema Markup Validator, then rerun the audit and fetch the page again with curl to confirm the details are now in the HTML the server sends.

Dealing with spam once your details are visible

The usual reason for hiding an email address is fear of spam. It is a fair concern, but hiding the address from everyone is a heavy price, and modern spam filtering does most of the work anyway. Some better options:

For phone spam, publishing a number does not make much difference to nuisance calls, which mostly come from random dialling. A published number that appears in structured data and your Business Profile does, however, make it easier for people to check that a call claiming to be from you is genuine.

Platform notes

WordPress

Contact details are often set in the theme customiser, a page builder header template or a "top bar" plugin. Check that these output text rather than an image, and look for anti-spam plugins that encode email addresses with script. SEO plugins such as Yoast and Rank Math can output organisation or local business markup; make sure only one plugin produces it, and that its phone and address match the footer.

Shopify

Many themes place contact details in a footer text block, which is fine. Problems come from announcement bar images and from contact pages that use a form app with no visible details. Add the details as text in a rich text section on the contact page, and check whether your theme or an app already outputs structured data before adding your own.

Multi-location businesses

Give each branch its own page with its own address, phone number and hours, and its own LocalBusiness markup with a distinct @id. A single contact page listing ten branches in one table is hard for an agent to connect to a question like "is the Derby branch open on Sunday?".

Keeping details correct

Questions and answers

1. Why can an AI assistant not find my phone number?

Usually because the number is not in the page as text. It may be part of a header image, added by a script after the page loads, or shown only after clicking a reveal button. Fetch-based agents read the HTML your server sends and see none of those. Check with view-source or curl: if you cannot find the number in the raw HTML, add it as plain text inside a tel link, then check the source again.

2. Does Cloudflare email obfuscation stop agents reading my email address?

It can. Cloudflare's Email Address Obfuscation rewrites email addresses in the page and uses JavaScript to decode them in the browser. A tool that reads the HTML without running scripts sees a placeholder and a link to an email protection page instead of your address. You can switch the feature off for the zone, or wrap your public contact address in email_off comments so Cloudflare leaves that one address untouched. Then check the page source again to confirm the real address now appears.

3. Should I put my email address on the site if I get lots of spam?

Usually yes, using a dedicated role address such as enquiries@ that you filter hard. Modern email services catch most bulk spam without the address needing to be hidden, and hiding it stops customers and their agents from contacting you directly. If most spam comes through your form rather than your inbox, protect the form with a hidden honeypot field and rate limits instead of hiding the address. Review the filter every few months so genuine enquiries are not caught by mistake.

4. What format should a UK phone number be in a tel link?

Use the international format with a plus sign, the country code 44 and the number without its leading zero, and no spaces, for example tel:+441246000000. The visible text can stay in the familiar local style, such as 01246 000000. This works for callers inside and outside the UK, on mobiles and on desktop calling apps, and it matches the telephone value you should use in your structured data. Use the same number everywhere so the page, the markup and your profile agree.

5. How do I show holiday opening hours to agents?

Update the visible hours on your contact page and footer, for example a short notice listing the dates and times, and add a separate OpeningHoursSpecification in your structured data with validFrom and validThrough dates covering the change. Update your Google Business Profile special hours on the same day. Remove the notice once the dates pass, because agents that find old holiday hours may tell customers you are closed. A reminder in your calendar makes this easy to remember.

6. Is a contact form enough on its own?

A form is useful, but many tasks people give agents are simpler: find the number, check whether you are open, send a quick email. If the only route is a form, the agent must fill it in, which depends on the form being well labelled and not blocked by a puzzle. Publish at least one phone number or email address as text alongside the form so there is always a direct route.

7. Do I need both visible text and structured data?

Yes. The visible text is what people read and what browser-based agents see on the screen. Structured data gives fetch-based tools and search features the same facts in a predictable format. The two should always match, since conflicting details make agents and search engines less confident about either version. Treat the markup as a copy of what the page already says, never as a place to add details the page does not show.

Check whether agents can find how to reach you

The AI Agent Compatibility audit tests your page for bot blocks, content hidden behind JavaScript, unlabelled forms and controls, navigation agents cannot follow and missing structured data, and links each finding to the guide that fixes it.

Open AI Agent Compatibility Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All AI Agent Compatibility Fixes  ·  Fixing Structured Data for Agents  ·  Fixing JavaScript-Only Content  ·  Fixing Forms Agents Cannot Fill  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.