Skip to main content
Recipe Google Sheets Tender monitoring

How do you track public tenders in a Google Sheet automatically?

Peter Cools · Updated on · 4 min read · View as Markdown

Short answer

Create a Public Tenders signal in Rodz with your keywords, French departments or countries and market types, then paste your Google Sheet URL in the signal’s Integrations tab. Every matching BOAMP or TED notice adds a row: buyer, subject, notice link, market type, response deadline and the published contact. A tender costs 7 credits.

Key facts

  • A delivered tender costs 7 credits, plus 0.5 credit per email found when you turn on persona targeting and email finding.
  • Two official sources: BOAMP for France and TED for European notices (sources: boamp, ted).
  • Each notice is delivered once, within the signal’s daily limit.
  • Rodz identifies 400,000+ signals a month (July to September 2026 average).
Cost : 7 credits per tender Setup time : 10 min

Before you start

  • A Rodz account with credits (the test account includes 100).
  • A Google account with edit rights on the destination Google Sheet.
  • Your business keywords (for example "IT maintenance", "cleaning services"), and if needed your French departments, CPV codes and market types.

Steps

  1. Step 1. Connect Google Sheets to Rodz

    In the Rodz dashboard, open Integrations and click Google Sheets. A Google window opens: pick the Google account and allow access. This connection is made once, in the dashboard (OAuth); it cannot be made with an API key.

  2. Step 2. Create the Public Tenders signal

    In My Signals, click Activate Signal and pick the Public Tenders signal and set:

    • the sources: boamp (French notices) and/or ted (European notices);
    • the keywords searched in the tender subject (keywords) and excluded keywords (keywordsExclude);
    • French departments (departmentCodes, for example 44, 75) for BOAMP, countries (countryCodes) and CPV codes (cpvCodes) for TED;
    • the market types (marketTypes: Services, Fournitures, Travaux);
    • the minimum days before the deadline (minDaysUntilDeadline), to drop notices that close too soon to answer.

    Keywords match the subject as published, so use the notice’s language (French for BOAMP).

    Equivalent configuration (POST /api/v1/signals/public-tenders)

    {
      "name": "IT maintenance tenders, western France",
      "status": "draft",
      "dailyLeadLimit": 20,
      "config": {
        "sources": ["boamp"],
        "keywords": ["maintenance informatique", "infogérance"],
        "keywordsExclude": ["travaux"],
        "departmentCodes": ["44", "35", "49"],
        "marketTypes": ["Services"],
        "minDaysUntilDeadline": 10
      }
    }
  3. Step 3. Paste the Google Sheet URL in the signal

    Create an empty Google Sheet (or a dedicated tab), copy its URL, then in the signal’s Integrations tab switch on Google Sheets and paste the URL. Through the API, it is a PATCH on the signal with the googleSheets destination.

    Rodz writes the header row itself when the sheet is empty.

    Same setting through the API

    curl -X PATCH "https://api.rodz.io/api/v1/signals/$SIGNAL_ID" \
      -H "Authorization: Bearer $RODZ_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"destinations": {"googleSheets": {"sheetUrl": "https://docs.google.com/spreadsheets/d/YOUR_ID/edit"}}}'
  4. Step 4. Set the daily limit and activate

    In Basic Settings, set the Daily Lead Limit: it caps how many notices are delivered, so it caps spend. Set the signal to Active. Each new matching notice adds a row to the sheet.

  5. Step 5. Sort and share the sheet

    Add your own columns to the right of the Rodz columns (status, owner, bid / no bid): Rodz writes each value under the header of the same name and leaves columns it did not create alone. Sort on Response Deadline to see the notices that close first.

Example payload

What Rodz delivers for one tender (webhook format, also returned by `GET /api/v1/signals/{signal_id}/leads`, without persona targeting). The sheet receives the main columns.

