Cloud & Infrastructure|November 2, 2026|13 min read

One Tender Platform for FAR, Find a Tender, and EU TED

A practitioner architecture for ingesting US FAR solicitations, UK Find a Tender notices, and EU TED eForms into one canonical schema with jurisdiction-specific compliance rule packs.

Projectory team

To run US federal, UK, and EU public-sector pursuits from one platform, you need exactly four things: one ingestion layer per source, one canonical opportunity object they all write into, versioned jurisdiction rule packs sitting above that object, and a supplier identity store kept separate from opportunity data. You do not need three codebases. All three regimes now publish structured, machine-readable notices: FAR Part 5 governs US publicizing through the governmentwide point of entry [1] with GSA's documented Get Opportunities public API [2], the Procurement Act 2023 restructured UK notice duties routed through Find a Tender [3][4], and Commission Implementing Regulation (EU) 2019/1780 made eForms the standard notice structure on TED [7][5].

So collection is solved. What is not solved is what happens after collection, and that is where most multi-jurisdiction platforms quietly fail.

This is a design article for product leads and capture operations leaders who have been handed a mandate like "cover UK and EU work next quarter" and need to decide what to build first. It is written in the vocabulary proposal managers already use, because they are the people who will live inside whatever you ship.

Collection Was Never the Hard Part

Every team I have seen attempt this starts in the same place: an engineer writes an adapter for the GSA Get Opportunities API [2], it works, and leadership concludes the problem is tractable. Then someone writes a second adapter for Find a Tender [3]. Then a third for TED using the published eForms structure and TED APIs [6]. Three working adapters, three weeks, everyone pleased.

The bill arrives about four months later. By then the US pipeline has its own go/no-go form keyed to NAICS and product and service codes. The UK pipeline has a different form because award criteria and weightings are stated in the notice itself. The EU pipeline has a third form because eligibility runs through standardized self-declarations. Nobody can produce a single pipeline report, because contract value means three different things and nobody wrote down which.

That is normalization debt, and it compounds faster than technical debt because it lives in process, not code. The symptoms are easy to spot:

  • Three compliance matrix templates exist, each with different column names for the same concept.
  • Win rate is uncomputable across regimes because opportunity value, notice dates, and closing dates were never given shared definitions.
  • Content reuse breaks at the border, so a past performance narrative written for a US pursuit gets retyped for a UK one.
  • Nobody owns the crosswalk between CPV codes and NAICS or PSC codes, so service-line reporting is assembled by hand in a spreadsheet each quarter.
  • A portal redesign silently empties the pipeline because the adapter was written against page structure rather than the published notice schema.

Set one architectural rule before any of this happens: ingestion follows the legal publication obligation, not the HTML of a portal page. For US actions that means FAR Part 5 publicizing requirements and the governmentwide point of entry [1]. For UK actions it means the notice duties under the Procurement Act 2023 [4]. For EU notices it means the eForms notice types established under Implementing Regulation (EU) 2019/1780 [7]. Portals get redesigned. Statutory publication duties change on a legislative timeline you can actually plan around.

What Actually Differs Between the Three Regimes

The differences that matter are not cosmetic. Three of them break naive designs: where requirements live, how evaluation criteria are expressed, and how eligibility gets proven.

In US federal solicitations, instructions and evaluation criteria are split across separate sections, and the substantive requirements live inside attached documents rather than in the notice record. Your extractor has to open the PDFs. In UK notices published on Find a Tender, award criteria and weightings are typically stated in the notice itself [3], which means a structured field can carry what a US pursuit needs a document parser to recover. In EU notices, eForms gives you a defined field structure [7][6], and exclusion and selection criteria connect to standardized self-declarations with national evidence equivalents locatable through eCertis [11].

