Developers

API and MCP server

Connect Discer data to your tools and AI agents: open tenders, tender intelligence, Pipeline, renewals, company and buyer profiles, market report.

API base URL
https://api.discer.ca/api/v1
MCP server
https://api.discer.ca/mcp
Version
1.2.0
Access
Team plan
Contents

1.Overview

REST API

Your account's data as JSON, over HTTPS, read-only.

MCP server

The same data for your AI agents (Claude, Cursor, VS Code, Codex…), through the MCP protocol. Read-only tools.

Access

Team plan. Other plans get a 402 plan_required response. The API and the MCP server share the same keys and the same limits.

2.Get started

  1. Create a key

    The account owner creates the key in Settings › API and MCP. The full key is shown only once: keep it in a secrets manager. At most 3 active keys per account.

  2. Authenticate every request

    Send the key in the Authorization: Bearer dsk_live_… header. Without a valid key, the API returns 401.

  3. Call the API

    All endpoints are under https://api.discer.ca/api/v1. For example, search open tenders that contain “pavage” (paving):

curl
export DISCER_API_KEY="dsk_live_YOUR_KEY"

curl "https://api.discer.ca/api/v1/tenders?q=pavage&region=5&limit=20" \
  -H "Authorization: Bearer $DISCER_API_KEY"
Response example (made-up data)
{
  "data": [
    {
      "id": "1234567",
      "source": "seao",
      "title": "Réfection de pavage, rue des Exemples",
      "buyer": "Ville de Exempleville",
      "buyer_city": "Exempleville",
      "region_code": 5,
      "region": "Estrie",
      "province": "QC",
      "published_at": "2026-10-01T09:00:00-04:00",
      "closes_at": "2026-10-22T14:00:00-04:00",
      "days_left": 19,
      "estimated_value": 850000,
      "unspsc": "72141100",
      "language": "fr",
      "relevance": null
    }
  ],
  "pagination": {
    "next_cursor": "eyJvIjoyMCwiZiI6ImFiYzEyMyJ9",
    "has_more": true,
    "total": 37
  }
}

Key scope: lecture (read). The API and the MCP server are read-only.

3.Conventions

  • JSON responses: {"data": …}; lists add pagination.
  • Timestamps: ISO 8601 with UTC offset, e.g. 2026-10-22T14:00:00-04:00.
  • Date filters (published_after, closing_before…): calendar days in Québec time (America/Toronto); _after is inclusive, _before is exclusive.
  • Amounts: Canadian dollars, as published. Fields ending in _2026_dollars are indexed to 2026 dollars.
  • Statistics: figures {value, n, period: {from, to}, source}, where n is the sample size. Quote them with n and the period.
  • Explanatory notes (note, definition), labels and some enumerated values are in French.
  • No personal contact data is returned: only public bodies and bidding companies, as published on SEAO, are named.

4.Pagination

Paginated lists return pagination.next_cursor, pagination.has_more and pagination.total. Send the cursor back in the cursor parameter, with the same filters: a cursor issued for other filters is refused (422 invalid_cursor).

limit is 1 to 100 (50 by default). A filtered query stops at 1,000 results (422 pagination_limit): narrow the filters to go further. Tender search and renewals require at least one filter.

Python
url = "https://api.discer.ca/api/v1/tenders"
headers = {"Authorization": f"Bearer {os.environ['DISCER_API_KEY']}"}
params = {"q": "pavage", "region": 5, "limit": 100}
tenders = []
while True:
    body = requests.get(url, params=params, headers=headers, timeout=30).json()
    tenders.extend(body["data"])
    if not body["pagination"]["has_more"]:
        break
    params["cursor"] = body["pagination"]["next_cursor"]

5.Endpoints

The 19 operations of version 1.2.0, taken from the API's OpenAPI definition. Every endpoint requires a key; possible statuses are listed under each endpoint.

Account

GET/me

Your account, plan and API key

The account the key belongs to, its plan and the key's scopes. Use it to test a key.

Success: 200 · Possible errors: 401, 402, 403, 422, 429

Tenders

GET/tendersPaginated

Search open tenders

Tenders open today. At least one filter is required. _after dates are inclusive and _before dates exclusive. Each returned row counts toward the account's list rows.

