{"openapi":"3.1.0","info":{"title":"Critique Flow API","summary":"Gives you researched in-line cited search responses from Critique's in-built LLM powered agentic search engine","description":"\n**URL**: `https://api.critique-labs.ai/v1/search`  \n**Method**: `POST`  \n**Content-Type**: `application/json`  \n\n#### Headers\n- **X-API-Key**: (Required) Your unique API key for authentication.\n- **Content-Type**: (Required) Should be set to `application/json`.\n\n#### Request Body Parameters\n| Parameter        | Type              | Description                                                                                                                                                                                                                         |\n|------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **image**        | `string` (optional) | A base64-encoded string of the image or a URL to the image. Providing this parameter allows the API to incorporate visual data into the search. If both `image` and `prompt` are included, they are combined to refine the search. |\n| **prompt**       | `string`          | A natural language question or statement that specifies the information you are seeking. The prompt can include specific instructions about the expected answer type, timeframe, or content source.                                  |\n| **source_blacklist** | `array` of `string` (optional) | A list of URLs or domains (e.g., `\"expedia.com\"`) that should be excluded from the search results. Cannot be used together with source_whitelist.                              |\n| **source_whitelist** | `array` of `string` (optional) | A list of URLs or domains that should be exclusively used in the search results. Cannot be used together with source_blacklist.                              |\n| **output_format**   | `object` (optional) | A JSON object that specifies the expected structure of the response. This allows for control over the format and detail level of the results, making integration into structured applications seamless. See details below.      |\n\n#### `output_format` Parameter\nThe `output_format` parameter is a JSON object that defines the desired structure of the API response. Each key in this object represents a field in the response, and the value defines its data type or structure.\n\n##### Supported Data Types\n- **Primitive Types**: `\"string\"`, `\"number\"`, `\"boolean\"`\n- **Nested Objects**: An object can have other fields, each with types or nested structures.\n- **Arrays of Objects**: Arrays can contain objects with defined structures.\n\n##### Example of `output_format`\n```json\n{\n  \"flights\": [\n    {\n      \"destination\": \"string\",\n      \"price\": \"number\",\n      \"date\": \"string\"\n    }\n  ],\n  \"summary\": \"string\",\n  \"isAvailable\": \"boolean\"\n}\n```\n\nIn this example:\n- `flights` is an array where each object has `destination` (a string), `price` (a number), and `date` (a string).\n- `summary` is a single string.\n- `isAvailable` is a boolean value.\n\n##### Request Example\nHere's an example request using the parameters defined:\n\n```json\n{\n  \"image\": \"https://cdn.britannica.com/95/94195-050-FCBF777E/Golden-Gate-Bridge-San-Francisco.jpg\",\n  \"prompt\": \"What are the current flight prices to this location from Hong Kong?\",\n  \"source_blacklist\": [\"expedia.com\"],\n  \"output_format\": {\n    \"flights\": [\n      {\n        \"destination\": \"string\",\n        \"price\": \"number\",\n        \"date\": \"string\"\n      }\n    ],\n    \"response\": \"string\"\n  }\n}\n```\n\nIn this request:\n- `image` provides an image URL.\n- `prompt` specifies the information sought.\n- `source_blacklist` excludes results from `\"expedia.com\"`.\n- `output_format` requests a structured response with `flights` (each with `destination`, `price`, and `date`) and an additional `response` as a summary string.\n\n#### Response\nThe API returns a JSON object formatted according to the `output_format`, providing flexibility in structuring the data based on application needs.\n","termsOfService":"https://api.critique-labs.ai/en/docs/terms-of-service","contact":{"email":"support@critique-labs.ai"},"version":"1.5.0","x-logo":{"url":"https://critique-labs.ai/_next/image?url=%2Fimages%2Ficon_only.png&w=96&q=75"}},"servers":[{"url":"https://api.critique-labs.ai"},{"url":"http://localhost"}],"paths":{"/v1/search":{"post":{"summary":"Search","operationId":"search_v1_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CritiqueRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchOutput"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"api_key":[]}],"x-codeSamples":[{"lang":"Python","source":"\nimport requests\nimport base64\n\ndef image_url_to_base64(image_url):\n    # Fetch the image from the URL\n    response = requests.get(image_url)\n    \n    # Check if the request was successful\n    if response.status_code != 200:\n        raise Exception(f\"Failed to fetch image. Status code: {response.status_code}\")\n    \n    # Convert the image content to base64\n    base64_encoded_image = base64.b64encode(response.content).decode('utf-8')\n    \n    return f\"data:image/jpeg;base64,{base64_encoded_image}\"\n\nimage_url = \"https://cdn.britannica.com/95/94195-050-FCBF777E/Golden-Gate-Bridge-San-Francisco.jpg\"\nbase64_string_encoded_image = image_url_to_base64(image_url)\n\nurl = 'https://api.critique-labs.ai/v1/search'\nheaders = {\n    'Content-Type': 'application/json',\n    'X-API-Key': 'REPLACE_KEY_VALUE'\n}\ndata = {\n    'image': base64_string_encoded_image, ## optional, this is the preferred method of sending an image, though url is also accepted. \n    'prompt': 'how much are flights to this place from Hong Kong right now',\n    'source_blacklist': ['expedia.com'], ## optional - specify either source_blacklist or source_whitelist, not both\n    # 'source_whitelist': ['kayak.com'], ## optional - specify either source_blacklist or source_whitelist, not both\n    'output_format': {'flights': [{\"origin\": \"string\", \"airline\": \"string\", \"destination\": \"string\",\"price\": \"number\"}], \"response\": \"string\"} ## optional. If you want a structured response, you can specify the output format here \n\n}\n\n# Sending a POST request\nresponse = requests.post(url, headers=headers, json=data)\n\n# Check for any errors\nif response.status_code != 200:\n    raise Exception(f\"Request failed with status code {response.status_code}: {response.text}\")\n\n# Print the response body\nprint(response.json())","label":"Python"},{"lang":"JS (fetch)","source":"\nasync function imageUrlToBase64(imageUrl) {\n  try {\n    // Fetch the image as a Blob\n    const response = await fetch(imageUrl);\n    \n    if (!response.ok) {\n      throw new Error(`Failed to fetch image. Status code: ${response.status}`);\n    }\n    \n    // Convert the response to a base64 encoded string\n    const blob = await response.blob();\n    const reader = new FileReader();\n\n    return new Promise((resolve, reject) => {\n      reader.onloadend = () => resolve(`data:image/jpeg;base64,${reader.result.split(',')[1]}`);\n      reader.onerror = reject;\n      reader.readAsDataURL(blob);\n    });\n  } catch (error) {\n    console.error(\"Error converting image to base64:\", error);\n  }\n}\n\nasync function sendData() {\n  const imageUrl = \"https://cdn.britannica.com/95/94195-050-FCBF777E/Golden-Gate-Bridge-San-Francisco.jpg\";\n  const base64StringEncodedImage = await imageUrlToBase64(imageUrl);\n\n  const url = 'https://api.critique-labs.ai/v1/search';\n  const headers = {\n    'Content-Type': 'application/json',\n    'X-API-Key': 'REPLACE_KEY_VALUE'\n  };\n  const data = {\n    image: base64StringEncodedImage, // Optional arg. Preferred method of sending image instead of url\n    prompt: 'how much are flights to this place from Hong Kong right now',\n    source_blacklist: ['expedia.com'], // Optional - specify either source_blacklist or source_whitelist, not both\n    // source_whitelist: ['kayak.com'], // Optional - specify either source_blacklist or source_whitelist, not both\n    output_format: {\n      flights: [{\"origin\": \"string\", \"airline\": \"string\",\"destination\": \"string\", \"price\": \"number\"}],\n      response: \"string\"\n    } // Optional arg. Structured response format\n  };\n\n  try {\n    const response = await fetch(url, {\n      method: 'POST',\n      headers: headers,\n      body: JSON.stringify(data)\n    });\n\n    if (!response.ok) {\n      throw new Error(`Request failed with status code ${response.status}: ${await response.text()}`);\n    }\n\n    const responseData = await response.json();\n    console.log(responseData);\n  } catch (error) {\n    console.error(\"Error sending data:\", error);\n  }\n}\n","label":"JS (fetch)"},{"lang":"curl","source":"\n    curl -X POST https://api.critique-labs.ai/v1/search   -H \"Content-Type: application/json\"   -H \"X-API-Key: REPLACE_KEY_VALUE\"   -d '{\n        \"image\": \"https://cdn.britannica.com/95/94195-050-FCBF777E/Golden-Gate-Bridge-San-Francisco.jpg\",\n        \"prompt\": \"how much are flights to this place from Hong Kong right now\",\n        \"source_blacklist\": [\"expedia.com\"],\n        \"output_format\": {\n          \"flights\": [{\"origin\": \"string\", \"airline\": \"string\",\"destination\": \"string\", \"price\": \"number\"}],\n          \"response\": \"string\"\n        }\n      }'\n      ","label":"curl"}]}},"/v1/contents":{"post":{"summary":"Contents","description":"This endpoint is used to retrieve the post-processed contents of a web page in the format that the agentic search engine processes.","operationId":"contents_v1_contents_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentOutput"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"api_key":[]}]}},"/v1/user-defined-service/{api_stub}":{"post":{"summary":"Produce User Defined Service","operationId":"produce_user_defined_service_v1_user_defined_service__api_stub__post","security":[{"api_key":[]}],"parameters":[{"name":"api_stub","in":"path","required":true,"schema":{"type":"string","description":"The endpoint path as you build in the design your own API section","title":"Api Stub"},"description":"The endpoint path as you build in the design your own API section"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/published-service/{api_stub}":{"post":{"summary":"Produce Public Service","operationId":"produce_public_service_v1_published_service__api_stub__post","security":[{"api_key":[]}],"parameters":[{"name":"api_stub","in":"path","required":true,"schema":{"type":"string","description":"The endpoint path as you build in the design your own API section","title":"Api Stub"},"description":"The endpoint path as you build in the design your own API section"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/design-api":{"get":{"summary":"List Designed Apis With Key","operationId":"list_designed_apis_with_key_v1_design_api_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"api_key":[]}]},"post":{"summary":"Design Api With Key","operationId":"design_api_with_key_v1_design_api_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignedApiInput"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"api_key":[]}]}},"/v1/design-api/{api_id}":{"delete":{"summary":"Delete Api With Key","operationId":"delete_api_with_key_v1_design_api__api_id__delete","security":[{"api_key":[]}],"parameters":[{"name":"api_id","in":"path","required":true,"schema":{"type":"integer","title":"Api Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ws/search":{"get":{"summary":"Streaming Search","description":"\n> **⚠️ Important Note**: The auto-generated code samples in the playground will not work for this WebSocket endpoint, with the exception of the Python and JS(WebSocket) examples shown. Please use these provided examples only, and not the auto-generated ones.\n\nThis endpoint provides a WebSocket connection for streaming search results in real-time.\n\n#### Connection\nConnect to: `wss://api.critique-labs.ai/v1/ws/search`\n\n#### Headers\n- **X-API-Key**: (Required) Your unique API key for authentication.\n\n#### Message Format\nAfter connecting, send a JSON message with the following structure:\n```json\n{\n    \"prompt\": \"your search query\",\n    \"image\": \"optional base64 image or URL\",\n    \"source_blacklist\": [\"optional list of domains to exclude\"],\n    \"output_format\": {\n        // Optional structured output format\n    }\n}\n```\n\n#### Streaming Responses\nThe server will stream responses as JSON messages with the following structure:\n```json\n{\n    \"type\": \"response\" | \"context\" | \"error\",\n    \"content\": \"the actual content\"\n}\n```\n\n- `type: \"response\"` - Contains generated response content\n- `type: \"context\"` - Contains source context information\n- `type: \"error\"` - Contains error messages if any occur\n","x-codeSamples":[{"lang":"Python","source":"\nimport websockets\nimport asyncio\nimport json\n\nasync def search_streaming():\n    uri = \"wss://api.critique-labs.ai/v1/ws/search\"\n    headers = {\n        'X-API-Key': '<YOUR API KEY HERE>'\n    }\n    \n    async with websockets.connect(uri, extra_headers=headers) as websocket:\n        # Send the search request\n        await websocket.send(json.dumps({\n            'prompt': 'how much are flights to this place from Hong Kong right now',\n            'source_blacklist': ['expedia.com'],  # optional - specify either source_blacklist or source_whitelist, not both\n            # 'source_whitelist': ['kayak.com'],  # optional - specify either source_blacklist or source_whitelist, not both\n            'output_format': {\n                'flights': [{\"origin\": \"string\", \"airline\": \"string\", \"destination\": \"string\", \"price\": \"number\"}],\n                \"response\": \"string\"\n            }\n        }))\n        \n        # Receive and process streaming responses\n        while True:\n            try:\n                response = await websocket.recv()\n                data = json.loads(response)\n                \n                # Handle different types of responses\n                if data['type'] == 'response':\n                    print('Response:', data['content'])\n                elif data['type'] == 'context':\n                    print('Context:', data['content'])\n                elif data['type'] == 'error':\n                    print('Error:', data['content'])\n                    break\n            except websockets.exceptions.ConnectionClosed:\n                print(\"Connection closed\")\n                break\n\n# Run the async function\nasyncio.run(search_streaming())\n","label":"Python"},{"lang":"JavaScript","source":"\nconst WebSocket = require(\"ws\");\nconst ws = new WebSocket('wss://api.critique-labs.ai/v1/ws/search', {\n    headers: {\n        'X-API-Key': '<YOUR API KEY HERE>'\n    }\n});\n\nws.onopen = () => {\n    // Send the search request\n    ws.send(JSON.stringify({\n        prompt: 'how much are flights to this place from Hong Kong right now',\n        source_blacklist: ['expedia.com'],  # optional - specify either source_blacklist or source_whitelist, not both\n        // source_whitelist: ['kayak.com'],  # optional - specify either source_blacklist or source_whitelist, not both\n        output_format: {\n            flights: [{\"origin\": \"string\", \"airline\": \"string\", \"destination\": \"string\", \"price\": \"number\"}],\n            response: \"string\"\n        }\n    }));\n};\n\nws.onmessage = (event) => {\n    const data = JSON.parse(event.data);\n    \n    // Handle different types of responses\n    switch(data.type) {\n        case 'response':\n            console.log('Response:', data.content);\n            break;\n        case 'context':\n            console.log('Context:', data.content);\n            break;\n        case 'error':\n            console.log('Error:', data.content);\n            ws.close();\n            break;\n    }\n};\n\nws.onerror = (error) => {\n    console.error('WebSocket error:', error);\n};\n\nws.onclose = () => {\n    console.log('Connection closed');\n};\n","label":"JS (WebSocket)"}],"parameters":[{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key for authentication"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"The search query, can be as extended or succinct as you like"},"image":{"type":"string","description":"Optional, This string can be the url of the image you want to send. Alternatively, (and the preferred method) is providing a base64 encoded string of the image. If providing a url, the link must start with https:// and ends with a common image file extension like .jpg, .jpeg, .png, .gif, etc."},"source_blacklist":{"type":"array","items":{"type":"string"},"description":"Optional, a list of strings representing domains you want to exclude from the agentic search. ['cnn.com','foxnews.com']."},"output_format":{"type":"object","description":"Optional, a json schema for the response. This will be used to format the response of the agentic search. The types allowed can be any of: string, number, boolean, integer, array"}}}}}},"responses":{"101":{"description":"WebSocket connection established"}}}}},"components":{"schemas":{"ApiGraphEdge":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"source":{"type":"string","title":"Source"},"target":{"type":"string","title":"Target"}},"type":"object","required":["source","target"],"title":"ApiGraphEdge"},"ApiGraphNode":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"type":{"type":"string","title":"Type"},"name":{"type":"string","title":"Name"},"system_prompt":{"type":"string","title":"System Prompt"},"output_format":{"type":"object","title":"Output Format"},"configuration":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Configuration","default":{}}},"type":"object","required":["id","type","name","system_prompt","output_format"],"title":"ApiGraphNode"},"ContentOutput":{"properties":{"response":{"type":"string","title":"Response"},"info":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Info","default":{}}},"type":"object","required":["response"],"title":"ContentOutput"},"ContentRequest":{"properties":{"url":{"type":"string","title":"Url","description":"The url of the web page you want to retrieve the contents of"},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query","description":"Optional, a query to be used to search the contents of the url"}},"type":"object","required":["url"],"title":"ContentRequest"},"CritiqueRequest":{"properties":{"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image","description":"Optional, This string can be the url of the image you want to send. Alternatively, (and the preferred method) is providing a base64 encoded string of the image. If providing a url, the link must start with https:// and ends with a common image file extension like .jpg, .jpeg, .png, .gif, etc."},"prompt":{"type":"string","title":"Prompt","description":"The search query, can be as extended or succinct as you like"},"output_format":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Output Format","description":"Optional, a json schema for the response. This will be used to format the response of the agentic search. The types allowed can be any of: \nstring \nnumber\nboolean\ninteger\narray","default":{}},"source_blacklist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Source Blacklist","description":"Optional, a list of strings representing domains you want to exclude from the agentic search. ['cnn.com','foxnews.com'].  ","default":[]},"source_whitelist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Source Whitelist","description":"Optional, a list of strings representing domains you want to include in the agentic search. ['cnn.com','foxnews.com']. This is mutually exclusive with source_blacklist, if it is not empty, source_blacklist must be empty","default":[]}},"type":"object","required":["prompt"],"title":"CritiqueRequest"},"DesignedApiInput":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"original_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Prompt","default":""},"template_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Prompt","default":""},"inputs":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Inputs","default":[]},"output_format":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Output Format","default":{}},"api_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Name","default":""},"stub":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stub","default":""},"nodes":{"anyOf":[{"items":{"$ref":"#/components/schemas/ApiGraphNode"},"type":"array"},{"type":"null"}],"title":"Nodes","default":[]},"edges":{"anyOf":[{"items":{"$ref":"#/components/schemas/ApiGraphEdge"},"type":"array"},{"type":"null"}],"title":"Edges","default":[]}},"type":"object","title":"DesignedApiInput"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"SearchContext":{"properties":{"id":{"type":"integer","title":"Id"},"metadata":{"$ref":"#/components/schemas/SearchMetadata"}},"type":"object","required":["id","metadata"],"title":"SearchContext"},"SearchMetadata":{"properties":{"title":{"type":"string","title":"Title"},"url":{"type":"string","title":"Url"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content","default":""}},"type":"object","required":["title","url"],"title":"SearchMetadata"},"SearchOutput":{"properties":{"response":{"type":"string","title":"Response"},"context":{"items":{"$ref":"#/components/schemas/SearchContext"},"type":"array","title":"Context","default":[]},"info":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Info","default":{}}},"type":"object","required":["response"],"title":"SearchOutput"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"api_key":{"type":"apiKey","description":"Your API key for authentication. Get one at https://critique-labs.ai/en/dashboard","in":"header","name":"X-API-Key"}}}}