{"openapi":"3.1.0","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"TenderRadar API","version":"1.0.0","description":"REST-API van TenderRadar: doorzoek Belgische overheidsopdrachten, signalen uit besluiten en gunningen, en beheer\nde gegevens van je eigen werkruimte (bedrijfsprofiel, matches, pipeline, gevolgde aanbesteders en concurrenten).\n\nAuthenticatie met een persoonlijke API-sleutel: `Authorization: Bearer trk_...` (aan te maken op /developers).\nEen sleutel geeft enkel toegang tot de werkruimte waarvoor hij is aangemaakt. Scope `read` leest, scope `write`\nwijzigt pipeline, gevolgde items en (voor eigenaars en beheerders) het bedrijfsprofiel. API-toegang zit in het Team-plan.\n\nRate limit: 120 verzoeken per minuut per sleutel (per serverinstantie). Daarboven 429 met Retry-After.\nFouten: `{ \"error\": { \"code\": \"...\", \"message\": \"...\" } }`."},"servers":[{"url":"https://tenderradar-alpha.vercel.app/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Account","description":"Wie ben ik, werkruimte en plan"},{"name":"Inhoud","description":"Publieke inhoud: opdrachten, signalen, gunningen"},{"name":"Werkruimte","description":"Gegevens van je eigen werkruimte"}],"paths":{"/me":{"get":{"tags":["Account"],"operationId":"getMe","summary":"Gebruiker, werkruimte, plan en scopes","description":"Werkt ook zonder Team-plan (api_access is dan false). Leden worden zonder e-mailadres getoond.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/opportunities":{"get":{"tags":["Inhoud"],"operationId":"searchOpportunities","summary":"Open opdrachten zoeken","description":"Open opdrachten van e-Procurement en andere bronnen. Met een bedrijfsprofiel krijgt elk item score, relevant en reasons.","parameters":[{"name":"q","in":"query","required":false,"description":"Zoekterm in de titel of de naam van de aanbesteder.","schema":{"type":"string","maxLength":100}},{"name":"kind","in":"query","required":false,"description":"Soort: tender, permanent_call, concession, property, market_consultation of planned.","schema":{"type":"string","enum":["tender","permanent_call","concession","property","market_consultation","planned"]}},{"name":"source","in":"query","required":false,"description":"eproc = enkel e-Procurement, extern = enkel andere bronnen.","schema":{"type":"string","enum":["eproc","extern"]}},{"name":"cpv","in":"query","required":false,"description":"CPV-prefix, bv. 45 of 452332.","schema":{"type":"string","pattern":"^\\d{2,8}$"}},{"name":"nuts","in":"query","required":false,"description":"NUTS-prefix, bv. BE2 (Vlaanderen) of BE242. Beperkt tot e-Procurement.","schema":{"type":"string","pattern":"^BE[0-9A-Z]{0,3}$"}},{"name":"days","in":"query","required":false,"description":"Enkel met een deadline binnen dit aantal dagen.","schema":{"type":"integer","minimum":1,"maximum":365}},{"name":"sort","in":"query","required":false,"description":"Sortering: deadline (standaard), newest of score.","schema":{"type":"string","enum":["deadline","newest","score"]}},{"name":"relevant","in":"query","required":false,"description":"Enkel opdrachten die de minimumscore van het bedrijfsprofiel halen.","schema":{"type":"boolean"}},{"name":"include_hidden","in":"query","required":false,"description":"Ook opdrachten tonen die als niet relevant gemarkeerd zijn.","schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"description":"Paginanummer, vanaf 1.","schema":{"type":"integer","minimum":1,"maximum":10000}},{"name":"page_size","in":"query","required":false,"description":"Aantal resultaten per pagina (1 tot 100, standaard 50).","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityList"},"example":{"items":[{"key":"publications:59bd57c7-35e7-4ddb-a401-df9083637194","table":"publications","id":"59bd57c7-35e7-4ddb-a401-df9083637194","kind":"tender","source":"eproc","title":"Heraanleg van de dorpskern","buyer_name":"Gemeente Voorbeeld","organisation_id":5563,"municipality":null,"main_cpv":"45233000","cpv_codes":["45233000"],"nuts_codes":["BE242"],"natures":["WORKS"],"deadline":"2026-11-14T10:00:00+00:00","published_at":"2026-10-02","estimated_value":850000,"currency":"EUR","source_url":"https://www.publicprocurement.be/publication-workspaces/59bd57c7-35e7-4ddb-a401-df9083637194","app_url":"https://app.example.be/tenders/59bd57c7-35e7-4ddb-a401-df9083637194","score":78,"relevant":true,"reasons":["CPV 4523 in je profiel","Regio Vlaams-Brabant"],"pipeline_status":null}],"page":1,"page_size":50,"total":1,"has_next":false,"hidden":0,"personal":true,"eproc_only":false}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/opportunities/{table}/{id}":{"get":{"tags":["Inhoud"],"operationId":"getOpportunity","summary":"Details van een publicatie, bericht of besluit","parameters":[{"name":"table","in":"path","required":true,"schema":{"type":"string","enum":["publications","external_notices","decisions"]},"description":"Tabel van de record."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id van de record in die tabel."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/signals":{"get":{"tags":["Inhoud"],"operationId":"searchSignals","summary":"Signalen uit besluiten zoeken","description":"Besluiten die een opdracht aankondigen vóór de publicatie. Zonder Pro-plan beperkt tot de eerste 5 (limited: true).","parameters":[{"name":"q","in":"query","required":false,"description":"Zoekterm (volledige tekst van het besluit).","schema":{"type":"string","maxLength":200}},{"name":"kind","in":"query","required":false,"description":"signal (aankondiging van een opdracht, standaard), concession, property, market_consultation of all.","schema":{"type":"string","enum":["signal","concession","property","market_consultation","all"]}},{"name":"subtype","in":"query","required":false,"description":"Subtype van het besluit, bv. lastvoorwaarden.","schema":{"type":"string","maxLength":60,"pattern":"^[a-z_]+$"}},{"name":"buyer","in":"query","required":false,"description":"Naam van het bestuur of de gemeente.","schema":{"type":"string","maxLength":100}},{"name":"period_days","in":"query","required":false,"description":"Enkel besluiten van de laatste N dagen.","schema":{"type":"integer","minimum":1,"maximum":3650}},{"name":"min_value","in":"query","required":false,"description":"Minimale geraamde waarde in euro.","schema":{"type":"number","minimum":0}},{"name":"page","in":"query","required":false,"description":"Paginanummer, vanaf 1.","schema":{"type":"integer","minimum":1,"maximum":10000}},{"name":"page_size","in":"query","required":false,"description":"Aantal resultaten per pagina (1 tot 100, standaard 50).","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/awards":{"get":{"tags":["Inhoud"],"operationId":"searchAwards","summary":"Gunningen zoeken","parameters":[{"name":"winner","in":"query","required":false,"description":"Winnaar: naam of KBO-nummer.","schema":{"type":"string","maxLength":100}},{"name":"buyer","in":"query","required":false,"description":"Aanbesteder: naam, KBO-nummer of organisatie-id.","schema":{"type":"string","maxLength":100}},{"name":"cpv","in":"query","required":false,"description":"CPV-prefix (minstens 2 cijfers).","schema":{"type":"string","pattern":"^\\d{2,8}$"}},{"name":"since","in":"query","required":false,"description":"Gunningsdatum vanaf (JJJJ-MM-DD).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"until","in":"query","required":false,"description":"Gunningsdatum tot en met (JJJJ-MM-DD).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"source","in":"query","required":false,"description":"Bron: ted, lblod, brussels_opendata_awards, decisions, ...","schema":{"type":"string","maxLength":60,"pattern":"^[a-z_:]+$"}},{"name":"min_value","in":"query","required":false,"description":"Minimale gunningswaarde in euro.","schema":{"type":"number","minimum":0}},{"name":"page","in":"query","required":false,"description":"Paginanummer, vanaf 1.","schema":{"type":"integer","minimum":1,"maximum":10000}},{"name":"page_size","in":"query","required":false,"description":"Aantal resultaten per pagina (1 tot 100, standaard 50).","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwardList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/matches":{"get":{"tags":["Werkruimte"],"operationId":"listMatches","summary":"Matches van het bedrijfsprofiel","parameters":[{"name":"group","in":"query","required":false,"description":"tenders, signals, concessions of consultations.","schema":{"type":"string","enum":["tenders","signals","concessions","consultations"]}},{"name":"min_score","in":"query","required":false,"description":"Minimale score (standaard die van het profiel).","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"sort","in":"query","required":false,"description":"Sortering: score (standaard), deadline of newest.","schema":{"type":"string","enum":["score","deadline","newest"]}},{"name":"page","in":"query","required":false,"description":"Paginanummer, vanaf 1.","schema":{"type":"integer","minimum":1,"maximum":10000}},{"name":"page_size","in":"query","required":false,"description":"Aantal resultaten per pagina (1 tot 100, standaard 50).","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"description":"De werkruimte heeft nog geen bedrijfsprofiel (code no_profile).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/profile":{"get":{"tags":["Werkruimte"],"operationId":"getProfile","summary":"Bedrijfsprofiel","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"put":{"tags":["Werkruimte"],"operationId":"updateProfile","summary":"Bedrijfsprofiel bijwerken","description":"Scope write en rol owner of admin. Velden die je weglaat blijven ongewijzigd. Naam en minstens een CPV-code of trefwoord zijn vereist.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Naam van het bedrijf."},"vat_number":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"description":"Btw-nummer."},"email":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Algemeen e-mailadres van het bedrijf."},"phone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}]},"website":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"contact_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"description":"Korte omschrijving van het bedrijf (gebruikt voor de matching)."},"cpv_codes":{"maxItems":100,"type":"array","items":{"type":"string","pattern":"^\\d{2}[\\d.]{0,9}(-\\d)?$"},"description":"CPV-prefixen of -codes waarop gematcht wordt."},"keywords":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"description":"Trefwoorden die een opdracht relevant maken."},"excluded_keywords":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"description":"Trefwoorden die een opdracht uitsluiten."},"nuts_codes":{"maxItems":50,"type":"array","items":{"type":"string","enum":["BE1","BE2","BE21","BE22","BE23","BE24","BE25","BE3","BE31","BE32","BE33","BE34","BE35"]},"description":"NUTS-regio's, bv. BE2 of BE242."},"natures":{"maxItems":3,"type":"array","items":{"type":"string","enum":["WORKS","SUPPLIES","SERVICES"]},"description":"WORKS, SUPPLIES en/of SERVICES."},"kinds":{"maxItems":10,"type":"array","items":{"type":"string","enum":["tender","signal","concession","property","market_consultation"]},"description":"Soorten naast gewone opdrachten: signal, concession, property, market_consultation."},"min_value":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Minimale geraamde waarde in euro."},"max_value":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Maximale geraamde waarde in euro."},"min_score":{"type":"integer","minimum":1,"maximum":100,"description":"Minimale score om als relevant te gelden (standaard 40)."},"rate_card":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"item":{"type":"string","maxLength":200},"unit":{"type":"string","maxLength":50},"unit_price":{"anyOf":[{"type":"number"},{"type":"string","maxLength":50}]}},"required":["item","unit","unit_price"],"additionalProperties":false},"description":"Prijslijst: item, eenheid, eenheidsprijs."},"references_list":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"client":{"type":"string","maxLength":200},"project":{"type":"string","maxLength":300},"year":{"type":"string","maxLength":10},"value":{"type":"string","maxLength":50}},"required":["client","project","year","value"],"additionalProperties":false},"description":"Referenties: opdrachtgever, project, jaar, waarde."}},"additionalProperties":false},"example":{"keywords":["wegenis","riolering"],"cpv_codes":["4523"],"nuts_codes":["BE24"],"min_score":50}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/pipeline":{"get":{"tags":["Werkruimte"],"operationId":"listPipeline","summary":"Pipeline van de werkruimte","parameters":[{"name":"status","in":"query","required":false,"description":"Enkel items met deze status.","schema":{"type":"string","enum":["interested","go","submitted","won","lost","no_go","dismissed"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/pipeline/{table}/{id}":{"parameters":[{"name":"table","in":"path","required":true,"schema":{"type":"string","enum":["publications","external_notices","decisions"]},"description":"Tabel van de record."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id van de record in die tabel."}],"put":{"tags":["Werkruimte"],"operationId":"setPipelineStatus","summary":"Record in de pipeline zetten of verplaatsen","description":"Scope write. Titel, aanbesteder, deadline en CPV worden uit de databank gehaald.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"additionalProperties":false,"properties":{"status":{"type":"string","enum":["interested","go","submitted","won","lost","no_go","dismissed"]}}},"example":{"status":"go"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineItemResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"tags":["Werkruimte"],"operationId":"setPipelineNote","summary":"Notitie van een pipeline-item bewaren","description":"Scope write. De record moet al in de pipeline staan.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["note"],"additionalProperties":false,"properties":{"note":{"type":["string","null"],"maxLength":2000}}},"example":{"note":"Plaatsbezoek op 20/11, offerte via Jan."}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineItemResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Werkruimte"],"operationId":"removeFromPipeline","summary":"Record uit de pipeline halen","responses":{"200":{"description":"Verwijderd","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"const":true},"key":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/follows":{"get":{"tags":["Werkruimte"],"operationId":"listFollows","summary":"Gevolgde aanbesteders en concurrenten","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Werkruimte"],"operationId":"follow","summary":"Aanbesteder of concurrent volgen","description":"Scope write. buyer: bestaand organisatie-id. competitor: KBO-nummer of name:<bedrijfsnaam>. 201 bij een nieuw item, 200 als het al gevolgd werd.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["buyer","competitor"],"description":"buyer (aanbesteder) of competitor (concurrent)."},"key":{"type":"string","minLength":1,"maxLength":300,"description":"buyer: organisatie-id (organisations.id). competitor: KBO-nummer of name:<bedrijfsnaam>."},"label":{"description":"Optioneel label; standaard de naam uit de databank.","type":"string","maxLength":200}},"required":["type","key"],"additionalProperties":false},"example":{"type":"competitor","key":"0207.437.468"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowResponse"}}}},"201":{"description":"Aangemaakt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Werkruimte"],"operationId":"unfollow","summary":"Niet meer volgen","parameters":[{"name":"type","in":"query","required":true,"description":"buyer (aanbesteder) of competitor (concurrent).","schema":{"type":"string","enum":["buyer","competitor"]}},{"name":"key","in":"query","required":true,"description":"buyer: organisatie-id (organisations.id). competitor: KBO-nummer of name:<bedrijfsnaam>.","schema":{"type":"string","minLength":1,"maxLength":300}}],"responses":{"200":{"description":"Verwijderd"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"trk_<8 hex>_<43 base64url>","description":"Persoonlijke API-sleutel van /developers. In de webapp werkt ook de sessiecookie."}},"responses":{"Unauthorized":{"description":"Geen of een ongeldige sleutel (codes unauthorized, invalid_token).","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"TenderRadar\""}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Ongeldige, ingetrokken of vervallen API-sleutel."}}}}},"Forbidden":{"description":"Scope, rol, plan of werkruimte laten dit niet toe (codes insufficient_scope, forbidden, plan_required, workspace_mismatch).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"Deze API-sleutel mag enkel lezen: de scope write ontbreekt."}}}}},"NotFound":{"description":"Niet gevonden.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UnsupportedMediaType":{"description":"Body is geen JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationFailed":{"description":"Ongeldige invoer (code validation_failed) met details per veld.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"De invoer is ongeldig.","details":[{"path":"page_size","message":"Too big: expected number to be <=100"}]}}}}},"RateLimited":{"description":"Te veel verzoeken.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconden tot een nieuw verzoek kan."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}},"Me":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid"},"authenticated_via":{"type":"string","enum":["api_key","session"]},"key_id":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string","enum":["read","write"]}},"workspace":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"]},"member_count":{"type":"integer"},"members":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"role":{"type":"string"},"joined_at":{"type":"string"},"is_you":{"type":"boolean"}}}}}},"plan":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"billing_enabled":{"type":"boolean"}}},"api_access":{"type":"boolean"},"features":{"type":"object","additionalProperties":{"type":"boolean"}},"links":{"type":"object","additionalProperties":{"type":"string"}}}},"Opportunity":{"type":"object","properties":{"key":{"type":"string","description":"table:id"},"table":{"type":"string","enum":["publications","external_notices","decisions"]},"id":{"type":"string"},"kind":{"type":"string"},"source":{"type":"string"},"title":{"type":"string"},"buyer_name":{"type":["string","null"]},"organisation_id":{"type":["integer","null"]},"municipality":{"type":["string","null"]},"main_cpv":{"type":["string","null"]},"cpv_codes":{"type":"array","items":{"type":"string"}},"nuts_codes":{"type":"array","items":{"type":"string"}},"natures":{"type":"array","items":{"type":"string"}},"deadline":{"type":["string","null"]},"published_at":{"type":["string","null"]},"estimated_value":{"type":["number","null"]},"currency":{"type":["string","null"]},"source_url":{"type":["string","null"],"description":"Bronrecord"},"app_url":{"type":"string","description":"Record in de webapp"},"score":{"type":"integer","description":"Enkel met een bedrijfsprofiel"},"relevant":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}},"pipeline_status":{"type":["string","null"],"enum":["interested","go","submitted","won","lost","no_go","dismissed",null]}},"example":{"key":"publications:59bd57c7-35e7-4ddb-a401-df9083637194","table":"publications","id":"59bd57c7-35e7-4ddb-a401-df9083637194","kind":"tender","source":"eproc","title":"Heraanleg van de dorpskern","buyer_name":"Gemeente Voorbeeld","organisation_id":5563,"municipality":null,"main_cpv":"45233000","cpv_codes":["45233000"],"nuts_codes":["BE242"],"natures":["WORKS"],"deadline":"2026-11-14T10:00:00+00:00","published_at":"2026-10-02","estimated_value":850000,"currency":"EUR","source_url":"https://www.publicprocurement.be/publication-workspaces/59bd57c7-35e7-4ddb-a401-df9083637194","app_url":"https://app.example.be/tenders/59bd57c7-35e7-4ddb-a401-df9083637194","score":78,"relevant":true,"reasons":["CPV 4523 in je profiel","Regio Vlaams-Brabant"],"pipeline_status":null}},"OpportunityList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Opportunity"}},"page":{"type":"integer","minimum":1},"page_size":{"type":"integer","minimum":1,"maximum":100},"total":{"type":["integer","null"],"description":"Totaal aantal resultaten (null als onbekend)."},"has_next":{"type":"boolean"},"hidden":{"type":"integer","description":"Aantal als niet relevant gemarkeerde items dat verborgen is."},"personal":{"type":"boolean"},"eproc_only":{"type":"boolean"}}},"OpportunityDetail":{"allOf":[{"$ref":"#/components/schemas/Opportunity"},{"type":"object","properties":{"description":{"type":["string","null"]},"details":{"type":"object","additionalProperties":true},"pipeline":{"oneOf":[{"$ref":"#/components/schemas/PipelineItem"},{"type":"null"}]},"buyer_followed":{"type":"boolean"}}}]},"Signal":{"allOf":[{"$ref":"#/components/schemas/Opportunity"},{"type":"object","properties":{"subtype":{"type":["string","null"]},"body":{"type":["string","null"]},"session_date":{"type":["string","null"]},"invited_firms":{"type":"array","items":{"type":"string"}}}}]},"SignalList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Signal"}},"page":{"type":"integer","minimum":1},"page_size":{"type":"integer","minimum":1,"maximum":100},"total":{"type":["integer","null"],"description":"Totaal aantal resultaten (null als onbekend)."},"has_next":{"type":"boolean"},"limited":{"type":"boolean"},"limit":{"type":"integer"}}},"Award":{"type":"object","properties":{"id":{"type":"integer"},"source":{"type":"string"},"title":{"type":["string","null"]},"decision_date":{"type":["string","null"]},"winner_name":{"type":["string","null"]},"winner_kbo":{"type":["string","null"]},"value":{"type":["number","null"]},"value_vat":{"type":["string","null"]},"currency":{"type":["string","null"]},"received_tenders":{"type":["integer","null"]},"buyer_name":{"type":["string","null"]},"buyer_kbo":{"type":["string","null"]},"organisation_id":{"type":["integer","null"]},"cpv_codes":{"type":"array","items":{"type":"string"}},"record_url":{"type":["string","null"]},"competitor_key":{"type":["string","null"],"description":"Sleutel om de winnaar te volgen"},"competitor_url":{"type":["string","null"]}}},"AwardList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Award"}},"page":{"type":"integer","minimum":1},"page_size":{"type":"integer","minimum":1,"maximum":100},"total":{"type":["integer","null"],"description":"Totaal aantal resultaten (null als onbekend)."},"has_next":{"type":"boolean"}}},"MatchList":{"type":"object","properties":{"profile":{"type":"string"},"min_score":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Opportunity"}},"page":{"type":"integer","minimum":1},"page_size":{"type":"integer","minimum":1,"maximum":100},"total":{"type":["integer","null"],"description":"Totaal aantal resultaten (null als onbekend)."},"has_next":{"type":"boolean"}}},"ProfileResponse":{"type":"object","properties":{"profile":{"oneOf":[{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Naam van het bedrijf."},"vat_number":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"description":"Btw-nummer."},"email":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Algemeen e-mailadres van het bedrijf."},"phone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}]},"website":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"contact_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"description":"Korte omschrijving van het bedrijf (gebruikt voor de matching)."},"cpv_codes":{"maxItems":100,"type":"array","items":{"type":"string","pattern":"^\\d{2}[\\d.]{0,9}(-\\d)?$"},"description":"CPV-prefixen of -codes waarop gematcht wordt."},"keywords":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"description":"Trefwoorden die een opdracht relevant maken."},"excluded_keywords":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"description":"Trefwoorden die een opdracht uitsluiten."},"nuts_codes":{"maxItems":50,"type":"array","items":{"type":"string","enum":["BE1","BE2","BE21","BE22","BE23","BE24","BE25","BE3","BE31","BE32","BE33","BE34","BE35"]},"description":"NUTS-regio's, bv. BE2 of BE242."},"natures":{"maxItems":3,"type":"array","items":{"type":"string","enum":["WORKS","SUPPLIES","SERVICES"]},"description":"WORKS, SUPPLIES en/of SERVICES."},"kinds":{"maxItems":10,"type":"array","items":{"type":"string","enum":["tender","signal","concession","property","market_consultation"]},"description":"Soorten naast gewone opdrachten: signal, concession, property, market_consultation."},"min_value":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Minimale geraamde waarde in euro."},"max_value":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Maximale geraamde waarde in euro."},"min_score":{"type":"integer","minimum":1,"maximum":100,"description":"Minimale score om als relevant te gelden (standaard 40)."},"rate_card":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"item":{"type":"string","maxLength":200},"unit":{"type":"string","maxLength":50},"unit_price":{"anyOf":[{"type":"number"},{"type":"string","maxLength":50}]}},"required":["item","unit","unit_price"],"additionalProperties":false},"description":"Prijslijst: item, eenheid, eenheidsprijs."},"references_list":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"client":{"type":"string","maxLength":200},"project":{"type":"string","maxLength":300},"year":{"type":"string","maxLength":10},"value":{"type":"string","maxLength":50}},"required":["client","project","year","value"],"additionalProperties":false},"description":"Referenties: opdrachtgever, project, jaar, waarde."}},"additionalProperties":false},{"type":"null"}]},"can_edit":{"type":"boolean"},"app_url":{"type":"string"}}},"PipelineItem":{"type":"object","properties":{"key":{"type":"string"},"table":{"type":"string","enum":["publications","external_notices","decisions"]},"id":{"type":"string"},"status":{"type":"string","enum":["interested","go","submitted","won","lost","no_go","dismissed"]},"title":{"type":"string"},"buyer_name":{"type":["string","null"]},"deadline":{"type":["string","null"]},"note":{"type":["string","null"]},"cpv_codes":{"type":"array","items":{"type":"string"}},"updated_at":{"type":"string"},"app_url":{"type":"string"}}},"PipelineList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PipelineItem"}},"total":{"type":"integer"},"app_url":{"type":"string"}}},"PipelineItemResponse":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/PipelineItem"}}},"Follow":{"type":"object","properties":{"type":{"type":"string","enum":["buyer","competitor"]},"key":{"type":"string"},"label":{"type":"string"},"added_at":{"type":"string"},"app_url":{"type":"string"}}},"FollowList":{"type":"object","properties":{"buyers":{"type":"array","items":{"$ref":"#/components/schemas/Follow"}},"competitors":{"type":"array","items":{"$ref":"#/components/schemas/Follow"}},"total":{"type":"integer"}}},"FollowResponse":{"type":"object","properties":{"created":{"type":"boolean"},"follow":{"$ref":"#/components/schemas/Follow"}}}}}}