Parameters

  • qstringqueryoptional

    Words in the title or buyer name, e.g. pavage.

    At most 200 characters

  • sourcestringqueryoptional

    Source of the tender.

    Values: seao, canadabuys, toronto

  • provincestring[]queryoptionalrepeatable

    ISO province code (QC, ON…), repeatable. Canada-wide tenders are included.

  • regioninteger[]queryoptionalrepeatable

    Québec administrative region code (1-17), repeatable.

  • unspscstringqueryoptional

    UNSPSC code prefix, 2 to 8 digits, e.g. 7214.

    Pattern: ^\d{2,8}$

  • buyerstringqueryoptional

    Part of the buyer name, e.g. Ville de Lévis.

    At most 200 characters

  • published_afterdatequeryoptional

    Calendar date YYYY-MM-DD, Québec time (America/Toronto).

  • published_beforedatequeryoptional

    Calendar date YYYY-MM-DD, Québec time (America/Toronto).

  • closing_afterdatequeryoptional

    Calendar date YYYY-MM-DD, Québec time (America/Toronto).

  • closing_beforedatequeryoptional

    Calendar date YYYY-MM-DD, Québec time (America/Toronto).

  • profilestringqueryoptional

    Watch profile id (principal or an id from /watch-profiles): adds relevance and ranks by score; sort is then ignored.

    At most 40 characters

  • sortstringqueryoptional

    closing_asc: closing soonest first; published_desc: newest first.

    Default: closing_ascValues: closing_asc, published_desc

  • limitintegerqueryoptional

    Page size, 1 to 100.

    Default: 50From 1 to 100

  • cursorstringqueryoptional

    pagination.next_cursor from the previous page. Send the same filters with it.

    At most 200 characters

Success: 200 · Possible errors: 401, 402, 403, 404, 409, 422, 429

GET/tenders/{tender_id}

Tender detail with its intelligence

Tender facts and, for SEAO tenders, its intelligence: key facts, win probability (when calibrated), winning price range (same sub-category when available), expected bidders and their bid probability, competitiveness and price position (open tenders), buyer history for this UNSPSC category, amendments. Counts as one distinct tender record for the account's daily and monthly limits.

Parameters

  • tender_idstringpathrequired

    Tender id from /tenders: SEAO number, or CB-…, TOR-… for other sources.

    At most 40 characters

  • intelligencebooleanqueryoptional

    Include the intelligence block (SEAO tenders).

    Default: true

Success: 200 · Possible errors: 401, 402, 403, 404, 422, 429

Your data

GET/bidsPaginated

Your Pipeline (tenders by stage)

Cards of the account's Pipeline, discarded cards excluded: stage, bid price, relevance, followed tenders and their news (addenda, closing changes, published result). Does not count toward list rows.

Parameters

  • statusstringqueryoptional

    Pipeline stage.

    Values: to_evaluate, preparing, submitted, won, lost

  • limitintegerqueryoptional

    Page size, 1 to 100.

    Default: 50From 1 to 100

  • cursorstringqueryoptional

    pagination.next_cursor from the previous page. Send the same filters with it.

    At most 200 characters

Success: 200 · Possible errors: 401, 402, 403, 422, 429

GET/watch-profiles

Watch profiles (use their id in /tenders?profile=)

The account's watch profiles: UNSPSC categories, keywords, regions, value range.

Success: 200 · Possible errors: 401, 402, 403, 422, 429

Market

GET/renewalsPaginated

Upcoming renewals (contracts ending soon, with incumbents)

Contracts from past tenders (not sole-source) whose expected end falls within the horizon, with their incumbents; your company's contracts first (is_you). A new call for tenders is not confirmed. At least one of family, region, buyer_id or for_me is required. Each returned row counts toward the account's list rows.

Parameters

  • familystringqueryoptional

    UNSPSC prefix, 2 or 4 digits, e.g. 7214.

    Pattern: ^\d{2,4}$

  • regionintegerqueryoptional

    Québec administrative region code (1-17).

    From 1 to 17

  • buyer_idintegerqueryoptional

    Buyer id from /buyers.

    At least 1

  • horizon_monthsintegerqueryoptional

    Contracts whose expected end falls within N months.

    Default: 12From 1 to 24

  • for_mebooleanqueryoptional

    Only your niche (watch profile categories, keywords and regions), as on the Renewals page.

    Default: false

  • all_regionsbooleanqueryoptional

    With for_me and an all-Québec profile with priority regions: all of Québec instead of the priority regions.

    Default: false

  • limitintegerqueryoptional

    Page size, 1 to 100.

    Default: 50From 1 to 100

  • cursorstringqueryoptional

    pagination.next_cursor from the previous page. Send the same filters with it.

    At most 200 characters