DimensionUS federalUKEU (TED)
Publication triggerFAR Part 5 publicizing, governmentwide point of entry [1]Procurement Act 2023 notice duties [4]eForms notice types under Reg. (EU) 2019/1780 [7]
Machine-readable sourceGSA Get Opportunities public API [2]Find a Tender service [3]TED APIs with eForms structure [6][5]
Classification codesNAICS and product/service codesCPVCPV
Criteria conventionInstructions and evaluation factors split across solicitation sectionsAward criteria and weightings stated in the notice [3]Criteria structured in the notice, linked to self-declarations [11]
Eligibility evidenceSAM.gov entity registration and unique entity identifier per FAR Part 4 [8][9]Central digital platform supplier information [10]Standardized self-declaration plus national evidence via eCertis [11]
Adapter burdenLow for notices, high for document parsingLow, structured fields carry criteriaModerate, multilingual documents and dense field set

Read that table as a build estimate. The adapters are the cheap part everywhere. The expensive parts are document parsing on the US side and multilingual handling on the EU side, and neither of those is an adapter concern. They belong in shared services that every adapter feeds.

The Canonical Opportunity Schema and Its Extension Blocks

The core object should contain only what every regime genuinely has: buyer, identifiers, title, dates, value, classification, documents, and source lineage carrying both the raw and the normalized value for anything you transformed. Everything else goes in a named extension block.

json
{
  "opportunity_id": "int-2026-004871",
  "buyer": { "name": "...", "country": "GB", "buyer_id": "..." },
  "title": "...",
  "dates": { "published": "2026-02-11", "closing": "2026-03-20T14:00:00Z" },
  "value": { "raw": "4,000,000", "currency": "GBP", "normalized_usd": 5040000,
             "basis": "estimated_maximum" },
  "classification": { "source_scheme": "CPV", "source_codes": ["72000000"],
                      "internal_service_line": "digital-engineering" },
  "documents": [ { "uri": "...", "language": "en", "class": "buyer_document" } ],
  "lineage": { "source": "find_a_tender", "notice_type": "...",
               "fetched_at": "...", "adapter_version": "2.4.1" },
  "uk_ext": { "award_criteria": [ { "name": "...", "weight": 40 } ] },
  "far_ext": null,
  "eforms_ext": null
}

Two design choices in there do most of the work. First, `value.basis` is explicit, because contract value, estimated maximum value, and framework ceiling are different numbers that executives will otherwise average together. Second, `lineage.adapter_version` is stored on the record, so when you find a parsing bug you can identify exactly which records were affected rather than reprocessing everything.

For reporting fields, use the Open Contracting Data Standard as your reference model for lifecycle stages and award structures rather than inventing your own vocabulary. Also keep the opportunity side and the award side apart: notice feeds drive pipeline, official award reporting drives outcome analysis, and mixing them inside one win-rate metric produces a number nobody can defend in a board meeting.

Then instrument each adapter. Track notice counts per day, parse failure rate, and unmapped classification rate, and alert on schema drift. A regime can update its notice structure without telling you. The failure mode is not an error page; it is a pipeline that quietly reports zero new opportunities while everyone assumes the market went quiet.

Requirement Extraction That Works in Four Languages

Split extraction into three stages so only one of them changes per locale. Stage one is document segmentation: find sections, headings, tables, and attachments. Stage two is requirement candidate detection: find sentences that impose an obligation. Stage three is obligation classification: decide whether the candidate is a mandatory submission instruction, an evaluation factor, an eligibility condition, or informational context.

Only stage two is meaningfully language-dependent. Segmentation is structural. Classification operates on a normalized representation. That is the whole reason to decompose it this way: adding French and German costs you one layer, not a pipeline.

Keep the extracted requirement text as the primary record and the citation or notice field as metadata. This matters right now because the FAR is being rewritten part by part, with revised parts and model deviation text published as they are completed [13][12]. If your matrix rows are keyed to a part number, renumbering forces a narrative rewrite. If the requirement is the record and the citation is an attribute, renumbering is a metadata update with a changelog. We covered that failure mode in detail in the FAR overhaul compliance gap.

For multilingual work, extract in the source language, store the source span (document, page, character offsets), and attach translations as derived fields. Never overwrite the original. When a reviewer challenges an interpretation of a German-language specification, you need to show the German text, not a translation of a translation.

