Skip to main content
Glama

get_kik_document_markdown

Retrieve Public Procurement Authority (KİK) decision text in paginated Markdown format using a Base64 encoded KİK ID. Access detailed legal documents for analysis or integration into LLM applications.

Instructions

Get Public Procurement Authority (KİK) decision text in paginated Markdown format

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
karar_idYesThe Base64 encoded KIK decision identifier.
page_numberNoPage number for paginated Markdown content (1-indexed). Default is 1.

Implementation Reference

  • The core tool handler that fetches KIK document HTML via API and direct URL, encrypts document ID if numeric, and converts HTML to Markdown using MarkItDown library.
    async def get_document_markdown(self, document_id: str) -> KikV2DocumentMarkdown: """ Get KİK decision document content in Markdown format. This method uses a two-step process: 1. Call GetSorgulamaUrl endpoint to get the actual document URL 2. Use httpx to fetch the document content Args: document_id: The gundemMaddesiId from search results Returns: KikV2DocumentMarkdown with document content converted to Markdown """ logger.info(f"KikV2ApiClient: Getting document for ID: {document_id}") if not document_id or not document_id.strip(): return KikV2DocumentMarkdown( document_id=document_id, kararNo="", markdown_content="", source_url="", error_message="Document ID is required" ) try: # Step 1: Get the actual document URL using GetSorgulamaUrl endpoint logger.info(f"KikV2ApiClient: Step 1 - Getting document URL for ID: {document_id}") # Update security headers for this request headers = {**self.http_client.headers, **self._generate_security_headers()} # Call GetSorgulamaUrl to get the real document URL url_payload = {"sorguSayfaTipi": 2} # As shown in curl example url_response = await self.http_client.post( "/b_ihalearaclari/api/KurulKararlari/GetSorgulamaUrl", json=url_payload, headers=headers ) url_response.raise_for_status() url_data = url_response.json() # Get the base document URL from API response base_document_url = url_data.get("sorgulamaUrl", "") if not base_document_url: return KikV2DocumentMarkdown( document_id=document_id, kararNo="", markdown_content="", source_url="", error_message="Could not get document URL from GetSorgulamaUrl API" ) # If document_id is numeric, encrypt it to get the KararId hash # The web interface uses AES-256-CBC encrypted hashes for document URLs karar_id = document_id if document_id.isdigit(): try: karar_id = self.encrypt_document_id(document_id) logger.info(f"KikV2ApiClient: Encrypted numeric ID {document_id} to hash: {karar_id}") except Exception as enc_error: logger.warning(f"KikV2ApiClient: Could not encrypt document ID, using as-is: {enc_error}") # Construct full document URL with the encrypted KararId document_url = f"{base_document_url}?KararId={karar_id}" logger.info(f"KikV2ApiClient: Step 2 - Retrieved document URL: {document_url}") except Exception as e: logger.error(f"KikV2ApiClient: Error getting document URL for ID {document_id}: {str(e)}") # Fallback to old method if GetSorgulamaUrl fails # Also encrypt numeric IDs in fallback path karar_id = document_id if document_id.isdigit(): try: karar_id = self.encrypt_document_id(document_id) logger.info(f"KikV2ApiClient: Encrypted numeric ID in fallback: {karar_id}") except Exception as enc_error: logger.warning(f"KikV2ApiClient: Could not encrypt in fallback: {enc_error}") document_url = f"https://ekap.kik.gov.tr/EKAP/Vatandas/KurulKararGoster.aspx?KararId={karar_id}" logger.info(f"KikV2ApiClient: Falling back to direct URL: {document_url}") try: # Step 2: Use httpx to get the document content logger.info(f"KikV2ApiClient: Step 2 - Using httpx to retrieve document from: {document_url}") # Create a separate httpx client for document retrieval with HTML headers doc_ssl_context = ssl.create_default_context() doc_ssl_context.check_hostname = False doc_ssl_context.verify_mode = ssl.CERT_NONE if hasattr(ssl, 'OP_LEGACY_SERVER_CONNECT'): doc_ssl_context.options |= ssl.OP_LEGACY_SERVER_CONNECT doc_ssl_context.set_ciphers('ALL:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA') async with httpx.AsyncClient( verify=doc_ssl_context, headers={ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "tr,en-US;q=0.5", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" }, timeout=60.0, follow_redirects=True ) as doc_client: response = await doc_client.get(document_url) response.raise_for_status() html_content = response.text logger.info(f"KikV2ApiClient: Retrieved content via httpx, length: {len(html_content)}") # Convert HTML to Markdown using MarkItDown with BytesIO try: from markitdown import MarkItDown from io import BytesIO md = MarkItDown() html_bytes = html_content.encode('utf-8') html_stream = BytesIO(html_bytes) result = md.convert_stream(html_stream, file_extension=".html") markdown_content = result.text_content return KikV2DocumentMarkdown( document_id=document_id, kararNo="", markdown_content=markdown_content, source_url=document_url, error_message="" ) except ImportError: return KikV2DocumentMarkdown( document_id=document_id, kararNo="", markdown_content="MarkItDown library not available", source_url=document_url, error_message="MarkItDown library not installed" ) except Exception as e: logger.error(f"KikV2ApiClient: Error retrieving document {document_id}: {str(e)}") return KikV2DocumentMarkdown( document_id=document_id, kararNo="", markdown_content="", source_url=document_url, error_message=str(e) )
  • Pydantic schema defining the output structure of the get_kik_document_markdown tool response.
    class KikV2DocumentMarkdown(BaseModel): """Document content in Markdown format.""" document_id: str = Field("", description="Document ID") kararNo: str = Field("", description="Decision number") markdown_content: str = Field("", description="Decision content in Markdown") source_url: str = Field("", description="Source URL") error_message: str = Field("", description="Error message if retrieval failed")
  • Static helper method for encrypting numeric document IDs to the required hex hash format for KIK document URLs, reverse-engineered from the web app.
    @staticmethod def encrypt_document_id(numeric_id: str) -> str: """ Encrypt a numeric KİK gundemMaddesiId to the 64-character hex hash used in document URLs. Algorithm: AES-256-CBC with PKCS7 padding Output format: IV (16 bytes hex) + Ciphertext (16 bytes hex) = 64 chars Args: numeric_id: The numeric document ID from search results (e.g., "177280") Returns: 64-character hex string for use in document URL KararId parameter """ if not HAS_CRYPTOGRAPHY: raise ImportError("cryptography library required for document ID encryption") # Generate random IV (16 bytes) iv = os.urandom(16) # Create AES-CBC cipher with the encryption key cipher = Cipher( algorithms.AES(KikV2ApiClient.DOCUMENT_ID_ENCRYPTION_KEY), modes.CBC(iv), backend=default_backend() ) encryptor = cipher.encryptor() # Encode plaintext and apply PKCS7 padding plaintext = numeric_id.encode('utf-8') block_size = 16 padding_len = block_size - (len(plaintext) % block_size) padded_plaintext = plaintext + bytes([padding_len] * padding_len) # Encrypt ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize() # Return IV + ciphertext as lowercase hex (64 characters total) return iv.hex() + ciphertext.hex()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/saidsurucu/yargi-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server