Success: 200 · Possible errors: 401, 402, 403, 409, 422, 429, 503

GET/companies

Find companies by name or NEQ

Companies that bid on SEAO, matched by name (accents, case and legal suffixes ignored) or NEQ, at most 10. Each match counts toward the account's list rows.

Parameters

  • qstringqueryrequired

    Part of the company name, or the start of its NEQ (3 to 10 digits).

    2 to 80 characters

Success: 200 · Possible errors: 401, 402, 403, 422, 429

GET/companies/{neq}

Company profile (SEAO bidding history)

Bids, wins, win rate, top buyers, UNSPSC categories, regions, main opponents with head-to-head, recent bids with prices, strength in its market, amendments of its contracts. Counts as one distinct company profile.

Parameters

  • neqstringpathrequired

    Québec enterprise number, 10 digits.

Success: 200 · Possible errors: 401, 402, 403, 404, 422, 429

GET/buyers

Find public buyers by name

Public buyers (cities, ministries, school boards…), most active first, at most 10. Each match counts toward the account's list rows.

Parameters

  • qstringqueryrequired

    Part of the buyer name, e.g. Ville de Québec.

    2 to 120 characters

Success: 200 · Possible errors: 401, 402, 403, 422, 429

GET/buyers/{buyer_id}

Buyer profile (purchases, winners, prices, sole-source, amendments)

Purchases by UNSPSC category over 5 years, top winners, price ranges, market presence, sole-source contracts and amendments. Counts as one distinct buyer profile.

Parameters

  • buyer_idintegerpathrequired

    Buyer id from /buyers.

Success: 200 · Possible errors: 401, 402, 403, 404, 422, 429

GET/market

