{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"API request stimuli","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"api-request-stimuli","__idx":0},"children":["API request stimuli"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Mabyduck supports direct evaluation of APIs through ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["API request stimuli"]},". These are"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".req.json"]}," files that stand in for media files in your datasets. API request stimuli are"," ","organized into groups like other stimuli. For instance:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"treeview","header":{"controls":{"copy":{}}},"source":"├── providers.json          (optional, but recommended)\n├── source_1/\n│   ├── elevenlabs.req.json\n│   └── cartesia.req.json\n├── source_2/\n│   ├── elevenlabs.req.json\n│   └── cartesia.req.json\n├── source_3/\n│   ├── ...\n","lang":"treeview"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["API request stimuli allow your experiments to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["fetch content dynamically from external APIs"]}," ","instead of using uploaded media files. Each stimulus is defined as a request configuration that"," ","the platform executes on-demand."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-it-works","__idx":1},"children":["How it works"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When a rater views an API request stimulus:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The platform reads your request configuration (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".req.json"]}," file)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/datasets/secrets/"},"children":["Dataset secrets"]}," are securely injected into the request."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The platform makes the API call on your behalf."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The response is processed and streamed to the rater."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your API credentials never leave our servers and are never exposed to raters."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"request-files--reqjson-","__idx":2},"children":["Request files (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".req.json"]},")"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A request file defines everything needed to call an external API:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"url\": \"https://api.openai.com/v1/images/generations\",\n    \"method\": \"POST\",\n    \"headers\": {\n        \"Authorization\": \"Bearer #{SECRETS.OPENAI_KEY}\",\n        \"Content-Type\": \"application/json\"\n    },\n    \"body\": {\n        \"model\": \"dall-e-3\",\n        \"prompt\": \"A futuristic city with neon lights\",\n        \"n\": 1,\n        \"size\": \"1024x1024\"\n    },\n    \"response_format\": \"json_url\",\n    \"response_extraction_path\": \"data[0].url\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"required-fields","__idx":3},"children":["Required fields"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["url"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The API endpoint URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_format"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["How to process the API response (see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#response-formats"},"children":["Response formats"]},")"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"optional-fields","__idx":4},"children":["Optional fields"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["method"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["HTTP method (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]},", etc.). Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["headers"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Request headers as key-value pairs"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["body"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["JSON body to send with the request"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_extraction_path"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["JMESPath expression to extract data from JSON responses"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"providers-registry--providersjson-","__idx":5},"children":["Providers registry (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["providers.json"]},")"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you have multiple stimuli calling the same API, you can define shared configurations in a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["providers.json"]}," file at the root of your dataset. This avoids repetition and makes your dataset easier to maintain."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"dalle_3\": {\n        \"url\": \"https://api.openai.com/v1/images/generations\",\n        \"method\": \"POST\",\n        \"headers\": {\n            \"Authorization\": \"Bearer #{SECRETS.OPENAI_KEY}\",\n            \"Content-Type\": \"application/json\"\n        },\n        \"body\": {\n            \"model\": \"dall-e-3\",\n            \"n\": 1,\n            \"size\": \"1024x1024\"\n        },\n        \"response_format\": \"json_url\",\n        \"response_extraction_path\": \"data[0].url\"\n    },\n    \"stable_diffusion\": {\n        \"url\": \"https://api.stability.ai/v1/generation/stable-diffusion-xl/text-to-image\",\n        \"method\": \"POST\",\n        \"headers\": {\n            \"Authorization\": \"Bearer #{SECRETS.STABILITY_KEY}\",\n            \"Content-Type\": \"application/json\"\n        },\n        \"response_format\": \"json_base64\",\n        \"response_extraction_path\": \"artifacts[0].base64\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-providers-in-request-files","__idx":6},"children":["Using providers in request files"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once you have defined providers, your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".req.json"]}," files become much simpler:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"provider\": \"dalle_3\",\n    \"body\": {\n        \"prompt\": \"A futuristic city with neon lights\",\n        \"quality\": \"hd\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["provider"]}," field tells the platform to start with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dalle_3"]}," configuration and merge in any overrides you specify."," ","When a request file references a provider:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Objects are merged recursively."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Lists and primitives are replaced."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Setting a value to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," removes it."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For example, if your provider sets ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"size\": \"1024x1024\""]}," but you want a different size:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"provider\": \"dalle_3\",\n    \"body\": {\n        \"prompt\": \"A mountain landscape\",\n        \"size\": \"512x512\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"response-formats","__idx":7},"children":["Response formats"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_format"]}," field tells the platform how to process the API response:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Format"},"children":["Format"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Use when"},"children":["Use when"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["binary"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Stream response bytes directly"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["API returns raw image/audio/video data"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json_url"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Extract a URL from JSON, then fetch that URL"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["API returns a JSON with a hosted file URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json_base64"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Extract a Base64 string from JSON, decode it"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["API returns Base64-encoded file data in JSON"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redirect_url"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Follow redirects and stream the final response"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["API redirects to the file location"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["multipart"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Handle multipart responses"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["API returns mixed content types"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"extracting-data-with-jmespath","__idx":8},"children":["Extracting data with JMESPath"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json_url"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json_base64"]}," formats, use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_extraction_path"]}," to specify where the data is located in the JSON response. This uses ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://jmespath.org/"},"children":["JMESPath"]}," syntax."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example responses and extraction paths:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"// Response: {\"data\": [{\"url\": \"https://...\"}]}\n// Path: \"data[0].url\"\n\n// Response: {\"artifacts\": [{\"base64\": \"iVBORw0...\"}]}\n// Path: \"artifacts[0].base64\"\n\n// Response: {\"result\": {\"image\": {\"url\": \"https://...\"}}}\n// Path: \"result.image.url\"\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"using-dataset-secrets","__idx":9},"children":["Using dataset secrets"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["API keys and other credentials should be stored as ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/datasets/secrets/"},"children":["dataset secrets"]},", not in your configuration files. Reference them using the placeholder syntax:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"#{SECRETS.SECRET_NAME}\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"headers\": {\n        \"Authorization\": \"Bearer #{SECRETS.OPENAI_KEY}\",\n        \"X-Api-Key\": \"#{SECRETS.CUSTOM_API_KEY}\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The placeholders are replaced with your actual secrets when the request is made. Your credentials are never exposed to raters or visible in browser developer tools."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"complete-example","__idx":10},"children":["Complete example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's a complete example dataset for comparing two image generation models:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["providers.json"]}]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"dalle\": {\n        \"url\": \"https://api.openai.com/v1/images/generations\",\n        \"method\": \"POST\",\n        \"headers\": {\n            \"Authorization\": \"Bearer #{SECRETS.OPENAI_KEY}\",\n            \"Content-Type\": \"application/json\"\n        },\n        \"body\": {\n            \"model\": \"dall-e-3\",\n            \"n\": 1,\n            \"size\": \"1024x1024\"\n        },\n        \"response_format\": \"json_url\",\n        \"response_extraction_path\": \"data[0].url\"\n    },\n    \"midjourney\": {\n        \"url\": \"https://api.example.com/midjourney/generate\",\n        \"method\": \"POST\",\n        \"headers\": {\n            \"Authorization\": \"#{SECRETS.MJ_API_KEY}\",\n            \"Content-Type\": \"application/json\"\n        },\n        \"response_format\": \"json_url\",\n        \"response_extraction_path\": \"imageUrl\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sunset/dalle.req.json"]}]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"provider\": \"dalle\",\n    \"body\": {\n        \"prompt\": \"A beautiful sunset over the ocean, photorealistic\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sunset/midjourney.req.json"]}]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"provider\": \"midjourney\",\n    \"body\": {\n        \"prompt\": \"A beautiful sunset over the ocean, photorealistic\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mountain/dalle.req.json"]}]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"provider\": \"dalle\",\n    \"body\": {\n        \"prompt\": \"Snow-capped mountains at dawn, cinematic lighting\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mountain/midjourney.req.json"]}]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"provider\": \"midjourney\",\n    \"body\": {\n        \"prompt\": \"Snow-capped mountains at dawn, cinematic lighting\"\n    }\n}\n","lang":"json"},"children":[]}]},"headings":[{"value":"API request stimuli","id":"api-request-stimuli","depth":1},{"value":"How it works","id":"how-it-works","depth":2},{"value":"Request files ( .req.json )","id":"request-files--reqjson-","depth":2},{"value":"Required fields","id":"required-fields","depth":3},{"value":"Optional fields","id":"optional-fields","depth":3},{"value":"Providers registry ( providers.json )","id":"providers-registry--providersjson-","depth":2},{"value":"Using providers in request files","id":"using-providers-in-request-files","depth":3},{"value":"Response formats","id":"response-formats","depth":2},{"value":"Extracting data with JMESPath","id":"extracting-data-with-jmespath","depth":3},{"value":"Using dataset secrets","id":"using-dataset-secrets","depth":2},{"value":"Complete example","id":"complete-example","depth":2}],"frontmatter":{"seo":{"title":"API request stimuli"}},"lastModified":"2026-05-01T17:00:53.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/datasets/self_hosted/apis","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}