Agent-native public procurement intelligence API (Spain: TED/PLACSP award, buyer, competitor and renewal intelligence)
licita-agent demonstrates solid tool design with consistent naming (verb_noun pattern), comprehensive parameter schemas, and detailed descriptions. All 10 tools follow action-verb conventions (search_, get_, research). Schemas are well-formed with type constraints, enums, and validation rules. Descriptions average ~180 chars, meeting the 10-1024 char baseline. However, output schemas are not explicitly documented in the source code, only input schemas are visible. Error handling is present but generic (no recovery guidance in tool descriptions). Payment token parameters appear across all tools but lack security context in descriptions. Tool composition is sound: search_tenders chains to get_tender/get_company/get_buyer; get_company chains to get_company_awards/get_company_opportunities. Pagination is properly implemented (page, size params with defaults and limits).
Buyer profile by id: name, country, org type, plus aggregate stats (total awards, top suppliers, concentration, recurrence metrics).
Buyer's award history: all awards issued, with winners, CPVs, dates, and values. Paginated.
Company profile by id: name, country, NIF, aliases and source identifiers (cross-source identity), plus aggregate stats (wins, total awarded value, top CPVs, top buyers).
All awards won by a company: tender id, buyer, CPV, award date, value, and contract lifecycle (start/end dates, renewal window).
Upcoming renewal opportunities for a company: contracts ending soon, with buyer, CPV, estimated value, and renewal window dates.
Pricing information: returns the current pricing structure for all endpoints, including per-call costs and bundle options.
Renewal forecast: contracts ending soon across all buyers, with incumbent winner, CPV, estimated value, confidence score, and renewal window. Filters: cpv, buyer, company, region, from/to dates.
Output schemas not documented in source code. Tool descriptions state what is returned (e.g., 'Full tender detail by id: buyer, CPVs, deadline...') but formal output schema definitions are absent. LLMs cannot reliably extract fields or plan downstream calls without documented return types.
payment_token parameter lacks security context. Appears in all 10 tools as optional string but descriptions do not explain it is a payment proof (x402 standard), how to obtain it, or that it should never be logged. This risks token leakage into traces.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | <=2025-11-25 | v2 |
Full tender detail by id: buyer, CPVs, deadline, estimated value, all awards/lots with winners, plus provenance (source + TED url).
Research endpoint: accepts a structured research request (buyer, cpv, company, region filters) and returns aggregated intelligence (market size, top suppliers, concentration, trends).
Search Spanish public-sector IT/software/cyber procurement: awards, tenders and contracts. Filters: q (full-text), cpv (prefix), buyer, company, region (NUTS), from/to (YYYY-MM-DD), type=award|tender|contract. Returns compact rows with ids for the other tools.
Error handling guidance missing from tool descriptions. No recovery hints (e.g., 'If tender not found, try search_tenders() first'). LLMs cannot self-correct on failures without explicit guidance.
research tool description is vague. States 'aggregated intelligence (market size, top suppliers, concentration, trends)' but does not clarify what filters are required vs optional, or what the output structure contains. Ambiguous for LLM selection.
get_pricing tool lacks context. Description only states 'returns the current pricing structure' but does not explain when an LLM should call it (e.g., before expensive searches) or what the response format is.