Your market report (your company's SEAO record, competitors, lost tenders)

Market report of the account's company: niche, figures, competitors, lost tenders. report is null when the account has no company NEQ; an unverified NEQ gets the public-level report.

Success: 200 · Possible errors: 401, 402, 403, 422, 429

GET/market/competitors

Companies that win the most in your niche

Companies that won the most contracts in your niche over 36 months (your bids, otherwise your watch profile): contracts won, bids, win rate, last bid, and the median win rate of active companies. Works for a company that rarely bids or never did; yours is never listed.

Success: 200 · Possible errors: 401, 402, 403, 422, 429

GET/market/portrait

Market figures for your niche

For the first 3 UNSPSC categories of your niche (your bids, otherwise your watch profile): tenders published, open tenders, bidders per tender, amounts awarded, main buyers, tenders per month. Your region when the profile has only one, otherwise all of Québec.

Success: 200 · Possible errors: 401, 402, 403, 422, 429

Concluded tenders

GET/concluded-tendersPaginated

Search concluded tenders (winners, amounts, bidders)

SEAO tenders concluded since 2015, as on the History page: winner, winning amount, number of bidders, gap between the two lowest submitted prices, your own result. At least one filter is required. _after dates are inclusive and _before dates exclusive (conclusion date, otherwise publication date). Each returned row counts toward the account's list rows.

Parameters

  • qstringqueryoptional

    Words in the title, e.g. pavage.

    At most 200 characters

  • unspscstringqueryoptional

    UNSPSC category (4 digits) or segment (2 digits), e.g. 7214.

    Pattern: ^\d{2}(\d{2})?$

  • buyer_idintegerqueryoptional

    Buyer id from /buyers.

    At least 1

  • regionintegerqueryoptional

    Québec administrative region code (1-17).

    From 1 to 17

  • concluded_afterdatequeryoptional

    Calendar date YYYY-MM-DD, Québec time (America/Toronto).

  • concluded_beforedatequeryoptional

    Calendar date YYYY-MM-DD, Québec time (America/Toronto).

  • min_amountnumberqueryoptional

    Minimum winning amount. Canadian dollars.

    At least 0

  • max_amountnumberqueryoptional

    Maximum winning amount. Canadian dollars.

    At least 0

  • companystringqueryoptional

    NEQ of a company that bid (or won, with role=won).

    Pattern: ^\d{10}$

  • rolestringqueryoptional

    With company: tenders it bid on, or won.

    Default: bidValues: bid, won

  • minebooleanqueryoptional

    Only tenders your company bid on (verified NEQ).

    Default: false

  • min_biddersintegerqueryoptional

    Minimum number of bidders.

    From 1 to 500

  • max_biddersintegerqueryoptional

    Maximum number of bidders.

    From 1 to 500

  • pricesstringqueryoptional

    with: all prices published; without: prices not published.

    Values: with, without

  • sortstringqueryoptional

    recent first, highest amount first, or largest gap between the two lowest submitted prices first.

    Default: recentValues: recent, amount, gap

  • limitintegerqueryoptional

    Page size, 1 to 50.

    Default: 25From 1 to 50

  • cursorstringqueryoptional

    pagination.next_cursor from the previous page. Send the same filters with it.

    At most 200 characters

Success: 200 · Possible errors: 401, 402, 403, 422, 429, 503

GET/concluded-tenders/{tender_id}

A concluded tender: every bid and its price

Every bidder with its price, rank and gap to the winner, second-lowest price, price dispersion, amendments of the contract, similar concluded tenders. Counts as one distinct tender record.

Parameters

  • tender_idstringpathrequired

    SEAO number from /concluded-tenders.

    Pattern: ^\d{1,12}$

Success: 200 · Possible errors: 401, 402, 403, 404, 422, 429, 503

Subcontracting

GET/subcontracting/openPaginated

Open tenders where one of your trades may be needed

Open tenders where one of the trades of your Subcontracting settings may be needed (RBQ licence in construction, analysis of the documents elsewhere), as on the Subcontracting page. Empty when the account has no trade. Each returned row counts toward the account's list rows.

Parameters

  • tradestringqueryoptional

    One of your trades (a code from trade_codes: RBQ sub-category such as 4.1, service code or libre:…).

    At most 90 characters

  • regionintegerqueryoptional

    Québec administrative region code (1-17).

    From 1 to 17

  • min_amountnumberqueryoptional

    Minimum estimated value. Canadian dollars.

    At least 0

  • max_amountnumberqueryoptional

    Maximum estimated value. Canadian dollars.

    At least 0

  • since_daysintegerqueryoptional

    Published within N days.

    From 1 to 365

  • limitintegerqueryoptional

    Page size, 1 to 50.

    Default: 25From 1 to 50

  • cursorstringqueryoptional

    pagination.next_cursor from the previous page. Send the same filters with it.

    At most 200 characters

Success: 200 · Possible errors: 401, 402, 403, 422, 429, 503

GET/subcontracting/awardedPaginated

Awarded tenders in your trades: winners to contact

Tenders awarded in your trades, region and value range: the winning company to contact for subcontracting (name, NEQ, city), amount, trades. The contact published by SEAO is read in Discer only. Each returned row counts toward the account's list rows.

Parameters

  • tradestringqueryoptional

    One of your trades (a code from trade_codes: RBQ sub-category such as 4.1, service code or libre:…).

    At most 90 characters

  • regionintegerqueryoptional

    Québec administrative region code (1-17).

    From 1 to 17

  • min_amountnumberqueryoptional

    Minimum winning amount. Canadian dollars.

    At least 0

  • max_amountnumberqueryoptional

    Maximum winning amount. Canadian dollars.

    At least 0

  • since_daysintegerqueryoptional

    Concluded within 30, 90 or 365 days.

    Default: 90From 30 to 365

  • winnerstringqueryoptional

    Only the tenders won by this NEQ (all trades).

    Pattern: ^\d{10}$

  • buyer_idintegerqueryoptional

    Only this buyer's tenders (all trades).

    At least 1

  • limitintegerqueryoptional

    Page size, 1 to 50.

    Default: 25From 1 to 50

  • cursorstringqueryoptional

    pagination.next_cursor from the previous page. Send the same filters with it.

    At most 200 characters

Success: 200 · Possible errors: 401, 402, 403, 422, 429

Private tenders

GET/private-tenders

Private tenders sent to your organization

Private tenders published on Discer by public and private buyers. Read-only: interest, questions and bids are given in Discer. Each returned row counts toward the account's list rows.

Parameters

  • viewstringqueryoptional

    for_you: the private tenders your organization was invited to or matched; all: every open one.

    Default: for_youValues: for_you, all

Success: 200 · Possible errors: 401, 402, 403, 404, 422, 429

GET/private-tenders/{private_tender_id}

A private tender

The private tender as your organization sees it. Reading it here registers no interest and no view (opening it in Discer does). Counts as one distinct tender record.

Parameters

  • private_tender_idstringpathrequired

    id from /private-tenders.

    At most 40 characters

Success: 200 · Possible errors: 401, 402, 403, 404, 422, 429

6.Errors

Every error returns an error object with code, message and, when useful, details. The code is stable; the message, in English, may change.

Error example
{
  "error": {
    "code": "invalid_parameter",
    "message": "Invalid parameters.",
    "details": {
      "errors": [
        {
          "parameter": "limit",
          "message": "Input should be less than or equal to 100"
        }
      ]
    }
  }
}
  • 401missing_api_keyNo Authorization: Bearer header.
  • 401invalid_api_keyUnknown or malformed key.
  • 401revoked_api_keyThe key was revoked in Settings.
  • 402plan_requiredThe account is not on the Team plan, or its subscription is inactive.
  • 402subscription_pausedThe subscription is paused: access resumes with it.
  • 402first_payment_requiredTrial period: the API and MCP server open with the first payment.
  • 403api_key_suspendedThe key is suspended pending review after unusual usage.
  • 403account_under_reviewAPI, MCP, assistant and exports are paused pending review.
  • 403account_disabledThe account is disabled.
  • 404not_foundUnknown tender, company, buyer, watch profile or path.
  • 405method_not_allowedHTTP method not supported on this path.
  • 409profile_inactiveThis watch profile is inactive on the current plan.
  • 409profile_incompletefor_me needs a watch profile with categories or keywords.
  • 422invalid_parameterA parameter is missing or invalid (details.errors lists them).
  • 422invalid_cursorThe cursor is malformed or was issued for other filters.
  • 422filter_required/tenders and /renewals need at least one filter.
  • 422pagination_limitPaging stops after the result cap of a filtered query: narrow the filters.
  • 429rate_limitedToo many requests in the last minute.
  • 429quota_exceededDaily or monthly request cap reached.
  • 429entity_quota_exceededDaily or monthly cap of distinct records reached.
  • 429row_quota_exceededDaily or monthly cap of list rows reached.
  • 429temporarily_blockedAccess paused for 24 hours after unusual usage.
  • 500internal_errorUnexpected server error: try again; write to thomas@contact.discer.ca if it persists.
  • 503not_readyRenewals are being computed: try again later.

429 responses carry the Retry-After header, in seconds.

7.Limits and safeguards

Discer is built for teams that prepare their own bids, not for copying its database. Limits per account, all keys and the MCP server combined; days and months follow Québec time.

Limits per account
MeasurePer dayPer month
Requests (API and MCP)and 60 per minute2,00030,000
Distinct tender records3003,000
Distinct company profiles2002,000
Distinct buyer profiles100600
List rows returned5,00060,000
  • A record already viewed this month does not count twice.
  • At most 3 active keys per account; at most 1,000 results per filtered query.
  • Over a limit: 429 with the Retry-After header.
  • Systematic use (records requested in sequence, deep paging) slows the account down, then pauses it, then suspends its keys pending review (403 api_key_suspended).
  • Systematic extraction, resale, rebuilding a database and training models with Discer data are prohibited: see the terms of use. You accept these rules when you create a key.

8.MCP server

The MCP server gives Discer data to an AI agent, with the same key and the same limits as the API.

URL
https://api.discer.ca/mcp
Header
Authorization: Bearer dsk_live_…
Transport
Streamable HTTP, stateless, JSON responses. Both /mcp and /mcp/ answer.

Set up your client

One command in the terminal. Add --scope user to have it in all your projects.

Claude Code
claude mcp add --transport http discer https://api.discer.ca/mcp \
  --header "Authorization: Bearer dsk_live_YOUR_KEY"

Never commit a key: use an environment variable or your client's secret storage. Revoke an exposed key in Settings › API and MCP; it takes effect immediately.

9.MCP tools

14 read-only tools. Each tool returns compact JSON; the API limits apply.

search_open_tendersRead-only

Search tenders OPEN today (SEAO and other Canadian sources): id, title, buyer, closing date (ISO 8601), days left, estimated value (Canadian dollars), link, and the total number of matches. Never reveals who is preparing a bid on an open tender.

Arguments

  • querystringoptional

    Words in the title or buyer name (French gives more matches), e.g. 'pavage'

  • unspscstringoptional

    UNSPSC code prefix, 2 to 8 digits, e.g. '7214' (heavy construction)

    Pattern: ^\d{2,8}$

  • regionstringoptional

    Québec administrative region: code 1-17 or name, e.g. 'Montérégie'

  • buyerstringoptional

    Part of the public buyer name, e.g. 'Ville de Lévis'

  • sourcestringoptional

    seao, canadabuys or toronto

  • closing_within_daysintegeroptional

    Only tenders closing within N calendar days (Québec time)

    From 1 to 365

  • use_watch_profilebooleanoptional

    Rank by relevance (score 0-100) to the account's main watch profile

    Default: false

  • limitintegeroptional

    Tenders to return, 1 to 25

    Default: 10From 1 to 25

get_tender_intelligenceRead-only

Full intelligence for one tender: key facts (French), Discer's calibrated win probability for your company (only when the segment is calibrated; report it as given), winning price range observed at this buyer and UNSPSC category (2026 dollars, with n and period), expected gap between the two lowest submitted prices, competitiveness and price position (open tenders), expected bidders with their bid probability, buyer history. Information, not a recommendation. Counts as one distinct tender record.

Arguments

  • tender_idstringrequired

    Tender id from search_open_tenders (SEAO number, e.g. '20158453')

get_winning_priceRead-only

Observed winning prices relevant to a tender: P10-P90 of comparable winning bids (same sub-category when available; Canadian dollars indexed to 2026, with n and period), price per 12 months for recurring services, expected gap between the lowest and second-lowest bid, buyer's winning-price-to-estimate ratio, and the price position of past bids (open tenders). Information calculated from past tenders, never a recommendation or a guarantee.

Arguments

  • tender_idstringrequired

    SEAO tender number, e.g. '20158453'

get_likely_biddersRead-only

Companies that may bid on a tender: bidders of the most similar concluded tenders (or 36 months of SEAO history at this buyer and in this UNSPSC category and region), with their bid probability when Discer's model computed it, bids and wins with the buyer, and head-to-head record with your company.

Arguments

  • tender_idstringrequired

    SEAO tender number, e.g. '20158453'

get_buyer_profileRead-only

Public buyer profile: purchases by UNSPSC category (5 years), top winners, price ranges (Canadian dollars), sole-source contracts and amendments. Give buyer_id, or a name: several matches return candidates with their buyer_id.

Arguments

  • buyer_idintegeroptional

    Discer buyer id (from a previous result)

  • namestringoptional

    Buyer name to look up, e.g. 'Ville de Québec'

get_company_profileRead-only

A company's SEAO bidding record: bids, wins, win rate, top buyers, UNSPSC categories, regions, main opponents with head-to-head, recent bids with prices (Canadian dollars). Give a NEQ, or a name: several matches return candidates with their NEQ.

Arguments

  • neqstringoptional

    Québec enterprise number (10 digits)

    Pattern: ^\d{10}$

  • namestringoptional

    Company name to look up

list_my_bidsRead-only

The account's Pipeline (tenders by stage, discarded cards excluded): tender, buyer, status, bid price, closing date, notes, relevance, followed tenders and their news (addenda titles, closing date changes, published result and winner, cancellation).

Arguments

  • statusstringoptional

    Pipeline stage: to_evaluate, preparing, submitted, won or lost

    Values: to_evaluate, preparing, submitted, won, lost

  • limitintegeroptional

    Cards to return, 1 to 100

    Default: 50From 1 to 100

list_upcoming_renewalsRead-only

Contracts from past tenders whose expected end falls within the horizon, with the incumbent: possible re-tenders (not confirmed). Buyer, title, expected end (YYYY-MM-DD), amount (Canadian dollars), incumbents; the account's own contracts first (is_you). Without family, region or buyer_id: the account's niche (for_me).

Arguments

  • familystringoptional

    UNSPSC prefix, 2 or 4 digits, e.g. '7214'

    Pattern: ^\d{2,4}$

  • regionstringoptional

    Québec region code 1-17 or name, e.g. 'Laurentides'

  • buyer_idintegeroptional

    Discer buyer id (from get_buyer_profile)

    At least 1

  • horizon_monthsintegeroptional

    Expected end within N months

    Default: 12From 1 to 24

  • for_mebooleanoptional

    Only the account's niche (watch profile), as on the Renewals page

    Default: false

  • limitintegeroptional

    Contracts to return, 1 to 50

    Default: 20From 1 to 50

search_concluded_tendersRead-only

Search SEAO tenders concluded since 2015: winner, winning amount (Canadian dollars), number of bidders, gap between the two lowest submitted prices, the account's own result, and the total number of matches. Give at least one filter.

Arguments

  • querystringoptional

    Words in the title (French gives more matches), e.g. 'pavage'

  • unspscstringoptional

    UNSPSC category (4 digits) or segment (2 digits), e.g. '7214'

    Pattern: ^\d{2}(\d{2})?$

  • regionstringoptional

    Québec administrative region: code 1-17 or name, e.g. 'Montérégie'

  • buyer_idintegeroptional

    Discer buyer id (from get_buyer_profile)

    At least 1

  • company_neqstringoptional

    Only tenders this company bid on

    Pattern: ^\d{10}$

  • won_onlybooleanoptional

    With company_neq: only the tenders it won

    Default: false

  • minebooleanoptional

    Only tenders the account's company bid on

    Default: false

  • concluded_within_monthsintegeroptional

    Concluded within N months

    From 1 to 144

  • sortstringoptional

    recent, amount (highest first) or gap (largest gap between the two lowest submitted prices first)

    Default: recentValues: recent, amount, gap

  • limitintegeroptional

    Tenders to return, 1 to 25

    Default: 10From 1 to 25

get_concluded_tenderRead-only

One concluded tender: every bidder with its price (Canadian dollars), rank and gap to the winner, second-lowest price, amendments of the contract. Counts as one distinct tender record.

Arguments

  • tender_idstringrequired

    SEAO number of a concluded tender

    Pattern: ^\d{1,12}$

list_subcontracting_opportunitiesRead-only

Subcontracting, from the trades of the account's Subcontracting settings: open tenders where a trade may be needed, or awarded tenders with the winning company to contact (name, NEQ, city; its published contact is read in Discer only).

Arguments

  • kindstringoptional

    open: open tenders where one of the account's trades may be needed; awarded: awarded tenders in its trades, with the winner to contact

    Default: openValues: open, awarded

  • tradestringoptional

    One of the account's trade codes (see trade_codes in a previous result)

  • regionstringoptional

    Québec region code 1-17 or name

  • since_daysintegeroptional

    open: published within N days; awarded: 30, 90 or 365 (default 90)

    From 1 to 365

  • limitintegeroptional

    Tenders to return, 1 to 25

    Default: 10From 1 to 25

get_niche_marketRead-only

The account's niche (its bids, otherwise its watch profile): companies that win the most there over 36 months (contracts won, bids, win rate) and market figures for its first 3 UNSPSC categories (tenders published, bidders per tender, amounts, main buyers). Useful even for a company that rarely bids or never did.

list_private_tendersRead-only

Private tenders published on Discer by buyers (public or private): title, buyer, city, closing date, status, whether the account's organization was invited and has bid. Read-only.

Arguments

  • viewstringoptional

    for_you: invited or matched; all: every open private tender

    Default: for_youValues: for_you, all

get_private_tenderRead-only

One private tender as the account's organization sees it: scope, constraints, dates, document names, addenda, published questions and answers, Discer's analysis of the documents; after the opening, the account's result and, with the Team plan, bidders, prices and winner. Reading it here registers no interest (opening it in Discer does).

Arguments

  • private_tender_idstringrequired

    id from list_private_tenders

10.Version and changes

Current version: 1.2.0.

  1. October 3, 2026/mcp/ (trailing slash) accepted without a redirect; date filters in Québec time; source parameter limited to sources that publish tenders (seao, canadabuys, toronto); 405, 500 and NUL-character errors in the error format; detailed response schemas in the OpenAPI.
  2. September 29, 2026 · 1.0.0First version: 12 paths, 8 MCP tools.