{
  "signal": {
    "id": "d4f5a6b7-c8d9-4e0f-a1b2-c3d4e5f6a7b8",
    "name": "IT maintenance tenders, western France",
    "type": "public_tenders",
    "last_signal": "Public Tender",
    "last_signal_date": "2026-10-08",
    "job_offer_title": "Maintenance du parc informatique des services municipaux",
    "job_offer_url": "https://www.boamp.fr/avis/detail/26-000000",
    "matched_keywords": "maintenance informatique",
    "tender_description": "Maintenance préventive et curative du parc informatique, 3 lots.",
    "tender_deadline": "2026-11-06T12:00:00+00:00",
    "tender_published_date": "2026-10-07T02:00:00+00:00",
    "tender_cpv_code": "50320000",
    "tender_market_type": "services",
    "tender_nature": "cn-standard",
    "tender_submission_url": "https://tenders.example/file/123456",
    "tender_source": "boamp",
    "buyer_siren": "000000000",
    "buyer_city": "Nantes",
    "buyer_website": "https://city.example",
    "buyer_contact_email": "procurement@city.example",
    "buyer_contact_phone": "+33 2 00 00 00 00"
  },
  "company": {
    "name": "City of Example",
    "website": "https://city.example",
    "hq_country_code": "FR",
    "hq_city": "Nantes"
  }
}

Sheet columns ← Rodz fields

Google Sheets columnRodz field (payload)
Companycompany.name (the public buyer)
Tender Subjectsignal.job_offer_title (the notice subject)
Tender URLsignal.job_offer_url (link to the notice)
Market Typesignal.tender_market_type
Response Deadlinesignal.tender_deadline
Tender Descriptionsignal.tender_description
Published Datesignal.tender_published_date
CPV Codesignal.tender_cpv_code
Notice Sourcesignal.tender_source
Buyer SIREN, Buyer City, Buyer Websitesignal.buyer_siren, signal.buyer_city, signal.buyer_website
Buyer Contact Email, Buyer Contact Phonesignal.buyer_contact_email, signal.buyer_contact_phone
Signal Namesignal.name

Getting the keywords right

Keywords apply to the tender subject. A few simple rules:

  1. Start broad, then exclude: three or four trade phrases, then exclusions (keywordsExclude) for the false positives you see.
  2. Use minDaysUntilDeadline: a notice that closes in three days is rarely workable. Ten days is a common starting point.
  3. One signal per offer: if you bid on different kinds of contracts, create one signal and one tab per offer, so each team has its sheet.

Troubleshooting

  • No row arrives: check that Google Sheets is switched on in the signal’s Integrations tab, that the signal is Active and that the connected Google account can edit the sheet.
  • Empty values in a column: the published notice does not carry the information (no deadline or no contact, for example).
  • Renamed column: Rodz writes each value under the header of the same name; a renamed Rodz column is no longer recognized. Keep the original headers.

Frequently asked questions

Which columns does Rodz write to the sheet?

Among others: Timestamp, Company (the buyer), Tender Subject, Tender URL, Market Type, Response Deadline, Tender Description, Published Date, CPV Code, Notice Source, Buyer SIREN, Buyer City, Buyer Website, Buyer Contact Email, Buyer Contact Phone and Signal Name.

Can I get European notices?

Yes. Add ted to the sources, then filter with countryCodes (2-letter ISO country codes) and cpvCodes. Departments and market types apply to BOAMP notices.

Can the same notice arrive twice?

No: each tender is delivered once per signal, within the daily limit.

Can I get a contact at the buyer?

The row already holds the email and phone published on the notice. For a named decision-maker, turn on persona targeting (enablePersonaTargeting, targetPersonas): the person found is delivered as the contact.

What does it cost a month?

7 credits per delivered notice, capped by the daily limit. With a limit of 5 notices a day, the maximum is 35 credits a day. A credit costs €0.10 to €0.05 excl. VAT depending on the pack.

Sources

Try it on your own market

Create an account: 100 free credits to test, no credit card.