Search engines
Connect your store to Google, Bing and IndexNow through Formahand or your own account, what is read every day, who can see it, and the agent tools.
Written 2026-09-28. How your store gets connected to Google, Bing and IndexNow, what Formahand reads back, who can see it, and how an agent helps.
1. What it does
Formahand proves to a search engine that your store's address is yours and sends it your sitemap, so the engine knows every page. Every day it then reads what the engine reports about your store (searches, pages, clicks, impressions, position) and shows it under Analytics. With IndexNow turned on, it also tells the engines that take part when a page changes.
The dashboard groups metadata, connections and recommendations under Online Store → SEO. Use Settings, Connections and Insights to move between them. Existing #seo, #search-engines and #seo-insights links, including their detail paths, still work and select the matching section.
2. Let Formahand manage
Choose Let Formahand manage for Google or Bing. With your approval, Formahand verifies your store's address, manages its Search Console or Webmaster Tools property, submits the sitemap and reads search performance using its own account. No search engine account sign-in or manual verification code is needed.
Managed setup is the only option for new connections. The former manual-account setup is retired. Existing connections are not automatically disconnected or migrated.
Only your store's main address is connected. If you change the main address, Formahand connects the new one the same way and keeps the data read so far.
Free address or your own domain. What happens through Formahand depends on the address:
| Engine | <name>.store-on-formahand.app | Your own domain |
|---|---|---|
| Your store serves a Google verification file and gets its own URL-prefix property. Access is isolated to your store. | Google gives a file named google<code>.html. Your store serves it, Google checks it, and https://<your domain>/ is added to Formahand's Google account. | |
| Bing | Your store serves /BingSiteAuth.xml, Bing checks it, and the address is added to Formahand's Bing account. | The same. |
| IndexNow | A key file /<key>.txt on every address of the store. | The same. |
A test store (sandbox) is never connected to a search engine.
3. Connecting
Open Online Store → SEO → Connections in the dashboard (address #search-engines). There is one tile per engine: Google, Bing and IndexNow. Only a signed-in owner or admin can connect, disconnect or approve. An agent can only ask (section 9).
- Open the engine's tile and click Let Formahand manage for Google or Bing, or Turn on for IndexNow.
- Read the popup and confirm. For Google through Formahand it says, word for word (Bing reads the same with Bing): - Formahand will prove to Google that this store's address is yours. When a proof is needed, the store serves a small file. - Formahand will add the store to its own Google account and send Google your sitemap. - Formahand will read the store's search results every day (searches, pages, country, device, clicks, impressions and position) and keep them for 16 months. - Formahand staff can read this data, for this store and across stores, to provide SEO help. - You can disconnect at any time and choose to keep or delete the data.
- The popup shows the steps: Proving the address, Adding the site, Sending the sitemap, Done. It checks again every few seconds. After two minutes it says "This is taking longer than usual. We will keep trying. You can close this." You can close it; Check again on the tile carries on.
- When it is done the tile says Connected. The engine's page shows Last read, such as Read today or Read 2 days ago.
Formahand records who confirmed, when, and the exact text shown. If the text changes while the popup is open, you are asked to read it again.
For IndexNow the popup says:
- Formahand will tell participating search engines when a page of the store changes.
- Formahand will serve a small key file from the store so they can trust these notices.
- No data is read.
- You can turn this off at any time.
4. Existing connections from the previous setup
Existing manual-account connections keep their data and consent. To move one to managed setup, disconnect it first, choose whether to keep its imported data, then choose Let Formahand manage. This records a new approval; Formahand does not switch accounts silently.
Google Search Console access
For every managed Google URL-prefix property, Formahand grants and maintains owner access for support.formahand@gmail.com. Existing managed properties are backfilled automatically. A failed grant is retried without marking the search connection as failed.
In SEO → Connections → Google, the Google Search Console access card lists current owners and opens the exact property in Google's console. A store owner or admin can add a Google account email after confirming that it receives owner access, including reports, property settings and user management. This is not a read-only permission. The supported Site Verification API grants delegated ownership.
Only emails added through Formahand can be removed here, after confirmation. Existing unrelated owners and Formahand's service and support accounts are protected. Google can refuse removal when the email independently verified the property; resolve that verification in Google. Requests with an uncertain response remain tracked and can be refreshed or retried.
A merchant is never granted access to Formahand's shared parent-domain property. New hosted stores get their own URL-prefix property and verification file. Older shared-domain connections prepare an isolated URL-prefix property before access can be shared. Search history already read stays with the store.
Google owner mutations are serialized per connection and audited with the acting user. Requests require a signed-in owner/admin, the selected Live store, a currently linked hostname, same-origin mutation and explicit permission confirmation. No merchant access-management action is exposed to agent tokens.
Automatic Formahand support access
For every consenting store using Formahand-managed Google SEO, Formahand automatically grants support.formahand@gmail.com owner access and registers the store’s isolated Google property in the support account. This is independent of which Google account the merchant connects. Merchant permissions and Formahand’s reports continue using their existing connections.
Formahand staff enable the platform-wide support connection once at /operator/google-search. Sign in with the verified support account or a platform operator, choose Authorize support for all managed stores, and approve Google access using exactly support.formahand@gmail.com. The connection is encrypted and renewable, separate from personal merchant credentials. Existing managed properties are registered in batches; new connections trigger registration automatically. Google must confirm the exact property and owner permission before the dashboard shows support registration as complete.
If Google revokes or expires support authorization, staff reconnect it once on the same page. Individual merchants never need to connect the support Google account. Test stores, manual-account connections, inactive hostnames and stores without managed consent are excluded.
Your connected Google account
Your Google account is shared across Formahand features for the signed-in person. It is separate from the service account that manages stores. Connect once to save a secure, renewable connection. Each feature checks its required Google permissions. When a new permission is needed, choose Approve additional permission; existing grants are kept. Google can require reconnection if you revoke access or the authorization expires.
The panel shows the connected email and tracks Google authorization separately from this store’s property registration. Connecting from the store’s Google page grants the selected email owner access and automatically adds the store to that Google account’s Search Console. Success is shown only after Google confirms the exact property and owner permission. If Google is connected but registration is unfinished, choose Finish Search Console setup; it reuses the existing Google connection. Use another Google account replaces the personal connection after confirmation and Google approval. Disconnect from Formahand removes the saved personal credentials across features. It does not disconnect Formahand-managed store properties or sign you out of Formahand.
Google sign-in alone does not grant permissions for Search Console, Merchant Center or Sheets. Merchant Center permissions will be requested when that integration needs them; connecting Google does not itself enable product synchronization.
Add a granted property to a person's Search Console account
Google site ownership and the property's registration in a person's Search Console account are separate. After an email is granted ownership, Add to my Google Search Console starts a one-time Google authorization flow. Copy setup link lets the store owner or their agent hand the same flow to the recipient. Links are email-specific and expire after seven days. The recipient needs no Formahand login; they must choose the exact invited Google account.
Formahand first reuses a matching connected Google account when it has the required permission. Otherwise, after approval, Formahand verifies that the Google account's verified email matches the invitation, rechecks the current grant and active store hostname, and calls Search Console sites.add using that person's token. It checks sites.get for the exact property and siteOwner before showing success. Formahand continues managing the connection through its service account. Signed-in users save an encrypted, renewable Google connection that other Formahand features can reuse. Anonymous recipients use a one-time token that is not saved. The permission Google asks for covers Search Console properties; this flow uses it to register and confirm the invited property.
Deployment configuration (platform operator, once):
- In the OAuth web client matching
GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET, registerhttps://formahand.com/api/search-engines/google-register/callbackas an authorized redirect URI. - Configure
https://www.googleapis.com/auth/webmasterson the OAuth consent screen and complete Google's applicable production verification. The flow also requestsopenid emailto validate the intended recipient. - Set
GOOGLE_SEARCH_REGISTRATION_ENABLED=enabledonly after that configuration is ready. Until then, registration buttons and setup links are hidden; existing managed connections and email grants keep working. - Apply the registration database migration. One-use attempts last ten minutes, use PKCE S256 and a Secure/HttpOnly/SameSite=Lax browser cookie, and are consumed atomically on callback. Starting an attempt requires a same-origin POST. An invitation never grants new ownership, and revoked grants fail on callback.
The Google-account authorization step cannot be replaced with an unauthenticated URL: sites.add operates on the authenticated account. Formahand's service-account token can add a property only to that service account's list.
5. IndexNow
IndexNow is one notice that every participating engine shares. Bing and Yandex take part, and other participating engines too. Google does not take IndexNow: Google learns your pages from the sitemap Formahand sent when you connected Google, and from its own crawling.
What is sent: the full addresses of pages on your store's main address, nothing else.
- When a product, collection, page or post is created, changed or removed, its address and the list pages it appears on, such as the home page,
/collections/allor/blog. A renamed page sends the old address and the new one. - When a page is unpublished or deleted, its address, so the engine sees it is gone.
- When you publish the storefront, the home page,
/collections/all,/blogand your sitemap's pages. - When you first turn IndexNow on, or change the main address, your sitemap's pages once (2,000 at most).
When: changes are collected and sent every ten minutes or so, a little later during a burst of edits. A page that changes several times before the next send is sent once.
Only while the store is open to the public and not hidden from search. A store behind a password or a coming-soon page sends nothing. When you hide the whole store from search, the home page is sent once so engines look again and drop it. The test store never sends anything.
6. Search performance
See it in Analytics, card Search performance (Analytics), or with get_search_performance.
| Number | Means |
|---|---|
| Clicks | Times someone clicked through to your store from the engine's results |
| Impressions | Times your store was shown in the results |
| Position | Average position in the results, weighted by impressions (1 is the top) |
| CTR | Clicks divided by impressions |
- The data is about two days behind. Formahand reads the last three days again each day, because the engine can still change them.
- The first read goes back 90 days. For older history, upload your engine's export (Analytics).
- Google leaves out rare searches, so the rows of a report can add up to less than its totals.
- Formahand reads Bing by search and day only: Bing rows have no page, country or device and show as All pages or Not split.
- Rows read from an engine are kept for 16 months, then removed.
7. Who can read the data
- Your store's team, in Analytics, and your agents with a token that reads orders.
- Formahand staff, for your store and across stores, to provide SEO help. This is what the consent says, and it is why you are asked before anything is read.
Staff can read a store's rows only if an owner or admin gave consent for that engine. That includes data you chose to keep when you disconnected.
8. Disconnecting
Open the engine's tile and click Disconnect (Turn off for IndexNow). The popup offers Disconnect and keep data or Disconnect and delete data.
- What stops: the daily read, and the proof your store served for that engine. Through Formahand, the site is removed from Formahand's engine account (a free address under Formahand's Google property has nothing to remove).
- Delete data removes the rows read from that engine, here and in Formahand's copy. Rows you uploaded yourself stay.
- Keep data keeps them, still readable by your team and by Formahand staff as in section 7.
- Turning off IndexNow removes the key file and anything waiting to be sent.
- What may remain at the engine: your pages stay in its index until it drops them on its own. With your own account, your property stays yours: remove Formahand's address from its users there if you added it. If removal fails, the tile says "Disconnected. The site may still be listed in Formahand's Google account."
9. For agents
An agent can read the state and ask. Consent is a person's act: only a signed-in owner or admin connects, approves or disconnects, in the dashboard. No tool verifies, approves, saves your own code or disconnects. A token acts on one environment: connect_search_engine with a test token is refused with "Search engines connect to your live store."
| Tool | Scope | Does |
|---|---|---|
describe_search_engines | settings:read | State of each engine, pending requests, what to do next. Never returns a code or a key. |
connect_search_engine | settings:write | Creates a request the owner approves on the dashboard. |
get_search_performance | orders:read | Reads the numbers, grouped and filtered. |
import_search_performance | settings:write | Uploads rows from an export the owner made. |
States: not_connected, waiting_for_owner, checking, connected, needs_attention, disconnected.
describe_search_engines {}
→ { "mode": "live", "primaryHostname": "shop.example.com",
"engines": [
{ "engine": "google", "available": true, "state": "connected", "way": "formahand",
"hostname": "shop.example.com", "lastReadAt": "2026-09-28T06:10:00.000Z", "lastError": "", "readAccess": false },
{ "engine": "bing", "available": true, "state": "not_connected", "way": null,
"hostname": "shop.example.com", "lastReadAt": null, "lastError": "", "readAccess": false } ],
"requests": [], "ways": { "formahand": "…", "own": "…" }, "consent": "…",
"dashboard": "https://formahand.com/dashboard#search-engines",
"next": ["connect_search_engine { engine: \"bing\" } asks the owner to connect Bing."] }
connect_search_engine { "engine": "bing" }
→ { "request": { "id": "…", "engine": "bing", "hostname": "shop.example.com", "state": "waiting_for_owner" },
"approveAt": "https://formahand.com/dashboard#search-engines/bing",
"next": "Ask the owner to open that page and approve. Only a signed-in owner or admin can give consent." }
Asking again returns the same request. An engine already connected or being set up answers { connection: { engine, hostname, state }, message } instead.
get_search_performance { "from": "2026-09-01", "to": "2026-09-26", "groupBy": "query",
"engine": "google", "country": "usa", "device": "mobile", "limit": 5 }
→ { "period": { "from": "2026-09-01", "to": "2026-09-26", "days": 26 }, "groupBy": "query",
"rows": [{ "key": "oat granola", "clicks": 12, "impressions": 340, "ctr": 0.035, "position": 6.8 }],
"totals": { "clicks": 40, "impressions": 1900, "ctr": 0.021, "position": 11.4 },
"filters": { "engine": "google", "country": "usa", "device": "mobile" } }
groupBy is query, page, engine, country, device or day (a series in date order; the others rank by clicks). engine is google, bing or other; country the engine's three-letter code; device desktop, mobile or tablet; limit 1 to 250. filters appears only when one was given. The numbers above are an example.
import_search_performance { "source": "search-console", "rows": [
{ "day": "2026-05-01", "query": "oat granola", "page": "https://shop.example.com/products/oat-granola",
"clicks": 3, "impressions": 120, "position": 8.2, "engine": "google", "country": "usa", "device": "mobile" } ] }
→ { "imported": { "rows": 1, "days": 1, "from": "2026-05-01", "to": "2026-05-01", "source": "search-console" } }
At most 5,000 rows a call. A row replaces the one stored for the same day, engine, query, page, country and device. The source formahand-sync is kept for the daily read and refused.
10. Troubleshooting
| Message | Means | Do |
|---|---|---|
| Search engines connect to your live store. | You are in the test store. | Switch to Live. |
| Not set up yet. | Formahand cannot connect this engine yet. | Try later. |
| The store has no live address yet. | The store has no main address. | Finish setting up the store first. |
| The text changed. Read it again and confirm. | The consent text changed while the popup was open. | Open it again and confirm. |
| Sign in to connect a search engine. | You are not signed in, or an API token was used. | Sign in to the dashboard. |
| Only store owners and admins can do this. | Your role cannot connect engines. | Ask an owner or admin. |
| Start this action from Formahand. | The request did not come from the dashboard. | Use the dashboard. |
| Too many requests: 20 a minute. Retry in *n*s. | More than 20 actions a minute on this store. | Wait and retry. |
| Check the request. | The request was not understood. | Reload the page and retry. |
| Could not load search engines. | The screen could not load. | Reload the page. |
| That connection is not on this store. | The page is out of date. | Reload the page. |
| This engine is connected with your own account. Disconnect it first. | You chose your own account earlier. | Disconnect it, then choose Let Formahand manage. |
| This engine is connected through Formahand. Disconnect it first. | Formahand already connected it. | Existing connections can be kept or disconnected. |
| Approve this request first. | An agent's request is still waiting. | Click Approve or Decline. |
| That is not a pending request. | Someone already approved or declined it. | Reload the page. |
| Connect again to continue. | The connection was disconnected or failed. | Click Try managed setup again. |
| That connection does not use your own account. | Check access is only for your own account. | Nothing. |
| IndexNow has no account of its own. Turn it on instead. | IndexNow has no own-account way. | Click Turn on. |
| Paste the code first. | The field is empty. | Paste the code. |
| That is too long to be a verification code. | More than 2,000 bytes. | Paste only the tag, file name or code. |
| Paste the meta tag, the file name or the code your search engine gave you. | What you pasted is not a form we accept. | See the table in section 4. |
| The meta content has characters a verification code never has. | The tag's content value is not a code. | Copy the tag again from the console. |
| A Google file must be named google\<token\>.html. | The file name is not Google's. | Copy the file name again. |
| A Bing file must contain only the users and user code Bing gave you. | The pasted file is not Bing's. | Paste the code alone. |
| The search engine gave a code we cannot serve. | The engine's proof had an unexpected form. | Try again later. |
| The store could not be reached. / The store is not ready yet. | The proof could not be put on your store yet. | Check again in a minute. |
| The search engine could not find the proof on the site yet. | The engine checked before it could see the proof. | Check again in a minute. |
| The search engine is limiting requests. We will try again later. | The engine asked us to slow down. | Nothing; it retries. |
| The search engine could not be reached. We will try again later. | The engine did not answer. | Nothing; it retries. |
| The search engine no longer gives us access to this site. | Access was removed at the engine. | Try managed setup again. |
| The search engine does not know this site. | The engine has no such property. | Connect again. |
| The search engine did not accept the request. | The engine refused. | Try again; if it repeats, contact support. |
| No room for more sites right now. | Formahand's engine account is full for now. | Try later. |
| That search engine account is not available. | Formahand's engine account could not be used. | Try later. |
| This is taking longer than usual. We will keep trying. You can close this. | Checking takes more than two minutes. | Close the popup; Check again later. |
| Disconnected. The site may still be listed in Formahand's Google account. | Disconnected, but the engine did not confirm the removal. | Nothing; data reading has stopped. |
| Formahand can no longer read this site. Connect it again. | Formahand lost access at the engine. | Click Try managed setup again. |
| Formahand's access to your property was removed. Add it again, then check access. | Formahand's address was removed from your property. | Add it again, click Check access. |
| Sync stopped after repeated errors. Connect it again. | Reading failed many times in a row. | Click Try managed setup again. |
| Your store could not be updated. We will try again. | The numbers were read but not yet saved to your store. | Nothing; it retries. |
| Something went wrong. We will try again. | A read failed. | Nothing; it retries. |
| Paused for now. It continues on the next run. | A long read is split over several runs. | Nothing. |
| More rows than one run can read. | The engine had more rows for a day than one read takes. | Nothing; the rows read are kept, the rest of that day is missing. |
| The run stopped before it finished. | A read was cut off. | Nothing; the next one covers it. |
| The key file is not reachable on the store yet. | IndexNow could not see your key file. | Nothing; it is put back and retried. |
| Something went wrong. Try again. | An unexpected error. | Try again. |
| The date range is not valid. | from is after to, or a day is not YYYY-MM-DD. | Fix the dates. |
| formahand-sync is kept for the rows read from connected search engines. … | An agent's upload used the reserved source name. | Name your export's source, such as search-console. |
| This source is kept for rows Formahand reads itself. Leave source out, or use another name. | An upload used the reserved source name. | Leave the source out. |
| Sign in to read search performance. / Sign in to import search performance. | You are signed out. | Sign in. |