A normalized matrix row that works across all three regimes carries the same fields regardless of origin:

  • Requirement text in source language, verbatim.
  • Source locator: document name plus page and offset, or the eForms field identifier.
  • Jurisdiction and rule pack version that produced the row.
  • Obligation class: submission instruction, evaluation factor, eligibility condition.
  • Owner and evidence reference pointing at a reusable content record.
  • Status with last-verified date.

If you want the US-only mechanics in depth, the walkthroughs on Section M decomposition and compliance matrix automation cover the single-jurisdiction version of this pipeline, and the content reuse library guide covers the evidence side.

Jurisdiction Rule Packs Instead of Three Codebases

A rule pack is a versioned, reviewable bundle that encodes everything jurisdiction-specific: mandatory notice fields, eligibility checks, criteria weighting logic, submission constraints, and reviewer gates. It sits above the shared extractor. It is data, not code.

yaml
pack: uk_find_a_tender
version: 2026.1
eligibility_checks:
  - central_digital_platform_profile_current   # ref [10]
  - financial_standing_evidence_within_24mo
criteria_model: stated_weightings_from_notice
submission_constraints:
  portal_enforced_fields: true
reviewer_gates:
  - name: criteria_weighting_review
    owner: capture_lead
crosswalk: cpv_to_internal_service_line@2026.1

The reason this must be readable by a capture lead and not buried in application code is the crosswalk. Mapping CPV codes to NAICS and product and service codes involves judgment calls that only a capture organization can make, and each decision needs a recorded rationale. When the pipeline report looks wrong, someone has to be able to open the mapping, see why code 72000000 routes to a given service line, and change it without filing an engineering ticket.

Supplier identity belongs in a separate master record, not in the rule pack and definitely not in the opportunity object. Model one source of truth per corporate fact, then attach per-regime attestation objects that reference those facts instead of copying them: SAM.gov entity registration and the unique entity identifier for US federal work as addressed in FAR Part 4 [8], with GSA's Entity Information API available for programmatic status and expiry monitoring [9]; central digital platform supplier information for UK procurements [10]; and standardized self-declarations mapped to producible national evidence through eCertis [11].

Then gate submission on a profile completeness check. Expiring eligibility evidence should surface during pursuit review, not at 3pm on the deadline when the registration status page loads wrong.

Stamp the rule pack version on every generated matrix

Print the pack name and version in the header of every compliance matrix your platform generates, next to the adapter version that ingested the notice. When a reviewer disputes a row, the first question is always "which logic produced this?" Without the version stamp, answering takes an afternoon of archaeology. With it, the answer is one line on the page and your changelog tells the rest.

Data Residency and the Single Bid Environment Problem

Classify every artifact at ingestion. Not later, not on demand. Four tiers cover almost everything a bid environment holds:

  1. Public notice data: the notice record itself, published by the buyer. Lowest sensitivity, broadest access, useful for cross-regime analytics.
  2. Buyer-provided documents: solicitation attachments, specifications, drawings. Access scoped per pursuit, retention tied to the award decision.
  3. Proprietary pricing and strategy: price to win models, teaming terms, competitive assessments. Tightest access scope in the system.
  4. Personal data: key personnel CVs, named references, contact details. Retention limits and lawful basis apply regardless of which regime the bid serves.

For components that handle controlled unclassified information, align to NIST SP 800-171 and document the scope boundary explicitly so the assessment surface stays bounded [14]. Scoping is the entire exercise. A platform where CUI can land anywhere is a platform where every component is in scope. Department of Defense Cybersecurity Maturity Model Certification program requirements are codified at 32 CFR Part 170 [15], which is the text to read rather than a vendor summary. For practical artifact work, CMMC artifact engineering covers the documentation side.

Two more checks before you route anything. Confirm the FedRAMP authorization status of cloud services in federal-facing portions of the stack before agency-sourced documents pass through them, and verify it yourself rather than accepting a marketing claim. And treat GDPR as in scope by default on the European side, because tender submissions routinely carry named individuals: document lawful basis, set retention limits per artifact class, restrict access, and keep processing records. Least privilege should be enforced per pursuit and per regime, with access logged.

