{"openapi":"3.1.0","info":{"title":"Mockulator API","version":"1.0.0","summary":"Create and manage hosted mock HTTP APIs.","description":"Mockulator hosts mock HTTP APIs. A mock server groups endpoints under a public base URL (https://api.mockulator.com/api/{accountId}/{serverName}/), and every endpoint is live at its URL the moment it is created. Use this API to list servers, and to list, create, and edit mock endpoints. The same operations are available as MCP tools at https://api.mockulator.com/mcp. Response bodies support dynamic templating re-evaluated on every request: {{faker.*}} tokens run faker.js methods (e.g. {{faker.string.uuid}}, {{faker.person.fullName}}, {{faker.number.int(18, 99)}}); shorthand tokens {{uuid}}, {{timestamp}}, {{date}}, {{random(1, 100)}}, {{random_choice(\"a\", \"b\")}}; and {{#repeat N}}...{{/repeat}} blocks inside a JSON array to emit N templated items (max 1000).","contact":{"name":"Mockulator support","email":"support@mockulator.com","url":"https://mockulator.com/contact"},"termsOfService":"https://mockulator.com/policy","x-logo":{"url":"https://mockulator.com/web-app-manifest-192x192.png"}},"externalDocs":{"description":"Mockulator documentation","url":"https://mockulator.com/docs"},"servers":[{"url":"https://api.mockulator.com","description":"Production"}],"security":[{"apiKey":[]}],"tags":[{"name":"Servers","description":"Mock servers group endpoints under a shared public base URL."},{"name":"Endpoints","description":"Mock endpoints and the responses they return."},{"name":"Mocks","description":"The public mock URLs that the endpoints are served from. No auth."}],"paths":{"/v1/servers":{"get":{"tags":["Servers"],"operationId":"listServers","summary":"List mock servers","description":"List the caller's mock servers with endpoint counts and public base URLs. Call this first to obtain a serverId for the endpoint operations.","responses":{"200":{"description":"The list of mock servers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerList"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{serverId}/endpoints":{"parameters":[{"name":"serverId","in":"path","required":true,"description":"Mock server ID, from listServers.","schema":{"type":"integer","minimum":1}}],"get":{"tags":["Endpoints"],"operationId":"listEndpoints","summary":"List mock endpoints","description":"List the endpoints of one mock server, including the public URL each mock is served from.","parameters":[{"name":"search","in":"query","description":"Only endpoints whose name contains this text.","schema":{"type":"string"}},{"name":"method","in":"query","description":"Only endpoints with this HTTP method.","schema":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]}}],"responses":{"200":{"description":"The endpoints of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndpointList"}}}},"400":{"description":"Invalid parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Server not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Endpoints"],"operationId":"createEndpoint","summary":"Create a mock endpoint","description":"Create an HTTP mock endpoint with one default response. The mock is live at the returned URL immediately. Response bodies support dynamic templating re-evaluated on every request: {{faker.*}} tokens run faker.js methods (e.g. {{faker.string.uuid}}, {{faker.person.fullName}}, {{faker.number.int(18, 99)}}); shorthand tokens {{uuid}}, {{timestamp}}, {{date}}, {{random(1, 100)}}, {{random_choice(\"a\", \"b\")}}; and {{#repeat N}}...{{/repeat}} blocks inside a JSON array to emit N templated items (max 1000).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEndpointRequest"}}}},"responses":{"201":{"description":"The endpoint was created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEndpointResponse"}}}},"400":{"description":"Invalid body or endpoint name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Server not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"An endpoint with that name already exists on the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/servers/{serverId}/endpoints/{endpointId}":{"parameters":[{"name":"serverId","in":"path","required":true,"description":"Mock server ID, from listServers.","schema":{"type":"integer","minimum":1}},{"name":"endpointId","in":"path","required":true,"description":"Endpoint ID, from listEndpoints.","schema":{"type":"integer","minimum":1}}],"get":{"tags":["Endpoints"],"operationId":"getEndpoint","summary":"Get a mock endpoint","description":"Full detail of one endpoint: response bodies, headers, rules, and validations.","responses":{"200":{"description":"The endpoint detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndpointDetailResponse"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Server or endpoint not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Endpoints"],"operationId":"editEndpoint","summary":"Edit a mock endpoint","description":"Edit an endpoint. Only the fields you pass change. For endpoints with several configured responses, statusCode, responseBody, and contentType edit the default response. The endpoint name (and URL) cannot change.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditEndpointRequest"}}}},"responses":{"200":{"description":"The endpoint was updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditEndpointResponse"}}}},"400":{"description":"Invalid body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Server or endpoint not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/{accountId}/{serverName}/{path}":{"parameters":[{"name":"accountId","in":"path","required":true,"description":"8-character account ID (part of each baseUrl).","schema":{"type":"string","pattern":"^[A-Za-z0-9]{8}$"}},{"name":"serverName","in":"path","required":true,"description":"Mock server name.","schema":{"type":"string"}},{"name":"path","in":"path","required":true,"description":"Endpoint name, may contain slashes.","schema":{"type":"string"}}],"get":{"tags":["Mocks"],"operationId":"callMockGet","summary":"Call a mock endpoint (GET)","description":"Returns whatever the matching mock endpoint is configured to return.","security":[],"responses":{"default":{"description":"The configured mock response."}}},"post":{"tags":["Mocks"],"operationId":"callMockPost","summary":"Call a mock endpoint (POST)","description":"Returns whatever the matching mock endpoint is configured to return.","security":[],"responses":{"default":{"description":"The configured mock response."}}},"put":{"tags":["Mocks"],"operationId":"callMockPut","summary":"Call a mock endpoint (PUT)","description":"Returns whatever the matching mock endpoint is configured to return.","security":[],"responses":{"default":{"description":"The configured mock response."}}},"patch":{"tags":["Mocks"],"operationId":"callMockPatch","summary":"Call a mock endpoint (PATCH)","description":"Returns whatever the matching mock endpoint is configured to return.","security":[],"responses":{"default":{"description":"The configured mock response."}}},"delete":{"tags":["Mocks"],"operationId":"callMockDelete","summary":"Call a mock endpoint (DELETE)","description":"Returns whatever the matching mock endpoint is configured to return.","security":[],"responses":{"default":{"description":"The configured mock response."}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Mockulator MCP key. Generate one at https://mockulator.com/account and send it as \"Authorization: Bearer <key>\"."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code.","enum":["unauthorized","invalid_api_key","validation_error","invalid_endpoint_name","invalid_status_code","server_not_found","endpoint_not_found","endpoint_exists","not_found","internal_error"]},"message":{"type":"string","description":"Human-readable explanation."},"hint":{"type":"string","description":"How to resolve the error."},"docs":{"type":"string","format":"uri"},"details":{"type":"array","description":"Field-level validation problems (validation_error only).","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}},"HttpMethod":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"Server":{"type":"object","required":["serverId","name","endpointCount","baseUrl"],"properties":{"serverId":{"type":"integer"},"name":{"type":"string"},"endpointCount":{"type":"integer"},"baseUrl":{"type":"string","format":"uri","description":"Public base URL; endpoints are served under it."}}},"ServerList":{"type":"object","required":["servers"],"properties":{"servers":{"type":"array","items":{"$ref":"#/components/schemas/Server"}}}},"EndpointSummary":{"type":"object","required":["endpointId","name","method","type","url"],"properties":{"endpointId":{"type":"integer"},"name":{"type":"string","description":"Endpoint path, e.g. \"users/profile\"."},"method":{"$ref":"#/components/schemas/HttpMethod"},"type":{"type":"string","enum":["http","validation"]},"statusCode":{"type":["integer","null"]},"responseDelayMs":{"type":["integer","null"]},"url":{"type":"string","format":"uri","description":"Public URL the mock is served from."}}},"EndpointList":{"type":"object","required":["server","endpoints"],"properties":{"server":{"type":"string","description":"Server name."},"endpoints":{"type":"array","items":{"$ref":"#/components/schemas/EndpointSummary"}}}},"ResponseRule":{"type":"object","properties":{"field_name":{"type":"string"},"operator":{"type":"string"},"value":{"type":["string","null"]},"source":{"type":"string","description":"Where the field is read from (body, query, header, ...)."}}},"EndpointResponse":{"type":"object","properties":{"name":{"type":"string"},"statusCode":{"type":"integer"},"responseBody":{"type":"string"},"contentType":{"type":"string"},"headers":{"type":["object","array","null"],"description":"Custom response headers."},"isDefault":{"type":"boolean"},"rules":{"type":"array","items":{"$ref":"#/components/schemas/ResponseRule"}}}},"Validation":{"type":"object","properties":{"field_name":{"type":"string"},"is_required":{"type":"boolean"},"validation_type":{"type":"string"},"validation_value":{"type":["string","null"]},"source":{"type":"string"}}},"EndpointDetail":{"allOf":[{"$ref":"#/components/schemas/EndpointSummary"},{"type":"object","properties":{"responseMode":{"type":["string","null"],"description":"http endpoints: rules, sequential, shuffle, or fallback."},"responses":{"type":"array","items":{"$ref":"#/components/schemas/EndpointResponse"}},"responseBody":{"type":"string","description":"validation endpoints only."},"contentType":{"type":"string","description":"validation endpoints only."},"validations":{"type":"array","items":{"$ref":"#/components/schemas/Validation"}}}}]},"EndpointDetailResponse":{"type":"object","required":["server","endpoint"],"properties":{"server":{"type":"string"},"endpoint":{"$ref":"#/components/schemas/EndpointDetail"}}},"CreateEndpointRequest":{"type":"object","required":["endpointName","method"],"properties":{"endpointName":{"type":"string","maxLength":255,"pattern":"^[a-zA-Z0-9_\\-/]+$","description":"Endpoint path, e.g. \"users\" or \"users/profile\". No spaces, no leading/trailing slash."},"method":{"$ref":"#/components/schemas/HttpMethod"},"statusCode":{"type":"integer","minimum":100,"maximum":599,"default":200},"responseBody":{"type":"string","default":"","description":"Response body, e.g. a JSON string. Response bodies support dynamic templating re-evaluated on every request: {{faker.*}} tokens run faker.js methods (e.g. {{faker.string.uuid}}, {{faker.person.fullName}}, {{faker.number.int(18, 99)}}); shorthand tokens {{uuid}}, {{timestamp}}, {{date}}, {{random(1, 100)}}, {{random_choice(\"a\", \"b\")}}; and {{#repeat N}}...{{/repeat}} blocks inside a JSON array to emit N templated items (max 1000)."},"contentType":{"type":"string","default":"application/json"}}},"CreateEndpointResponse":{"type":"object","required":["created"],"properties":{"created":{"type":"object","properties":{"endpointId":{"type":"integer"},"name":{"type":"string"},"method":{"$ref":"#/components/schemas/HttpMethod"},"statusCode":{"type":"integer"},"contentType":{"type":"string"},"url":{"type":"string","format":"uri"}}},"note":{"type":"string"}}},"EditEndpointRequest":{"type":"object","properties":{"method":{"$ref":"#/components/schemas/HttpMethod"},"statusCode":{"type":"integer","minimum":100,"maximum":599},"responseBody":{"type":"string","description":"New response body. Response bodies support dynamic templating re-evaluated on every request: {{faker.*}} tokens run faker.js methods (e.g. {{faker.string.uuid}}, {{faker.person.fullName}}, {{faker.number.int(18, 99)}}); shorthand tokens {{uuid}}, {{timestamp}}, {{date}}, {{random(1, 100)}}, {{random_choice(\"a\", \"b\")}}; and {{#repeat N}}...{{/repeat}} blocks inside a JSON array to emit N templated items (max 1000)."},"contentType":{"type":"string"},"responseDelayMs":{"type":"integer","minimum":0,"maximum":60000,"description":"Delay before the mock responds."}}},"EditEndpointResponse":{"type":"object","required":["updated"],"properties":{"updated":{"type":"object","properties":{"endpointId":{"type":"integer"},"name":{"type":"string"},"method":{"$ref":"#/components/schemas/HttpMethod"},"responseDelayMs":{"type":"integer"},"url":{"type":"string","format":"uri"}}},"note":{"type":"string"}}}}}}