SearchOps

SearchOps + n8n

Own your data: a warehouse of every client's profile results, Map Pack history and AI visibility, plus a weekly brief per account written for your team.

WebhooksREST API

n8n is for agencies that want full control. Self-host it for free, pull SearchOps data into your own Postgres or BigQuery, and give each account manager a short weekly brief per client, written by the AI model you choose from numbers SearchOps supplies. One run counts as one execution however many steps it has, so heavy workflows stay cheap.

Your own local SEO warehouse

Profile performance, Map Pack history and AI visibility for every location, in tables you own and can join to sales data.

A brief per client, every Monday

An AI node turns each client's numbers into a short internal note: what moved, what we did, what to do next.

Verified events only

A Code node checks every webhook signature before anything runs.

Cheap at scale

Self-hosted n8n is free; n8n Cloud counts one execution per run, not per step.

Recipes

What agencies build with n8n

Weekly warehouse load

GET /profile/performance, /grid-history, /ai-visibility

Agencies with their own BI or a data person

Schedule Trigger
Weekly
SearchOps API
Results, grids, AI
Insert rows
Postgres or BigQuery
  1. 1Schedule Trigger, weekly.
  2. 2HTTP Request to /api/v1/locations with Bearer Auth, paginating with limit and offset.
  3. 3Per location: /profile/performance?months=1, /keywords/{keywordId}/grid-history and /ai-visibility?engine=chatgpt.
  4. 4Insert into Postgres or BigQuery, keyed on location and week, then chart it in your BI tool.

Monday account brief, written per client

GET /week, /geo-grid/insights

Account managers with ten or more clients

Schedule + loop
Every client
SearchOps API
Week + grid insights
Brief per client
Internal page
  1. 1Schedule Trigger on Monday morning, then loop over each client's locations.
  2. 2HTTP: /locations/{id}/week (results and tasks done) and /locations/{id}/geo-grid/insights (why rivals win).
  3. 3AI node with your own model: write five lines (what moved, what we did, what to do next), from the numbers only.
  4. 4Create a Notion page or Slack message for the account manager. Internal only: a person decides what reaches the client.

Verified event router

all events

Teams that want signatures checked before acting

Any event
Signed webhook
Webhook + Code
Verify signature
Switch on type
Moves, changes, tasks
  1. 1Webhook node, POST, Respond Immediately, Raw Body on.
  2. 2Code node with the verification snippet below.
  3. 3Switch on type: geo_grid.moved to the account channel, profile.changed to #ops, task.completed to the client's work log.

Setup

Connect n8n, step by step

  1. 1

    Add a Webhook node or a Schedule Trigger

    For events, add a Webhook node: POST, Respond Immediately, Raw Body on if you'll verify signatures, and copy the Production URL (the Test URL only works while listening). For reports, start with a Schedule Trigger.

  2. 2

    Add the webhook in SearchOps

    In SearchOps, open Developers, then Webhooks, and choose Add webhook. Paste the URL from the n8n Webhook node (the Production URL), tick the events you want and, for a client-specific workflow, pick that client's locations. Save, and copy the signing secret somewhere safe: it is shown once.

  3. 3

    Publish the workflow

    The Production URL only receives events once the workflow is published (active). Publish it, then send the test.

  4. 4

    Send a test event

    Back in SearchOps, press Send test on the endpoint. The test event has the same envelope as real events but a short sample body. To map review or scan fields, wait for a real event of that type or replay one from Deliveries, then use that as your sample.

  5. 5

    Verify the signature

    Add a Code node set to Run Once for Each Item with the snippet below. n8n's built-in Crypto node can't decode the whsec_ secret, so use code. On self-hosted n8n, allow the crypto module with NODE_FUNCTION_ALLOW_BUILTIN=crypto.

    Code node
    // Code node, "Run Once for Each Item", after a Webhook node with Raw Body on.
    const crypto = require('crypto');
    const secret = 'whsec_...'; // from SearchOps, ideally from a credential or variable
    const h = $json.headers;
    const id = h['webhook-id'], ts = h['webhook-timestamp'], sigs = h['webhook-signature'] || '';
    const bin = $input.item.binary && $input.item.binary.data;
    const raw = bin ? Buffer.from(bin.data, 'base64').toString('utf8') : JSON.stringify($json.body);
    if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) throw new Error('stale webhook');
    const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
    const expected = crypto.createHmac('sha256', key).update(`${id}.${ts}.${raw}`).digest();
    const ok = sigs.split(' ').some((entry) => {
      const [version, sig] = entry.split(',');
      if (version !== 'v1' || !sig) return false;
      const given = Buffer.from(sig, 'base64');
      return given.length === expected.length && crypto.timingSafeEqual(given, expected);
    });
    if (!ok) throw new Error('bad signature');
    return { json: JSON.parse(raw) };
  6. 6

    Call the API

    HTTP Request node with the Bearer Auth credential and your SearchOps API key. Base URL https://searchops.co/api/v1; 120 requests a minute per key, so add a short Wait in big loops.

Field reference

The fields you'll map most

From the SearchOps webhook payload. Every event also carries type, id, created_at and the location's id and business name.

FieldUse it for
typeRoute by event: geo_grid.moved, scan.completed, profile.changed, task.created, task.planned, task.completed, review.created
location.business_nameWhich client or branch it is about
data.directionup or down: a grid move beyond normal re-run swing (geo_grid.moved)
data.points_gained / data.points_lostHow many grid points entered or left the top 3 (geo_grid.moved)
data.keyword / data.engine_labelThe keyword and engine: Google Maps, Google Search or AI Mode
data.share / data.share_low / data.share_highShare of answered grid points in the top 3 (or named, for AI Mode), with its likely range
data.keyword_url / data.scan_urlOpen the keyword's grid history or the scan in SearchOps
data.field_label / data.before / data.afterWhat changed on the Business Profile (profile.changed)
data.changed_bygoogle or someone_else: who changed the profile
data.kind / data.severityverification or duplicate, and how serious the change is
data.title / data.completed_at / data.task_urlA task and when it was done: your proof of work (task.created, task.planned, task.completed)

What you need

  • SearchOps Pro, Agency or Enterprise. Webhooks and the API are included; an owner or admin sets them up.
  • n8n: self-hosted Community Edition is free. On n8n Cloud, Starter includes 2,500 executions a month; one execution is one run, whatever its length.
  • The AI brief uses your own model key in n8n; SearchOps supplies the numbers.

Steps checked against the vendor's own documentation on 12 October 2026. Tools change their menus often; if a step no longer matches, the help article has the latest.

FAQ

SearchOps and n8n

What can I put in a warehouse?

Anything the 29 read-only endpoints return: Business Profile performance by day, week or month for up to 18 months, search terms, Map Pack grid history per keyword, AI Mode and AI Overview answers, ChatGPT and Gemini visibility, competitors, Search Console and Google Analytics.

Test URL or Production URL?

Paste the Production URL into SearchOps and publish the workflow. The Test URL only works while the editor is listening for a test event.

Why not the Crypto node for signatures?

Our secret is base64 after the whsec_ prefix, and the Crypto node takes the secret as plain text, so its HMAC won't match. The Code node snippet decodes it correctly.

Start tracking your real rankings today

See where you actually rank on Google Maps, not where Google tells you. Pick the plan that fits and start tracking from day one.