Two Build Scenarios, Walked Through

Both of the following are illustrative design scenarios, not customer results.

Scenario A: US mid-tier integrator adding UK work

A services integrator with an established US federal capture process wants UK public-sector pipeline. The adapter is the cheap part: Find a Tender publishes structured notices [3] and the notice duties are legislated [4]. Two sprints, maybe three.

The expensive part is the scoring model. Because award criteria and weightings are stated in the notice, the team's existing go/no-go model, built around US evaluation factor structures, produces nonsense. The fix lives in the rule pack: a criteria weighting model that reads stated weightings, maps them to internal capability scores, and feeds a bid decision gate. Sequence it as canonical schema first, one adapter second, UK rule pack third, analytics last.

Scenario B: EU-headquartered firm pursuing US federal work

An EU engineering firm wins its first US federal subcontract and wants its existing TED pipeline to cover SAM.gov opportunities. Here the residency decision comes before any ingestion work. Agency-sourced documents, potential CUI, and FedRAMP considerations push toward a split-tenant design with a bounded US environment, while the EU side continues to hold personal data under European rules.

Decide the tenancy question first, because retrofitting a scope boundary onto a shared store costs more than building two environments did. Then add the SAM.gov adapter [2], then the FAR rule pack with a citation register, then document parsing for solicitation attachments.

Sequencing advice that applies to both: canonical schema and one adapter, then the rule pack, then multilingual extraction, then cross-regime analytics. Teams that build analytics early produce dashboards nobody trusts and then rebuild them.

Frequently asked questions

Can one compliance matrix engine serve all three regimes?

Yes, if the engine operates on normalized requirement records and the jurisdiction logic lives in rule packs above it. The shared parts are segmentation, obligation classification, owner assignment, and status tracking. The regime-specific parts are mandatory field lists, criteria models, and submission constraints.

Do I need separate tenants for EU data?

Not automatically. You need a documented classification and residency decision per artifact class. Separate tenants become the practical answer when CUI scoping under NIST SP 800-171 [14] and EU personal data handling would otherwise expand your assessment surface across the whole platform.

How do I report comparable win rates across CPV and NAICS work?

Through a versioned crosswalk owned by capture operations, with the rationale recorded per mapping, plus explicit value and date definitions published alongside the dashboard. Keep pipeline (notice feeds) and outcomes (official award reporting) in separate metrics.

What breaks first when I add a jurisdiction?

Classification mapping, every time. The adapter works, the notices land, and then half of them carry a CPV code nobody has mapped to a service line, so they fall out of every report.

Which go/no-go inputs change when you bid outside the US?

Two of them. Award criteria and weightings are typically stated in the UK notice itself [3], so a scoring model can read weightings directly instead of inferring them from solicitation sections. On the EU side, eligibility runs through standardized self-declarations with national evidence equivalents locatable through eCertis [11], which makes evidence availability a gate rather than an afterthought. Both belong in the rule pack feeding your go/no-go decision framework, not hard-coded into the scoring engine.

How do I handle FAR overhaul deviation signals at intake?

Capture them as an intake field. When a solicitation references deviation or revised part text, flag the pursuit and route it to a reviewer who confirms which version governs, then check the citation register against current text on Acquisition.gov [12][13].

Your first two weeks

Week one: build the citation and notice-field register. One row per FAR or supplement citation, eForms field, and Find a Tender notice field your templates and automated checks depend on, each with an owner and a last-verified date. This is unglamorous and it is the artifact that prevents silent drift.

Metric to start tracking this week: parse-failure rate and unmapped-classification rate per adapter, reviewed by capture operations every Friday. Both are leading indicators. A rising unmapped rate means your crosswalk is aging; a rising parse-failure rate means a regime changed something.

Collection was never the hard part, and it is even less so now that all three regimes publish structured notices [2][3][6]. The win is normalization discipline. If you are a product or capture lead deciding what to do Monday, do this: write down your canonical opportunity object's required core fields, get a capture lead and an engineer to sign off on the definition of `value.basis`, and refuse to build the second adapter until that document exists.

References