{"openapi":"3.0.3","info":{"title":"MockMe API","version":"1.0.0","description":"Manage mock endpoints, dynamic rules and request logs programmatically. Authenticate with an API key created in the dashboard.","contact":{"email":"hello@mockme.fyi","url":"https://mockme.fyi/contact"}},"servers":[{"url":"https://mockme.fyi/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Endpoints","description":"Create and manage mock endpoints"},{"name":"Rules","description":"Conditional responses for dynamic endpoints"},{"name":"Logs","description":"Requests received by your mocks"},{"name":"Account","description":"Plan limits and usage"},{"name":"API keys","description":"Credentials for programmatic access"}],"paths":{"/endpoints":{"get":{"tags":["Endpoints"],"summary":"List your mock endpoints","operationId":"listEndpoints","responses":{"200":{"description":"The endpoints belonging to the authenticated account","content":{"application/json":{"schema":{"type":"object","properties":{"endpoints":{"type":"array","items":{"$ref":"#/components/schemas/Endpoint"}}}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Endpoints"],"summary":"Create a mock endpoint","operationId":"createEndpoint","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","method","path"],"properties":{"name":{"type":"string"},"method":{"type":"string","enum":["GET","POST","PUT","DELETE","PATCH"]},"path":{"type":"string","example":"/users"},"status_code":{"type":"integer","default":200},"response_body":{},"response_headers":{"type":"object","additionalProperties":{"type":"string"}},"delay_ms":{"type":"integer","minimum":0,"maximum":30000,"default":0},"type":{"type":"string","enum":["common","dynamic","collection"],"default":"common"},"seed_with_faker":{"type":"boolean","description":"When type is collection, generate realistic seed items"},"collection_kind":{"type":"string","enum":["users","posts","orders","generic"]},"active":{"type":"boolean","default":true}}}}}},"responses":{"201":{"description":"Endpoint created","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/Endpoint"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Plan endpoint limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"An endpoint with this method and path already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/endpoints/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Endpoints"],"summary":"Fetch a single endpoint","operationId":"getEndpoint","responses":{"200":{"description":"The endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/Endpoint"}}}}}},"404":{"description":"Not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Endpoints"],"summary":"Update an endpoint","operationId":"updateEndpoint","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"method":{"type":"string","enum":["GET","POST","PUT","DELETE","PATCH"]},"path":{"type":"string"},"status_code":{"type":"integer"},"response_body":{},"response_headers":{"type":"object","additionalProperties":{"type":"string"}},"delay_ms":{"type":"integer","minimum":0,"maximum":30000},"type":{"type":"string","enum":["common","dynamic","collection"]},"active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Endpoint updated","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/Endpoint"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Endpoints"],"summary":"Delete an endpoint","operationId":"deleteEndpoint","responses":{"200":{"description":"Endpoint deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}}}}},"404":{"description":"Not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/endpoints/{id}/rules":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Rules"],"summary":"List the conditional rules of an endpoint","operationId":"listRules","responses":{"200":{"description":"Rules ordered by priority","content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"type":"array","items":{"$ref":"#/components/schemas/Rule"}}}}}}},"404":{"description":"Endpoint not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Rules"],"summary":"Add a conditional rule","operationId":"createRule","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","source","field","operator"],"properties":{"name":{"type":"string"},"source":{"type":"string","enum":["query","body","header"]},"field":{"type":"string","description":"Field or XPath evaluated against the request"},"operator":{"type":"string","enum":["equals","greater","less","present","absent","different"]},"value":{"type":"string","nullable":true},"priority":{"type":"integer","default":0,"description":"Lower runs first"},"status_code":{"type":"integer","default":200},"response_body":{},"response_headers":{"type":"object","additionalProperties":{"type":"string"}},"delay_ms":{"type":"integer","default":0},"active":{"type":"boolean","default":true}}}}}},"responses":{"201":{"description":"Rule created","content":{"application/json":{"schema":{"type":"object","properties":{"rule":{"$ref":"#/components/schemas/Rule"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Endpoint not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/endpoints/{id}/rules/{ruleId}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"ruleId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Rules"],"summary":"Fetch a conditional rule","operationId":"getRule","responses":{"200":{"description":"The rule","content":{"application/json":{"schema":{"type":"object","properties":{"rule":{"$ref":"#/components/schemas/Rule"}}}}}},"404":{"description":"Rule or endpoint not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Rules"],"summary":"Update a conditional rule","operationId":"updateRule","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"source":{"type":"string","enum":["query","body","header"]},"field":{"type":"string"},"operator":{"type":"string","enum":["equals","greater","less","present","absent","different"]},"value":{"type":"string","nullable":true},"priority":{"type":"integer","description":"Lower runs first"},"status_code":{"type":"integer"},"response_body":{},"response_headers":{"type":"object","additionalProperties":{"type":"string"}},"delay_ms":{"type":"integer"},"active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Rule updated","content":{"application/json":{"schema":{"type":"object","properties":{"rule":{"$ref":"#/components/schemas/Rule"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Rule or endpoint not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Rules"],"summary":"Delete a conditional rule","operationId":"deleteRule","responses":{"200":{"description":"Rule deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}}}}},"404":{"description":"Rule or endpoint not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/logs":{"get":{"tags":["Logs"],"summary":"List requests received by an endpoint","operationId":"listLogs","parameters":[{"name":"endpoint_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"hours","in":"query","schema":{"type":"integer"},"description":"Look-back window. Clamped to the retention allowed by your plan."},{"name":"limit","in":"query","schema":{"type":"integer","default":100,"maximum":500}}],"responses":{"200":{"description":"Matching request logs, newest first","content":{"application/json":{"schema":{"type":"object","properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/RequestLog"}},"window":{"type":"object","additionalProperties":true}}}}}},"400":{"description":"endpoint_id is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Endpoint not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"tags":["Account"],"summary":"Plan, limits and current consumption","operationId":"getUsage","responses":{"200":{"description":"Usage for the authenticated account. Unlimited values are null.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api-keys":{"get":{"tags":["API keys"],"summary":"List your API keys","description":"Secrets are never returned; only the display prefix.","operationId":"listApiKeys","responses":{"200":{"description":"Your API keys","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"tags":["API keys"],"summary":"Create an API key","description":"Requires a signed-in browser session; an API key cannot mint another API key. The plaintext token is returned once and cannot be recovered.","operationId":"createApiKey","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"expires_in_days":{"type":"integer","minimum":1,"maximum":3650}}}}}},"responses":{"201":{"description":"Key created. Store the token now.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"A browser session is required for this operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api-keys/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"delete":{"tags":["API keys"],"summary":"Revoke an API key","operationId":"revokeApiKey","responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api-keys/{id}/rotate":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["API keys"],"summary":"Rotate an API key","description":"Requires a signed-in browser session. Creates a replacement key with the same name and expiry, revokes the previous key, and returns the new plaintext token once.","operationId":"rotateApiKey","responses":{"201":{"description":"Replacement created and previous key revoked. Store the token now.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"The key is already revoked or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A browser session is required for this operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key created in the dashboard, sent as: Authorization: Bearer mk_live_..."}},"schemas":{"Endpoint":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"method":{"type":"string","enum":["GET","POST","PUT","DELETE","PATCH"]},"path":{"type":"string","example":"/users"},"url":{"type":"string","description":"Shareable /m/{slug}{path} URL, or the legacy /api/mock/user/{id} form when no slug exists"},"status_code":{"type":"integer","example":200},"response_body":{},"response_headers":{"type":"object","additionalProperties":{"type":"string"}},"delay_ms":{"type":"integer","minimum":0,"maximum":30000},"type":{"type":"string","enum":["common","dynamic","collection"]},"active":{"type":"boolean"},"expires_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Rule":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint_id":{"type":"string","format":"uuid"},"name":{"type":"string"},"priority":{"type":"integer"},"source":{"type":"string","enum":["query","body","header"]},"field":{"type":"string"},"operator":{"type":"string","enum":["equals","greater","less","present","absent","different"]},"value":{"type":"string","nullable":true},"status_code":{"type":"integer"},"response_body":{},"response_headers":{"type":"object","additionalProperties":{"type":"string"}},"delay_ms":{"type":"integer"},"active":{"type":"boolean"}}},"RequestLog":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint_id":{"type":"string","format":"uuid"},"ip_address":{"type":"string","nullable":true},"user_agent":{"type":"string","nullable":true},"request_headers":{"type":"object","additionalProperties":true},"request_body":{},"query_parameters":{"type":"object","additionalProperties":true},"response_status":{"type":"integer","nullable":true},"response_time_ms":{"type":"integer","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable, machine-readable error identifier","enum":["unauthorized","session_required","forbidden","not_found","validation_error","endpoint_exists","endpoint_limit_reached","plan_upgrade_required","rate_limited","payload_too_large","service_unavailable","internal_error"]},"message":{"type":"string","description":"Developer hint; may change between releases"},"docs_url":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}}}}