{"openapi":"3.1.0","info":{"title":"Tindreal API","version":"1.0.0","summary":"Veřejné inzeráty, zápis přes API klíč, webhooky a odměny pro ověřené profesionály.","description":"REST API realitního portálu Tindreal. Pole a číselníky inzerátů odpovídají importnímu rozhraní Sreality 3.0.0. Odměny za přivedení kupce se nikdy nevracejí ve veřejných odpovědích – jen na `/v1/pro/rewards` s JWT ověřeného profesionála. Import ve formátu Sreality (XML-RPC) je na `POST https://import.tindreal.cz/RPC2` (alias `/import/sreality/RPC2`; přístupy se vydávají v účtu, viz `docs/pro-dodavatele-softwaru.md`). Tindreal na Sreality neexportuje. Pro AI agenty existuje vzdálený MCP server (Model Context Protocol, Streamable HTTP) na https://mcp.tindreal.cz/mcp – stejná data, OAuth 2.1 nebo API klíč; viz `externalDocs`.","license":{"name":"Proprietary"}},"servers":[{"url":"https://api.tindreal.cz"}],"externalDocs":{"description":"Tindreal MCP server pro AI agenty (endpoint https://mcp.tindreal.cz/mcp, manifest /.well-known/oauth-protected-resource)","url":"https://mcp.tindreal.cz/llms.txt"},"tags":[{"name":"Inzeráty","description":"Veřejné čtení a zápis inzerátů"},{"name":"Číselníky"},{"name":"Odměny","description":"Jen pro ověřené profesionály (JWT)"},{"name":"Účet","description":"Žádost o ověření profesionála, nárok na odměnu (JWT uživatele)"},{"name":"Sdílení provize","description":"Makléř přenechává část odměny poradci nebo soukromníkovi (JWT). Tindreal podíl jen eviduje: nic nevyplácí a nic si nebere."},{"name":"Evidence přivedení","description":"Hlášení přivedených zájemců o koupi (JWT). Tindreal není stranou dohody o odměně a neprovádí platby."},{"name":"API klíče","description":"Správa vlastních API klíčů (JWT uživatele)"},{"name":"Import","description":"Přístupy pro realitní software (importní rozhraní kompatibilní se Sreality, `POST /RPC2`): vydání, rotace hesla, deaktivace, log"},{"name":"Administrace","description":"Jen administrátor (JWT, is_admin())"},{"name":"Webhooky"},{"name":"Feed"},{"name":"E-maily","description":"Odhlášení z nepovinných e-mailů (podepsaný token v odkazu, bez přihlášení)"}],"paths":{"/v1/listings":{"get":{"tags":["Inzeráty"],"operationId":"listListings","summary":"Výpis veřejných inzerátů","description":"Jen inzeráty ve stavu active/reserved. Výstup nikdy neobsahuje odměny. Stránkování: OFFSET (page, limit; max. 10 000 řádků, total je u velkých výsledků odhad) nebo KURZOR – z odpovědi vezměte next_cursor a pošlete ho jako ?cursor= se stejnými filtry a řazením (stálá cena na každé straně, bez total; podporují ho řazení newest, price_asc, price_desc). Veřejné GET odpovědi mají Cache-Control: public, s-maxage + stale-while-revalidate a ETag (If-None-Match → 304); požadavky s hlavičkou Authorization nebo X-API-Key se necachují (private, no-store). Výchozí řazení newest už nepreferuje topované inzeráty – chcete-li je napřed, použijte sort=promoted (jen OFFSET).","parameters":[{"name":"advert_function","in":"query","required":false,"description":"1 Prodej, 2 Pronájem, 3 Dražby, 4 Podíly","schema":{"type":"integer","minimum":1,"maximum":4},"example":1},{"name":"advert_type","in":"query","required":false,"description":"1 Byty, 2 Domy, 3 Pozemky, 4 Komerční, 5 Ostatní","schema":{"type":"integer","minimum":1,"maximum":5},"example":1},{"name":"advert_subtype","in":"query","required":false,"description":"Podkategorie (viz /v1/codebooks), např. 4 = 2+kk","schema":{"type":"integer"},"example":4},{"name":"country","in":"query","required":false,"description":"Země (ISO 3166-1 alpha-2), např. CZ, SK","schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"example":"CZ"},{"name":"city","in":"query","required":false,"description":"Město (částečná shoda, bez ohledu na velikost písmen)","schema":{"type":"string","maxLength":100},"example":"Praha"},{"name":"price_min","in":"query","required":false,"description":"Minimální cena","schema":{"type":"number","minimum":0},"example":2000000},{"name":"price_max","in":"query","required":false,"description":"Maximální cena","schema":{"type":"number","minimum":0},"example":6000000},{"name":"area_min","in":"query","required":false,"description":"Minimální plocha (užitná nebo pozemku) v m²","schema":{"type":"number","minimum":0},"example":40},{"name":"area_max","in":"query","required":false,"description":"Maximální plocha v m²","schema":{"type":"number","minimum":0},"example":90},{"name":"q","in":"query","required":false,"description":"Fulltext (titulek, popis, lokalita; bez diakritiky)","schema":{"type":"string","maxLength":200},"example":"balkon metro"},{"name":"sort","in":"query","required":false,"description":"Řazení (newest = published_at sestupně)","schema":{"type":"string","enum":["newest","price_asc","price_desc","area_desc","promoted"],"default":"newest"}},{"name":"page","in":"query","required":false,"description":"Stránka (OFFSET; ignoruje se s cursor)","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Počet na stránku (max. 100)","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","required":false,"description":"Kurzor next_cursor z předchozí odpovědi (stejné filtry a řazení)","schema":{"type":"string","maxLength":300}}],"responses":{"200":{"description":"Stránka inzerátů","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingPage"},"examples":{"praha":{"summary":"Byty v Praze","value":{"items":[{"public_id":1042,"title":"Prodej bytu 2+kk 54 m², Praha","status":"active","advert_function":1,"advert_type":1,"advert_subtype":4,"advert_price":5990000,"advert_price_currency":1,"advert_price_unit":1,"usable_area":54,"locality_city":"Praha","main_photo_url":null,"is_highlighted":false,"is_topped":false}],"page":1,"limit":20,"total":1}}}}}},"304":{"description":"Beze změny (If-None-Match odpovídá ETagu)"},"400":{"description":"Neplatné parametry dotazu (invalid_query), neplatný kurzor (invalid_cursor) nebo příliš hluboký OFFSET (offset_too_large)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Inzeráty"],"operationId":"createListing","summary":"Vytvoření inzerátu","description":"Vyžaduje API klíč se scope `listings:write`. Povinná pole se řídí kategorií (viz Sreality 3.0.0). Nepovinná `reward` zakládá odměnu za přivedení kupce (viditelnou jen vlastníkovi, adminům a ověřeným profesionálům). Neznámá pole se uloží do `sreality_attrs`.","security":[{"ApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingInput"},"examples":{"byt":{"summary":"Byt 2+kk s odměnou","value":{"advert_function":1,"advert_type":1,"advert_subtype":4,"advert_lifetime":3,"advert_price":5990000,"advert_price_currency":1,"advert_price_unit":1,"description":"Světlý byt po rekonstrukci, 5 minut od metra.","locality_city":"Praha","locality_street":"Radlická","locality_inaccuracy_level":2,"usable_area":54,"balcony":true,"loggia":false,"terrace":false,"floor_number":3,"ownership":1,"building_condition":9,"building_type":2,"cellar":true,"garage":false,"parking_lots":false,"reward":{"reward_type":"percent","percent":1.5,"payout_trigger":"cadastre_entry","payout_conditions":"Výplata do 14 dnů od vkladu do katastru.","allow_sharing":false}}}}}}},"responses":{"201":{"description":"Vytvořeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"},"example":{"id":"3f0c1d2e-5a6b-4c7d-8e9f-0a1b2c3d4e5f","public_id":1042,"status":"active"}}}},"401":{"description":"Chybí nebo je neplatný API klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Klíč nemá scope listings:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Chybí/neplatná pole (seznam v `issues`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Neplatná pole: locality_city","issues":[{"field":"locality_city","kind":"missing","message":"Pole locality_city je povinné."}]}}}}}}}},"/v1/listings/{public_id}":{"parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"integer"},"example":1042}],"get":{"tags":["Inzeráty"],"operationId":"getListing","summary":"Detail veřejného inzerátu (včetně fotek)","responses":{"200":{"description":"Inzerát","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicListing"}}}},"404":{"description":"Inzerát nenalezen nebo není veřejný","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Inzeráty"],"operationId":"updateListing","summary":"Částečná úprava inzerátu","description":"Mění se jen poslaná pole. `reward: null` odměnu smaže, objekt ji nahradí. Cizí inzerát nelze měnit (403).","security":[{"ApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingInput"},"example":{"advert_price":5790000}}}},"responses":{"200":{"description":"Upraveno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"401":{"description":"API klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Cizí inzerát / chybí scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná pole","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Inzeráty"],"operationId":"deleteListing","summary":"Smazání inzerátu (soft delete)","security":[{"ApiKey":[]}],"responses":{"204":{"description":"Smazáno"},"401":{"description":"API klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Cizí inzerát / chybí scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/codebooks":{"get":{"tags":["Číselníky"],"operationId":"getCodebooks","summary":"Číselníky (shodné se Sreality)","responses":{"200":{"description":"Všechny číselníky podle názvu pole","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codebooks"},"example":{"codebooks":{"advert_function":[{"code":1,"label":"Prodej"},{"code":2,"label":"Pronájem"}],"advert_subtype":[{"code":4,"label":"2+kk","advert_type":1}]}}}}}}}},"/v1/pro/rewards":{"get":{"tags":["Odměny"],"operationId":"listRewards","summary":"Odměny za přivedení kupce (jen ověření profesionálové)","description":"Dotaz jde do databáze s JWT uživatele, takže o výsledku rozhoduje RLS (`is_verified_professional()`). Neověřený uživatel dostane prázdný seznam.","security":[{"BearerJwt":[]}],"parameters":[{"name":"page","in":"query","required":false,"description":"Stránka","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Počet na stránku","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Stránka odměn","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardPage"}}}},"401":{"description":"Chybí nebo je neplatný JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/pro/rewards/{public_id}":{"parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"integer"},"description":"public_id inzerátu","example":1042}],"get":{"tags":["Odměny"],"operationId":"getReward","summary":"Odměna k inzerátu","security":[{"BearerJwt":[]}],"responses":{"200":{"description":"Odměna","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuyerReward"},"example":{"listing_public_id":1042,"reward_type":"percent","amount":null,"currency":1,"percent":1.5,"percent_base":"final_price","payout_trigger":"cadastre_entry","payout_conditions":"Výplata do 14 dnů od vkladu do katastru.","eligible_kinds":["real_estate_broker","financial_advisor"],"allow_sharing":false,"valid_until":null}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Odměna neexistuje nebo k ní nemáte přístup","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/webhooks":{"post":{"tags":["Webhooky"],"operationId":"createWebhook","summary":"Registrace webhooku","description":"Scope `webhooks:manage`. Cíl musí být veřejná adresa https. Odpověď obsahuje `secret` (jen jednou) pro ověření podpisu `X-Tindreal-Signature: t=<unix>,v1=<hex>` = HMAC-SHA256(secret, \"<t>.<tělo>\"). Secret je na serveru uložen jen zašifrovaný a nelze ho znovu zobrazit – při ztrátě webhook smažte a založte znovu.","security":[{"ApiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookInput"},"example":{"url":"https://example.cz/hooks/tindreal","event_types":["listing.created","listing.price_changed"],"filters":{"advert_type":1,"city":"Praha","price_max":6000000}}}}},"responses":{"201":{"description":"Vytvořeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"description":"API klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limit webhooků","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Webhooky jsou dočasně nedostupné (chybí konfigurace šifrování secretu na serveru)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Webhooky"],"operationId":"listWebhooks","summary":"Moje webhooky","security":[{"ApiKey":[]}],"responses":{"200":{"description":"Seznam","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"401":{"description":"API klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/webhooks/{id}":{"delete":{"tags":["Webhooky"],"operationId":"deleteWebhook","summary":"Smazání webhooku","security":[{"ApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Smazáno"},"401":{"description":"API klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/verifications":{"get":{"tags":["Účet"],"operationId":"listMyVerifications","summary":"Moje žádosti o ověření profesionála","security":[{"BearerJwt":[]}],"responses":{"200":{"description":"Žádosti uživatele (RLS)","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Verification"}}}}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Účet"],"operationId":"createMyVerification","summary":"Podání žádosti o ověření (+ automatická kontrola ARES/ČNB)","security":[{"BearerJwt":[]}],"description":"Žádost vzniká vždy jako `pending` (zápis s JWT uživatele přes RLS). Worker hned po vytvoření spustí kontrolu ARES + ČNB (service role, security definer funkce) a stav změní na `auto_checked`; je to jen PODKLAD pro administrátora – schválení provádí vždy člověk. Při selhání kontroly zůstane `pending` (`check_ran: false`).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationInput"}}}},"responses":{"201":{"description":"Vytvořeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"409":{"description":"Již existuje otevřená žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/verifications/{id}":{"get":{"tags":["Účet"],"operationId":"getMyVerification","summary":"Detail žádosti vč. výsledků kontrol","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/verifications/{id}/check":{"post":{"tags":["Účet"],"operationId":"rerunMyCheck","summary":"Znovu spustit automatickou kontrolu (max. 1× za 5 min)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Aktualizovaná žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Žádost je již rozhodnuta","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Příliš časté","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/verifications/{id}/renew":{"post":{"tags":["Účet"],"operationId":"renewMyVerification","summary":"Žádost o obnovení ověření (předvyplněná z původní žádosti)","security":[{"BearerJwt":[]}],"description":"Ověření platí 12 měsíců (`valid_until`). Obnovit lze vypršené ověření (`expired`) nebo schválené, kterému končí platnost do 30 dnů. Vznikne nová žádost (`pending`) s převzatým typem, IČO, IČO partnera a evid. číslem ČNB; Worker znovu spustí kontrolu ARES + ČNB a **znovu schvaluje administrátor**. Do rozhodnutí zůstává dosavadní ověření v platnosti (do `valid_until`).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID původní (schválené / vypršelé) žádosti"}],"responses":{"201":{"description":"Nová žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Obnovu zatím nelze podat (platnost delší než 30 dní / už existuje rozpracovaná žádost)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-eligibility":{"get":{"tags":["Účet"],"operationId":"getRewardEligibility","summary":"Smím vidět odměny / uplatnit nárok? (s důvodem)","security":[{"BearerJwt":[]}],"description":"Vidět odměny = schválené ověření. Uplatnit nárok (evidovat přivedení) = pravidlo `reward_eligibility` v `platform_settings` (SQL `can_claim_reward`).","responses":{"200":{"description":"Stav nároku","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardEligibility"}}}}}}},"/v1/me/api-keys":{"get":{"tags":["API klíče"],"operationId":"listMyApiKeys","summary":"Moje API klíče (bez hashe)","security":[{"BearerJwt":[]}],"responses":{"200":{"description":"Klíče","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyInfo"}},"max_active":{"type":"integer"}}}}}}}},"post":{"tags":["API klíče"],"operationId":"createMyApiKey","summary":"Vytvoření API klíče (plný klíč se vrátí JEDINKRÁT)","security":[{"BearerJwt":[]}],"description":"Klíč `tr_live_` + 43 znaků base62 (≈256 bitů, crypto.getRandomValues). V DB je jen sha256 a prefix. Insert jde s JWT uživatele přes RLS. Max. 10 aktivních klíčů.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"type":"string","maxLength":80},"scopes":{"type":"array","items":{"type":"string","enum":["listings:read","listings:write","webhooks:manage","searches:manage"]}},"expires_in_days":{"type":"integer","minimum":1,"maximum":730,"description":"Platnost klíče ve dnech (výchozí 365, max. 2 roky). Po vypršení klíč přestane fungovat (401 api_key_expired); 14 dní předem přijde upozornění."}}}}}},"responses":{"201":{"description":"Vytvořeno","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiKeyInfo"},{"type":"object","properties":{"key":{"type":"string","description":"Plný klíč – zobrazí se jen jednou"}}}]}}}},"409":{"description":"Limit aktivních klíčů","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/api-keys/{id}/rotate":{"post":{"tags":["API klíče"],"operationId":"rotateMyApiKey","summary":"Rotace API klíče (starý se odvolá, nový se vrátí JEDINKRÁT)","security":[{"BearerJwt":[]}],"description":"V jedné transakci odvolá starý klíč a vytvoří nový se stejným názvem, oprávněními a organizací. Platnost nového: `expires_in_days` (výchozí 365, max. 730).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in_days":{"type":"integer","minimum":1,"maximum":730}}}}}},"responses":{"201":{"description":"Nový klíč","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiKeyInfo"},{"type":"object","properties":{"key":{"type":"string","description":"Plný klíč – zobrazí se jen jednou"}}}]}}}},"404":{"description":"Nenalezeno nebo již odvoláno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/api-keys/{id}/revoke":{"post":{"tags":["API klíče"],"operationId":"revokeMyApiKey","summary":"Odvolání API klíče (okamžitě, nevratně)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Odvolaný klíč","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyInfo"}}}},"404":{"description":"Nenalezeno nebo již odvoláno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/import-clients":{"get":{"tags":["Import"],"operationId":"listMyImportClients","summary":"Moje importní klienty (přístupy pro realitní software) + stav","security":[{"BearerJwt":[]}],"description":"Klienti organizací, jejichž jsem členem. Heslo se nikdy nevrací (v DB je jen md5). `listing_count` = inzeráty z importu, `published_count` = z toho zveřejněné.","responses":{"200":{"description":"Klienti","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ImportClient"}},"organizations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}}},"max_active":{"type":"integer"},"endpoint":{"type":"string"}}}}}}}},"post":{"tags":["Import"],"operationId":"createMyImportClient","summary":"Vydání přístupu: nový importní klient (heslo se vrátí JEDINKRÁT)","security":[{"BearerJwt":[]}],"description":"Do exportního softwaru (místo přístupu ke Sreality) se zadá `endpoint`, `client_id`, `password` a `software_key`. Heslo generuje Worker (24 znaků, ≈119 bitů), v DB je jen md5. `sandbox: true` = testovací klient, jehož inzeráty se nikdy nezveřejní. Max. 10 aktivních klientů na organizaci. Bez `organization_id` se použije jediná organizace uživatele (nebo se založí nová).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":80},"sandbox":{"type":"boolean"},"organization_id":{"type":"string","format":"uuid","nullable":true}}}}}},"responses":{"201":{"description":"Vytvořeno","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ImportClient"},{"type":"object","properties":{"endpoint":{"type":"string"},"password":{"type":"string","description":"Importní heslo – zobrazí se jen jednou"}}}]}}}},"403":{"description":"Cizí organizace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Limit aktivních klientů","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/import-clients/{id}/rotate-password":{"post":{"tags":["Import"],"operationId":"rotateImportClientPassword","summary":"Rotace importního hesla (nové heslo jednou; staré přestane platit)","security":[{"BearerJwt":[]}],"description":"Ukončí všechny relace klienta a zruší zámek po chybných přihlášeních.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"client_id"}],"responses":{"200":{"description":"Klient + nové heslo","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ImportClient"},{"type":"object","properties":{"endpoint":{"type":"string"},"password":{"type":"string"}}}]}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/import-clients/{id}/deactivate":{"post":{"tags":["Import"],"operationId":"deactivateImportClient","summary":"Deaktivace klienta (getHash/login vrací 415, relace končí)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Klient","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportClient"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/import-clients/{id}/activate":{"post":{"tags":["Import"],"operationId":"activateImportClient","summary":"Opětovná aktivace klienta","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Klient","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportClient"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Limit aktivních klientů","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/import-clients/{id}/log":{"get":{"tags":["Import"],"operationId":"listImportClientLog","summary":"Poslední importy klienta (metoda, status, rkid, zpráva)","security":[{"BearerJwt":[]}],"description":"Bez session_id, hesel a těl požadavků.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"Počet záznamů (výchozí 50)","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Záznamy (nejnovější první)","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"method":{"type":"string"},"status":{"type":"integer"},"advert_rkid":{"type":"string","nullable":true},"message":{"type":"string","nullable":true}}}}}}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/import-clients":{"get":{"tags":["Administrace"],"operationId":"adminListImportClients","summary":"Přehled všech importních klientů (jen admin)","security":[{"BearerJwt":[]}],"parameters":[{"name":"page","in":"query","required":false,"description":"Stránka","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"description":"Počet na stránku","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Stránka klientů","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ImportClient"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/text-reviews":{"get":{"tags":["Administrace"],"operationId":"adminListTextReviews","summary":"Fronta inzerátů ke kontrole textu (jen admin)","security":[{"BearerJwt":[]}],"description":"Inzeráty, jejichž titulek/popis (včetně překladů) obsahuje přesnou adresu nebo výši odměny. Inzeráty zůstávají zveřejněné; fronta je jen příznak. Viz `docs/moderace-textu.md`.","parameters":[{"name":"status","in":"query","required":false,"description":"Filtr stavu","schema":{"type":"string","enum":["pending","approved","rejected","all"],"default":"pending"}},{"name":"page","in":"query","required":false,"description":"Stránka","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"description":"Počet","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Stránka fronty","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TextReviewQueueItem"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/text-reviews/{id}/decision":{"post":{"tags":["Administrace"],"operationId":"adminDecideTextReview","summary":"Schválit / odmítnout text inzerátu (odmítnutí vyžaduje zdůvodnění)","security":[{"BearerJwt":[]}],"description":"Rozhodnutí platí pro aktuální text; po jeho změně jde inzerát znovu ke kontrole. Neskrývá ani nemění inzerát. Zapisuje se do `audit_log`; vlastník vidí stav a zdůvodnění (`text_review`).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"public_id inzerátu"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["decision"],"properties":{"decision":{"type":"string","enum":["approved","rejected"]},"note":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"Nový stav","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextReviewInfo"}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Inzerát není ke kontrole","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Chybí zdůvodnění odmítnutí","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/verifications":{"get":{"tags":["Administrace"],"operationId":"adminListVerifications","summary":"Žádosti o ověření (jen admin)","security":[{"BearerJwt":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"Filtr stavu","schema":{"type":"string","enum":["pending","auto_checked","approved","rejected","revoked","expired"]}},{"name":"page","in":"query","required":false,"description":"Stránka","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"description":"Počet","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Stránka žádostí","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Verification"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/verifications/{id}":{"get":{"tags":["Administrace"],"operationId":"adminGetVerification","summary":"Detail žádosti + kandidáti na partnera (u poradce)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/verifications/{id}/decision":{"post":{"tags":["Administrace"],"operationId":"adminDecideVerification","summary":"Schválit / zamítnout / odvolat (povinná poznámka)","security":[{"BearerJwt":[]}],"description":"Rozhodnutí vždy dělá člověk. Zápis jde s JWT admina přes RLS; poznámka a přechody stavů se vynucují v DB a rozhodnutí se zapisuje do `audit_log`. Při schválení admin potvrzuje `has_rz_trade` (předvyplněno z ARES) a u poradce může přiřadit partnera (`partner_verification_id`). Povolené přechody: pending/auto_checked → approved/rejected; approved → revoked.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionInput"}}}},"responses":{"200":{"description":"Aktualizovaná žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Nepovolený přechod stavu","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Chybí poznámka / neplatný partner","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/verifications/{id}/check":{"post":{"tags":["Administrace"],"operationId":"adminRerunCheck","summary":"Znovu spustit kontrolu ARES + ČNB","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Aktualizovaná žádost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/cnb/refresh":{"post":{"tags":["Administrace"],"operationId":"adminRefreshCnb","summary":"Ručně spustit import registru ČNB (jen admin)","security":[{"BearerJwt":[]}],"description":"Stejná úloha jako denní cron (seznamy 3, 4, 5; idempotentní upsert, podezřele krátký soubor nic nesmaže). Nejvýše jednou za 10 minut (celkově). Spuštění se zapisuje do `audit_log`; při chybě se zařadí upozornění adminům.","responses":{"200":{"description":"Výsledek po seznamech (`ok: false`, pokud některý selhal; stará data zůstávají)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"list":{"type":"integer","enum":[3,4,5]},"loaded":{"type":"integer"},"removed":{"type":"integer"},"error":{"type":"string"}}}}}}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Import už před chvílí běžel (hlavička Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/unsubscribe":{"get":{"tags":["E-maily"],"operationId":"unsubscribePage","summary":"Stránka s potvrzením odhlášení z e-mailů (nic nemění)","security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"Podepsaný token z hlavičky List-Unsubscribe"}],"responses":{"200":{"description":"HTML s tlačítkem Odhlásit"},"400":{"description":"Neplatný token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Odhlášení není nakonfigurováno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["E-maily"],"operationId":"unsubscribe","summary":"Odhlášení z e-mailů hlídacích psů (RFC 8058 one-click)","security":[],"description":"Cíl hlavičky `List-Unsubscribe` (+ `List-Unsubscribe-Post: List-Unsubscribe=One-Click`). Idempotentní.","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Odhlášeno (HTML)"},"400":{"description":"Neplatný token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Odhlášení není nakonfigurováno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/partner-candidates":{"get":{"tags":["Administrace"],"operationId":"adminPartnerCandidates","summary":"Schválení makléři s živností RZ (kandidáti na partnera poradce)","security":[{"BearerJwt":[]}],"parameters":[{"name":"ico","in":"query","required":false,"description":"Filtr podle IČO","schema":{"type":"string"}}],"responses":{"200":{"description":"Kandidáti","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ico":{"type":"string"},"name":{"type":["string","null"]}}}}}}}}}}}},"/v1/admin/settings/reward-eligibility":{"get":{"tags":["Administrace"],"operationId":"adminGetEligibilitySettings","summary":"Pravidlo nároku na odměnu","security":[{"BearerJwt":[]}],"responses":{"200":{"description":"Nastavení","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardEligibilitySettings"}}}}}},"put":{"tags":["Administrace"],"operationId":"adminPutEligibilitySettings","summary":"Změna pravidla nároku (jen admin, audituje se)","security":[{"BearerJwt":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardEligibilitySettings"}}}},"responses":{"200":{"description":"Uloženo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardEligibilitySettings"}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná hodnota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/listings":{"get":{"tags":["Inzeráty"],"operationId":"listMyListings","summary":"Moje inzeráty (vlastní + inzeráty organizací, které spravuji)","security":[{"BearerJwt":[]}],"description":"Stránkovaný seznam inzerátů, které smí přihlášený uživatel spravovat (`can_manage_listing`): titulek, stav (draft/active/reserved/sold/expired), platnost (`expires_at`), počet fotek, odměna (aktivní/neaktivní, částka nebo %) a počty hlášení zájemců podle stavu. Cizí inzeráty se nevracejí ani když jsou veřejné. Odměnu vidí jen správce inzerátu (RLS).","parameters":[{"name":"status","in":"query","required":false,"description":"Filtr podle stavu inzerátu","schema":{"type":"string","enum":["draft","active","reserved","sold","expired"]}},{"name":"page","in":"query","required":false,"description":"Stránka","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Počet na stránku (max. 100)","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Stránka inzerátů, nejnovější změna první","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyListingPage"}}}},"400":{"description":"Neplatné parametry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Inzeráty"],"operationId":"createMyListing","summary":"Založení inzerátu přihlášeným uživatelem (JWT místo API klíče)","security":[{"BearerJwt":[]}],"description":"Totéž tělo a stejná validace jako `POST /v1/listings` (sdílené schéma, povinné položky podle kategorie), ale vlastníkem je přihlášený uživatel a zápis jde s jeho JWT přes RLS. Volitelné pole `reward` (pevná částka nebo %, podmínky výplaty, platnost `valid_until`). Fotky se nahrávají zvlášť na `/v1/me/listings/{id}/photos`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingInput"}}}},"responses":{"201":{"description":"Vytvořeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná pole","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/listings/{id}/photos":{"post":{"tags":["Inzeráty"],"operationId":"uploadMyListingPhoto","summary":"Nahrání fotky k vlastnímu inzerátu (bucket listing-photos)","security":[{"BearerJwt":[]}],"description":"Tělo = bajty obrázku (JPEG/PNG/GIF, formát se pozná podle obsahu a deklarovaný Content-Type mu musí odpovídat), max. 15 MB (limit platí i bez Content-Length), rozměry 480×360 až 12000×12000 px, duplicita dle sha256 (počítá se z očištěného souboru) se odmítne, max. 100 fotek. EXIF/XMP/IPTC (např. GPS) se z JPEG a PNG při uložení odstraní, zachová se jen orientace. První fotka je hlavní, jinak `?main=1`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"public_id inzerátu"},{"name":"main","in":"query","required":false,"description":"Nastavit jako hlavní","schema":{"type":"string","enum":["1"]}},{"name":"alt","in":"query","required":false,"description":"Alternativní text","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"image/gif":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"Uloženo","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"is_main":{"type":"boolean"},"width":{"type":"integer"},"height":{"type":"integer"}}}}}},"404":{"description":"Inzerát nenalezen / nespravujete","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicitní fotka / limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Příliš velký soubor","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Neplatný formát / Content-Type neodpovídá obsahu","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Rozlišení mimo 480×360 až 12000×12000 px","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/settings/reward-eligibility/preview":{"get":{"tags":["Administrace"],"operationId":"adminPreviewEligibilitySettings","summary":"Náhled dopadu změny pravidla nároku (nic se neukládá)","security":[{"BearerJwt":[]}],"description":"Spočítá, kolik aktuálně platně ověřených profesionálů by nárok na odměnu mělo / nemělo při navrženém nastavení a jak se to liší od současného stavu. Logika je v SQL společná se skutečným pravidlem.","parameters":[{"name":"require_rz_trade_for_brokers","in":"query","required":true,"schema":{"type":"boolean"}},{"name":"advisor_mode","in":"query","required":true,"schema":{"type":"string","enum":["via_partner_broker","own_rz_trade_only","disabled","allowed"]}}],"responses":{"200":{"description":"Náhled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EligibilityPreview"}}}},"400":{"description":"Neplatné parametry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/admin/settings/reward-eligibility/history":{"get":{"tags":["Administrace"],"operationId":"adminEligibilitySettingsHistory","summary":"Historie změn pravidla nároku (z audit_log)","security":[{"BearerJwt":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Počet záznamů (výchozí 50)","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Změny, nejnovější první","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SettingsHistoryEntry"}}}}}}},"403":{"description":"Není admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/introductions":{"get":{"tags":["Evidence přivedení"],"operationId":"listMyIntroductions","summary":"Moje hlášení přivedených zájemců (jako profesionál) vč. historie","security":[{"BearerJwt":[]}],"responses":{"200":{"description":"Hlášení (RLS)","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Introduction"}}}}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Evidence přivedení"],"operationId":"createIntroduction","summary":"Nahlásit přivedeného zájemce (evidence s časovým razítkem)","security":[{"BearerJwt":[]}],"description":"Tindreal NENÍ stranou dohody o odměně a neprovádí platby – eviduje jen hlášení a jeho stav. Smí jen uživatel, který může uplatnit nárok (`GET /v1/me/reward-eligibility`). `buyer_reference` je pseudonym/interní reference – API odmítne zjevný e-mail a telefonní číslo. Prohlášení (`declarations`) je povinné a ukládá se s verzí textu a serverovým časem. Stejná reference téhož profesionála k témuž inzerátu se nesmí opakovat (409).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntroductionInput"}}}},"responses":{"201":{"description":"Vytvořeno (stav submitted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Introduction"}}}},"403":{"description":"Nemáte nárok na odměnu","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Inzerát/odměna neexistuje nebo ji nevidíte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicitní reference","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data / chybí prohlášení","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/listings/{id}/introductions":{"get":{"tags":["Evidence přivedení"],"operationId":"listListingIntroductions","summary":"Hlášení k mému inzerátu (jako prodávající) + počet hlášení","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"public_id inzerátu"}],"description":"Jen správce inzerátu (vlastník / člen organizace). Prodávající vidí pseudonymní referenci, ne osobní údaje kupujícího.","responses":{"200":{"description":"Hlášení","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Introduction"}}}}}}},"404":{"description":"Inzerát nenalezen nebo jej nespravujete","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/introductions/{id}/transition":{"post":{"tags":["Evidence přivedení"],"operationId":"transitionIntroduction","summary":"Změna stavu hlášení","security":[{"BearerJwt":[]}],"description":"Pravidla vynucuje databáze (trigger): profesionál smí `submitted → withdrawn`; prodávající `submitted → accepted|rejected`, `accepted → closed_won|closed_lost`, `closed_won → paid` (poznámka povinná: prodávající potvrzuje, že odměnu vyplatil MIMO Tindreal); admin může stav opravit s povinnou poznámkou. Každý přechod se zapisuje do historie a `audit_log`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to"],"properties":{"to":{"$ref":"#/components/schemas/IntroductionStatus"},"note":{"type":["string","null"],"maxLength":1000}}}}}},"responses":{"200":{"description":"Aktualizované hlášení","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Introduction"}}}},"403":{"description":"Přechod není pro vaši roli povolen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Hlášení neexistuje nebo ho nevidíte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Chybí povinná poznámka","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-share-code":{"get":{"tags":["Sdílení provize"],"operationId":"getRewardShareCode","summary":"Můj kód pro sdílení (vytvoří se při prvním dotazu)","security":[{"BearerJwt":[]}],"description":"Kód (12 znaků) dává příjemce podílu (poradce, soukromník) makléři. Makléř podle něj příjemce nalezne bez znalosti e-mailu; kód sám nezakládá žádné právo.","responses":{"200":{"description":"Kód","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","example":"A1B2C3D4E5F6"}}}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-share-code/rotate":{"post":{"tags":["Sdílení provize"],"operationId":"rotateRewardShareCode","summary":"Obnovit kód pro sdílení (starý přestane platit)","security":[{"BearerJwt":[]}],"responses":{"200":{"description":"Nový kód","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"}}}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-shares":{"get":{"tags":["Sdílení provize"],"operationId":"listMyRewardShares","summary":"Moje podíly z provize – odeslané (makléř) i přijaté (příjemce)","security":[{"BearerJwt":[]}],"description":"Příjemce (i soukromník) vidí jen své podíly: částku/procento, stav a veřejné údaje o nabídce, nikdy odměnu, katalog odměn ani přivedení. Telefon druhé strany vidí jen makléř.","responses":{"200":{"description":"Podíly (RLS)","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RewardShare"}}}}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Sdílení provize"],"operationId":"createRewardShare","summary":"Navrhnout podíl z provize (makléř)","security":[{"BearerJwt":[]}],"description":"Tindreal NENÍ stranou dohody, nic nevyplácí a nic si nebere – podíl jen eviduje. Smí jen ověřený makléř s nárokem na odměnu, který přivedení nahlásil. Příjemce se určuje kódem pro sdílení. Pravidla vynucuje databáze: 0 < procento ≤ 100, součet aktivních podílů k přivedení ≤ 100 %, pevná částka nepřesáhne pevnou odměnu, příjemce není vlastník/člen organizace inzerátu ani jiný makléř. Změna přijatého podílu = nový návrh, který příjemce znovu přijme. Podíl vstoupí v platnost až přijetím příjemce.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardShareInput"}}}},"responses":{"201":{"description":"Návrh (stav pending)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardShare"}}}},"403":{"description":"Nejste ověřený makléř s nárokem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Kód nebo přivedení nenalezeno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Příjemci už čeká jiný návrh","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Neplatná data / porušena pravidla","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-shares/{id}/accept":{"post":{"tags":["Sdílení provize"],"operationId":"acceptRewardShare","summary":"Přijmout podíl s prohlášením (příjemce)","security":[{"BearerJwt":[]}],"description":"Vyžaduje prohlášení verze `prohlaseni-v1` – část B pro poradce, část C pro soukromníka (všechna pole `true`). Server uloží verzi, část a svůj čas; IP adresa se neukládá.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["declarations"],"properties":{"declarations":{"$ref":"#/components/schemas/RewardShareDeclarations"},"note":{"type":["string","null"],"maxLength":500}}}}}},"responses":{"200":{"description":"Přijato","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardShare"}}}},"403":{"description":"Akce není ve stavu / pro vaši roli povolena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Podíl neexistuje nebo ho nevidíte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Chybí úplné prohlášení","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-shares/{id}/decline":{"post":{"tags":["Sdílení provize"],"operationId":"declineRewardShare","summary":"Odmítnout podíl (příjemce)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":["string","null"],"maxLength":500}}}}}},"responses":{"200":{"description":"Odmítnuto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardShare"}}}},"403":{"description":"Akce není povolena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Podíl nenalezen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-shares/{id}/withdraw":{"post":{"tags":["Sdílení provize"],"operationId":"withdrawRewardShare","summary":"Stáhnout nepřijatý návrh (makléř)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":["string","null"],"maxLength":500}}}}}},"responses":{"200":{"description":"Staženo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardShare"}}}},"403":{"description":"Po přijetí nelze stáhnout – pošlete nový návrh","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Podíl nenalezen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/reward-shares/{id}":{"patch":{"tags":["Sdílení provize"],"operationId":"setRewardShareVisibility","summary":"Povolit/zakázat majiteli nabídky vidět podíl (makléř)","security":[{"BearerJwt":[]}],"description":"Výchozí je NE. Majitel nabídky/RK vidí podíl bez identity příjemce (jen druh příjemce, částku/procento a stav).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["visible_to_owner"],"properties":{"visible_to_owner":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Aktualizováno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardShare"}}}},"403":{"description":"Nejste odesílatel podílu","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Podíl nenalezen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/me/listings/{id}/reward-shares":{"get":{"tags":["Sdílení provize"],"operationId":"listListingRewardShares","summary":"Podíly povolené makléřem k mému inzerátu (majitel / RK)","security":[{"BearerJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"public_id inzerátu"}],"description":"Jen správce inzerátu a jen podíly, které makléř povolil. Bez identity příjemce (GDPR).","responses":{"200":{"description":"Podíly","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/OwnerRewardShare"}}}}}}},"401":{"description":"JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/feed.json":{"get":{"tags":["Feed"],"operationId":"feedJson","summary":"JSON Feed 1.1 posledních změn","responses":{"200":{"description":"JSON Feed","content":{"application/feed+json":{"schema":{"type":"object"}}}}}}},"/feed.xml":{"get":{"tags":["Feed"],"operationId":"feedXml","summary":"RSS 2.0 posledních změn","responses":{"200":{"description":"RSS","content":{"application/rss+xml":{"schema":{"type":"string"}}}}}}}},"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Klíč ve tvaru tr_live_<32 znaků>. V databázi je uložen jen jeho sha256."},"BearerJwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Supabase uživatelský JWT (access token)."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"validation_failed"},"message":{"type":"string","example":"Neplatná pole: locality_city"},"issues":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"kind":{"type":"string","enum":["missing","invalid"]},"message":{"type":"string"}}}}}}}},"WriteResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"public_id":{"type":"integer"},"status":{"type":"string","enum":["draft","active","reserved","sold","expired","deleted"]},"warnings":{"type":"array","description":"Jen když je co hlásit. Inzerát je uložený a zveřejněný beze změny; příznak se jen odešle ke kontrole (viz docs/moderace-textu.md).","items":{"$ref":"#/components/schemas/TextReviewWarning"}}}},"TextReviewWarning":{"type":"object","description":"Titulek nebo popis (v kterémkoli jazyce) obsahuje přesnou adresu nebo výši odměny.","properties":{"code":{"type":"string","enum":["text_needs_review"]},"reasons":{"type":"array","items":{"type":"string","enum":["exact_address","reward_amount"]},"description":"exact_address = č.p./č.o., RÚIAN, ulice s číslem, souřadnice (nebo název vlastní ulice u znepřesněné polohy); reward_amount = výše odměny/provize"},"message":{"type":"string"}}},"TextReviewInfo":{"type":"object","properties":{"status":{"type":"string","enum":["pending","approved","rejected"]},"reasons":{"type":"array","items":{"type":"string","enum":["exact_address","reward_amount"]}},"decision_note":{"type":["string","null"],"description":"Zdůvodnění odmítnutí od administrátora"}}},"TextReviewQueueItem":{"type":"object","description":"Inzerát ke kontrole textu (jen admin). Obsahuje plný text včetně překladů.","properties":{"public_id":{"type":"integer"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"locality_city":{"type":["string","null"]},"listing_status":{"type":"string"},"original_locale":{"type":["string","null"]},"owner_name":{"type":["string","null"]},"status":{"type":"string","enum":["pending","approved","rejected"]},"reasons":{"type":"array","items":{"type":"string","enum":["exact_address","reward_amount"]}},"detected_at":{"type":"string","format":"date-time"},"decided_at":{"type":["string","null"],"format":"date-time"},"decision_note":{"type":["string","null"]},"translations":{"type":"array","items":{"type":"object","properties":{"locale":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]}}}}}},"PublicListing":{"type":"object","description":"Veřejná podoba inzerátu. Neobsahuje odměny ani interní pole.","properties":{"public_id":{"type":"integer"},"title":{"type":["string","null"]},"status":{"type":"string","enum":["active","reserved"]},"advert_function":{"type":"integer"},"advert_type":{"type":"integer"},"advert_subtype":{"type":"integer"},"advert_room_count":{"type":["integer","null"]},"description":{"type":["string","null"],"maxLength":3000},"advert_price":{"type":["number","null"],"description":"0 nebo 1 = cena na dotaz"},"advert_price_currency":{"type":["integer","null"]},"advert_price_unit":{"type":["integer","null"]},"usable_area":{"type":["integer","null"]},"estate_area":{"type":["integer","null"]},"floor_area":{"type":["integer","null"]},"locality_city":{"type":["string","null"]},"locality_citypart":{"type":["string","null"]},"locality_street":{"type":["string","null"],"description":"Jen při přesné poloze (locality_inaccuracy_level = 1); při znepřesnění (2, 3) je vždy null – stejně jako číslo popisné/orientační, které API nikdy nevrací."},"locality_latitude":{"type":["number","null"],"description":"Vždy zaokrouhleno: úroveň 1 a 2 na 3 desetinná místa (≈ 100 m), úroveň 3 na 2 (≈ 1 km). Nezaokrouhlené souřadnice se nikdy nevracejí."},"locality_longitude":{"type":["number","null"]},"main_photo_url":{"type":["string","null"],"format":"uri","description":"Originál hlavní fotky"},"main_photo_variants":{"type":["object","null"],"description":"Varianty hlavní fotky (Cloudflare Images): thumb 320, card 640, detail 1280, full 1920 + srcset","properties":{"original":{"type":"string"},"thumb":{"type":"string"},"card":{"type":"string"},"detail":{"type":"string"},"full":{"type":"string"},"srcset":{"type":"string"}}},"country_code":{"type":"string","example":"CZ","description":"ISO 3166-1 alpha-2"},"original_locale":{"type":"string","example":"cs","description":"Jazyk titulku a popisu"},"published_at":{"type":["string","null"],"format":"date-time"},"is_highlighted":{"type":"boolean"},"is_topped":{"type":"boolean"},"translations":{"type":"object","description":"Jen v detailu: překlady titulku/popisu podle locale","additionalProperties":{"type":"object","properties":{"title":{"type":["string","null"]},"description":{"type":["string","null"]}}},"example":{"en":{"title":"Flat 2+kk, Prague","description":null}}},"photos":{"type":"array","description":"Jen v detailu","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"variants":{"type":"object"},"is_main":{"type":"boolean"},"sort_order":{"type":"integer"},"alt":{"type":["string","null"]}}}}},"additionalProperties":true},"MyListing":{"type":"object","description":"Inzerát, který uživatel spravuje, s přehledem odměny a hlášení zájemců.","properties":{"public_id":{"type":"integer"},"title":{"type":["string","null"]},"status":{"type":"string","enum":["draft","active","reserved","sold","expired"]},"advert_function":{"type":"integer"},"advert_type":{"type":"integer"},"advert_subtype":{"type":"integer"},"advert_price":{"type":["number","null"]},"locality_city":{"type":["string","null"]},"published_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time","description":"Platnost inzerátu"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"is_owner":{"type":"boolean","description":"false = spravuji jako člen organizace"},"photo_count":{"type":"integer"},"text_review":{"description":"Inzerát je ke kontrole textu (přesná adresa / výše odměny ve volném textu); null = bez nálezu. Zveřejnění se tím nemění.","oneOf":[{"$ref":"#/components/schemas/TextReviewInfo"},{"type":"null"}]},"reward":{"type":["object","null"],"description":"Jen správce inzerátu; null = bez odměny","properties":{"active":{"type":"boolean"},"reward_type":{"type":"string","enum":["fixed","percent"]},"amount":{"type":["number","null"]},"percent":{"type":["number","null"]},"currency":{"type":"integer"},"valid_until":{"type":["string","null"],"format":"date"}}},"introductions":{"type":"object","description":"Počet hlášení zájemců podle stavu (jen nenulové)","additionalProperties":{"type":"integer"},"example":{"submitted":2,"accepted":1}}}},"MyListingPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MyListing"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}},"ListingPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PublicListing"}},"page":{"type":["integer","null"],"description":"null v kurzorovém režimu"},"limit":{"type":"integer"},"total":{"type":["integer","null"],"description":"Počet nalezených (u velkých výsledků odhad); null v kurzorovém režimu"},"next_cursor":{"type":["string","null"],"description":"Kurzor další strany; null = poslední strana (nebo řazení bez kurzoru)"},"has_more":{"type":"boolean"}}},"ListingInput":{"type":"object","description":"Pole dle Sreality advert_data (kódy z /v1/codebooks). Neznámá pole jdou do sreality_attrs.","properties":{"advert_function":{"type":"integer"},"advert_type":{"type":"integer"},"advert_subtype":{"type":"integer","description":"Musí patřit do advert_type"},"advert_lifetime":{"type":"integer","example":3},"advert_price":{"type":"number"},"advert_price_currency":{"type":"integer","enum":[1,2,3]},"advert_price_unit":{"type":"integer"},"description":{"type":"string","maxLength":3000},"locality_city":{"type":"string"},"locality_inaccuracy_level":{"type":"integer","enum":[1,2,3]},"title":{"type":"string","description":"Nepovinné; jinak se vygeneruje"},"status":{"type":"string","enum":["draft","active","reserved","sold"]},"reward":{"oneOf":[{"$ref":"#/components/schemas/RewardInput"},{"type":"null"}],"description":"Odměna za přivedení kupce; null = smazat (jen PATCH)"}},"required":["advert_function","advert_type","advert_subtype"],"additionalProperties":true},"RewardInput":{"type":"object","required":["reward_type","payout_trigger","payout_conditions"],"properties":{"reward_type":{"type":"string","enum":["fixed","percent"]},"amount":{"type":["number","null"],"description":"Pro fixed"},"percent":{"type":["number","null"],"description":"Pro percent, 0 < p ≤ 10"},"currency":{"type":"integer","enum":[1,2,3],"default":1},"payout_trigger":{"type":"string","enum":["reservation_contract","purchase_contract","cadastre_entry","purchase_price_paid","other"]},"payout_conditions":{"type":"string","maxLength":2000},"eligible_kinds":{"type":"array","items":{"type":"string","enum":["real_estate_broker","financial_advisor"]}},"allow_sharing":{"type":"boolean"},"valid_until":{"type":["string","null"],"format":"date"}}},"BuyerReward":{"type":"object","properties":{"listing_public_id":{"type":"integer"},"reward_type":{"type":"string"},"amount":{"type":["number","null"]},"currency":{"type":"integer"},"percent":{"type":["number","null"]},"percent_base":{"type":"string"},"payout_trigger":{"type":"string"},"payout_conditions":{"type":"string"},"eligible_kinds":{"type":"array","items":{"type":"string"}},"allow_sharing":{"type":"boolean"},"valid_until":{"type":["string","null"]}}},"RewardPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BuyerReward"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}},"Codebooks":{"type":"object","properties":{"codebooks":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"code":{"type":"integer"},"label":{"type":"string"},"advert_type":{"type":"integer"}}}}}}},"WebhookInput":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"type":"string","enum":["listing.created","listing.updated","listing.deleted","listing.price_changed"]}},"filters":{"type":"object","description":"Stejné filtry jako GET /v1/listings (advert_function, advert_type, advert_subtype, city, price_min, price_max, area_min, area_max, q)"}}},"Webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"event_types":{"type":"array","items":{"type":"string"}},"filters":{"type":"object"},"active":{"type":"boolean"},"needs_rotation":{"type":"boolean","description":"Jen ve výpisu: odběr vznikl před zavedením šifrování secretu a je deaktivován – smažte ho a založte znovu."},"created_at":{"type":"string","format":"date-time"}}},"VerificationInput":{"type":"object","required":["kind","ico"],"properties":{"kind":{"type":"string","enum":["real_estate_broker","financial_advisor"]},"ico":{"type":"string","example":"27682242","description":"8 číslic, kontrola mod 11"},"partner_ico":{"type":["string","null"],"description":"Jen poradce: IČO spolupracující realitní kanceláře/makléře"},"cnb_registry_id":{"type":["string","null"],"description":"Jen poradce: evidenční číslo ČNB (volitelné)"}}},"Verification":{"type":"object","description":"Žádost o ověření vč. výsledků automatických kontrol (podklad pro admina).","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"ico":{"type":"string"},"partner_ico":{"type":["string","null"]},"partner_verification_id":{"type":["string","null"]},"status":{"type":"string","enum":["pending","auto_checked","approved","rejected","revoked","expired"],"description":"`expired` nastavuje jen denní cron po uplynutí platnosti (12 měsíců)"},"checks":{"type":["object","null"],"description":"ares / cnb / partner_ares; každá s outcome ok|fail|unavailable|not_applicable"},"ares_active":{"type":["boolean","null"]},"ares_trade_ok":{"type":["boolean","null"],"description":"Automatický výsledek: aktivní živnost Realitní zprostředkování"},"has_rz_trade":{"type":["boolean","null"],"description":"Potvrzený příznak (předvyplní ARES, přepíše admin)"},"cnb_lists":{"type":["array","null"],"items":{"type":"integer"}},"review_note":{"type":["string","null"]},"valid_until":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"check_ran":{"type":"boolean"}}},"DecisionInput":{"type":"object","required":["decision","note"],"properties":{"decision":{"type":"string","enum":["approved","rejected","revoked"]},"note":{"type":"string","minLength":3,"maxLength":2000,"description":"Povinná poznámka"},"has_rz_trade":{"type":"boolean","description":"Povinné při schválení"},"partner_verification_id":{"type":["string","null"],"format":"uuid"}}},"RewardEligibility":{"type":"object","properties":{"can_view_rewards":{"type":"boolean"},"can_claim":{"type":"boolean"},"reason":{"type":"string","enum":["ok","not_verified","broker_needs_rz_trade","advisor_disabled","advisor_needs_own_rz_trade","advisor_needs_partner","kind_not_eligible"]},"message":{"type":"string"},"legal_ref":{"type":["string","null"]}}},"RewardEligibilitySettings":{"type":"object","required":["require_rz_trade_for_brokers","advisor_mode"],"properties":{"require_rz_trade_for_brokers":{"type":"boolean"},"advisor_mode":{"type":"string","enum":["via_partner_broker","own_rz_trade_only","disabled","allowed"]}}},"ImportClient":{"type":"object","description":"Importní klient (bez hesla)","properties":{"client_id":{"type":"integer"},"organization_id":{"type":"string","format":"uuid"},"organization_name":{"type":"string"},"name":{"type":"string"},"sandbox":{"type":"boolean","description":"Testovací klient – inzeráty se nezveřejní"},"software_key":{"type":"string"},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"last_login_at":{"type":"string","format":"date-time","nullable":true},"password_rotated_at":{"type":"string","format":"date-time"},"deactivated_at":{"type":"string","format":"date-time","nullable":true},"failed_logins":{"type":"integer"},"locked_until":{"type":"string","format":"date-time","nullable":true},"listing_count":{"type":"integer","description":"Inzeráty z importu (bez smazaných)"},"published_count":{"type":"integer","description":"Z toho zveřejněné"}}},"ApiKeyInfo":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"key_prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"expires_at":{"type":"string","format":"date-time","description":"Konec platnosti klíče"}}},"EligibilityPreview":{"type":"object","properties":{"total":{"type":"integer","description":"Platně ověření profesionálové (jedno ověření na uživatele)"},"current":{"type":"object","properties":{"can_claim":{"type":"integer"},"cannot_claim":{"type":"integer"}}},"proposed":{"type":"object","properties":{"can_claim":{"type":"integer"},"cannot_claim":{"type":"integer"}}},"gain":{"type":"integer","description":"Kolik profesionálů nárok nově získá"},"loss":{"type":"integer","description":"Kolik nárok ztratí"},"by_kind":{"type":"object"},"by_reason":{"type":"object","additionalProperties":{"type":"integer"}}}},"SettingsHistoryEntry":{"type":"object","properties":{"id":{"type":"integer"},"at":{"type":"string","format":"date-time"},"actor_user_id":{"type":["string","null"]},"actor_name":{"type":["string","null"]},"from":{"oneOf":[{"$ref":"#/components/schemas/RewardEligibilitySettings"},{"type":"null"}]},"to":{"$ref":"#/components/schemas/RewardEligibilitySettings"}}},"RewardShareStatus":{"type":"string","enum":["pending","accepted","declined","withdrawn","superseded","cancelled"]},"RewardShareInput":{"type":"object","required":["introduction_id","recipient_code","share_type"],"properties":{"introduction_id":{"type":"string","format":"uuid","description":"Moje hlášení přivedení (GET /v1/me/introductions)"},"recipient_code":{"type":"string","description":"Kód pro sdílení příjemce (12 znaků, pomlčky a mezery se ignorují)"},"share_type":{"type":"string","enum":["percent","fixed"]},"percent":{"type":["number","null"],"exclusiveMinimum":0,"maximum":100,"description":"% z odměny makléře (jen u share_type=percent)"},"amount":{"type":["number","null"],"exclusiveMinimum":0,"description":"Pevná částka (jen u share_type=fixed); nesmí přesáhnout pevnou odměnu"},"currency":{"type":"integer","minimum":1,"maximum":3,"description":"1 = Kč"},"visible_to_owner":{"type":"boolean","description":"Povolit majiteli nabídky vidět podíl (výchozí false)"},"note":{"type":["string","null"],"maxLength":500,"description":"Bez e-mailu a telefonu"}}},"RewardShareDeclarations":{"type":"object","required":["version"],"description":"Prohlášení `prohlaseni-v1`. Poradce (část B): not_buyer, no_reward_transfer, informed_client, tindreal_not_party. Soukromník (část C): not_buyer, occasional, paid_by_broker, self_taxed. Vše `true`.","additionalProperties":{"type":"boolean"},"properties":{"version":{"type":"string","const":"prohlaseni-v1"}}},"RewardShare":{"type":"object","description":"Podíl z pohledu přihlášeného uživatele. Příjemce nemá `introduction_id`, `buyer_reference` ani telefon makléře; telefon příjemce vidí jen makléř.","properties":{"id":{"type":"string","format":"uuid"},"my_role":{"type":"string","enum":["sender","recipient"]},"status":{"$ref":"#/components/schemas/RewardShareStatus"},"share_type":{"type":"string","enum":["percent","fixed"]},"percent":{"type":["number","null"]},"amount":{"type":["number","null"]},"currency":{"type":"integer"},"recipient_kind":{"type":"string","enum":["advisor","private"]},"visible_to_owner":{"type":"boolean"},"note":{"type":["string","null"]},"listing_public_id":{"type":"integer"},"listing_title":{"type":["string","null"]},"is_replacement":{"type":"boolean"},"declaration_version":{"type":["string","null"]},"declaration_part":{"type":["string","null"],"enum":["B","C",null]},"accepted_at":{"type":["string","null"],"format":"date-time"},"decided_at":{"type":["string","null"],"format":"date-time"},"last_note":{"type":["string","null"]},"last_actor_role":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"introduction_id":{"type":["string","null"],"format":"uuid"},"buyer_reference":{"type":["string","null"]},"counterparty_name":{"type":["string","null"]},"counterparty_phone":{"type":["string","null"]}}},"OwnerRewardShare":{"type":"object","description":"Podíl pro majitele nabídky – bez identity příjemce.","properties":{"id":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/RewardShareStatus"},"recipient_kind":{"type":"string","enum":["advisor","private"]},"share_type":{"type":"string","enum":["percent","fixed"]},"percent":{"type":["number","null"]},"amount":{"type":["number","null"]},"currency":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"decided_at":{"type":["string","null"],"format":"date-time"}}},"IntroductionStatus":{"type":"string","enum":["submitted","accepted","rejected","closed_won","closed_lost","paid","withdrawn"]},"IntroductionInput":{"type":"object","required":["listing_public_id","buyer_reference","declarations"],"properties":{"listing_public_id":{"type":"integer"},"buyer_reference":{"type":"string","minLength":2,"maxLength":80,"description":"Pseudonym/interní reference. NEVKLÁDEJTE jméno, telefon ani e-mail kupujícího."},"note":{"type":["string","null"],"maxLength":1000},"declarations":{"type":"object","required":["version","not_buyer","no_reward_transfer","informed_client","cashless_only"],"properties":{"version":{"type":"string","example":"2026-11-02","description":"Verze textu prohlášení (aktuální viz web)"},"not_buyer":{"type":"boolean","enum":[true]},"no_reward_transfer":{"type":"boolean","enum":[true]},"informed_client":{"type":"boolean","enum":[true]},"cashless_only":{"type":"boolean","enum":[true]}}}}},"IntroductionEvent":{"type":"object","properties":{"id":{"type":"integer"},"from_status":{"type":["string","null"]},"to_status":{"$ref":"#/components/schemas/IntroductionStatus"},"actor_role":{"type":"string","enum":["professional","seller","admin","system"]},"note":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}},"Introduction":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"listing_public_id":{"type":["integer","null"]},"buyer_reference":{"type":"string"},"note":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/IntroductionStatus"},"declarations":{"type":["object","null"]},"professional_snapshot":{"type":["object","null"],"description":"Kdo hlásil (jméno, typ, IČO profesionála) – ne údaje kupujícího"},"created_at":{"type":"string","format":"date-time"},"decided_at":{"type":["string","null"],"format":"date-time"},"events":{"type":"array","items":{"$ref":"#/components/schemas/IntroductionEvent"}}}},"WebhookCreated":{"allOf":[{"$ref":"#/components/schemas/Webhook"},{"type":"object","properties":{"secret":{"type":"string","description":"Zobrazí se jen jednou"}}}]}}}}