{"security":[{"bearerAuth":[]}],"servers":[{"url":"/v1","description":"this site"}],"components":{"schemas":{"Violation":{"properties":{"count":{"type":"integer"},"sample_count":{"type":"integer"},"pointer":{"type":["string","null"]},"keyword":{"type":["string","null"]},"expected":{"type":["string","null"]},"operation_id":{"type":["string","null"]},"got_type":{"type":["string","null"]},"fingerprint":{"type":"string"},"last_seen":{"type":"integer"},"first_seen":{"type":"integer"},"spec_version":{"type":["string","null"]},"status":{"type":["integer","null"]}},"type":"object","required":["fingerprint","count"]},"Environment":{"required":["name"],"type":"object","properties":{"name":{"type":"string"},"version":{"type":["integer","null"]},"id":{"type":"integer"}}},"SpecVersion":{"properties":{"published":{"type":"boolean"},"id":{"type":"integer"},"operations":{"type":["integer","null"]},"digest":{"type":"string"},"size":{"type":"integer"}},"type":"object","required":["id","digest","size"]},"MockExample":{"properties":{"updated":{"type":"integer"},"status":{"type":"string","description":"the response status the example is for, e.g. \"200\" or \"default\""},"id":{"type":"integer"},"media_type":{"type":"string"},"body":{"type":"string","description":"the example as a JSON string, validated against the response schema"},"name":{"type":"string","description":"\"\" is the primary example (the media type's example); a set name is a scenario, reached with Prefer: example=<name>"},"operation_id":{"type":"string"}},"type":"object","required":["id","operation_id","status","name","media_type","body"]},"Problem":{"properties":{"title":{"type":"string"},"type":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"}},"required":["title","status"],"type":"object"},"Coverage":{"properties":{"skip_body":{"type":"integer"},"divisor":{"type":"integer"},"operation_id":{"type":"string"},"unsampled":{"type":"integer"},"skip_ctype":{"type":"integer"},"skip_size":{"type":"integer"},"updated":{"type":"integer"},"violations":{"type":"integer"},"checked":{"type":"integer"},"total":{"type":"integer"},"skip_decode":{"type":"integer"},"skip_schema":{"type":"integer"}},"required":["operation_id","total","checked"],"type":"object"},"Proxy":{"required":["id","name","slug","mode"],"type":"object","properties":{"mode":{"enum":["observe","enforce","mock"],"type":"string"},"host":{"type":"string"},"id":{"type":"integer"},"slug":{"type":"string"},"upstream":{"type":["string","null"]},"name":{"type":"string"},"published_version":{"type":["integer","null"]}}},"Alert":{"properties":{"target":{"type":"string"},"enabled":{"type":"boolean"},"state":{"enum":["ok","firing"],"type":"string"},"threshold":{"type":"integer"},"name":{"type":"string"},"last_fired":{"type":"integer"},"channel":{"enum":["webhook","slack"],"type":"string"},"operation_id":{"type":["string","null"]},"id":{"type":"integer"},"window_min":{"type":"integer"}},"required":["id","name","threshold","window_min","channel"],"type":"object"},"Diff":{"properties":{"removed":{"type":"array","items":{"type":"string"}},"added":{"items":{"type":"string"},"type":"array"},"to":{"type":"integer"},"changed":{"type":"array","items":{"type":"object","properties":{"operation":{"type":"string"},"notes":{"type":"array","items":{"type":"string"}}}}},"arrived":{"type":"array","items":{"type":"string"}},"fixed":{"items":{"type":"string"},"type":"array"},"from":{"type":"integer"},"carried":{"type":"array","items":{"type":"string"}}},"type":"object"}},"securitySchemes":{"bearerAuth":{"type":"http","description":"An account API token, issued on the account page.","scheme":"bearer"}},"responses":{"NotFound":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"no such thing, or not yours"},"Denied":{"description":"the token is missing, wrong, or not allowed to do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"info":{"description":"Everything the console does, as an API. This document is not written about the API - it IS the API: the server dispatches from it, validates every request against it, and a test walks its operations to prove the CLI can reach each one. We sell contract enforcement; our own contract being the implementation is the demo.","title":"openapi-proxy.com management API","version":"1.0.0"},"paths":{"/proxies/{proxy_id}/token":{"parameters":[{"schema":{"type":"integer"},"required":true,"in":"path","name":"proxy_id"}],"post":{"operationId":"rotateReportToken","tags":["proxies"],"responses":{"200":{"content":{"application/json":{"schema":{"required":["report_token"],"type":"object","properties":{"report_token":{"type":"string"}}}}},"description":"the new token"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Rotate the gateway report token"}},"/proxies/{proxy_id}/alerts":{"parameters":[{"in":"path","name":"proxy_id","required":true,"schema":{"type":"integer"}}],"get":{"summary":"The alert rules on a proxy","responses":{"200":{"description":"the rules","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Alert"}}}}},"404":{"$ref":"#/components/responses/NotFound"}},"tags":["alerts"],"operationId":"listAlerts"},"post":{"requestBody":{"content":{"application/json":{"schema":{"properties":{"threshold":{"minimum":0,"type":"integer"},"target":{"type":"string"},"window_min":{"maximum":1440,"type":"integer","minimum":1},"operation_id":{"type":"string"},"channel":{"enum":["webhook","slack"],"type":"string"},"name":{"type":"string","minLength":1}},"type":"object","required":["name","threshold","window_min","channel","target"]}}},"required":true},"summary":"Add an alert rule","responses":{"201":{"description":"the rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"400":{"$ref":"#/components/responses/NotFound"},"404":{"$ref":"#/components/responses/NotFound"}},"tags":["alerts"],"operationId":"createAlert"}},"/proxies/{proxy_id}/violations":{"get":{"summary":"Drift, one row per shape of disagreement","parameters":[{"schema":{"type":"string","enum":["24h","7d","friday"]},"name":"since","in":"query"},{"schema":{"type":"string"},"name":"operation","in":"query"}],"responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Violation"}}}},"description":"the violations"}},"tags":["drift"],"operationId":"listViolations"},"parameters":[{"name":"proxy_id","in":"path","schema":{"type":"integer"},"required":true}]},"/proxies/{proxy_id}/publish":{"post":{"responses":{"200":{"description":"the proxy, now serving it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proxy"}}}},"404":{"$ref":"#/components/responses/NotFound"}},"tags":["specs"],"operationId":"publishSpec","summary":"Publish a version","requestBody":{"content":{"application/json":{"schema":{"properties":{"version":{"type":"integer"}},"type":"object","required":["version"]}}},"required":true}},"parameters":[{"name":"proxy_id","in":"path","required":true,"schema":{"type":"integer"}}]},"/proxies/{proxy_id}":{"delete":{"tags":["proxies"],"responses":{"404":{"$ref":"#/components/responses/NotFound"},"204":{"description":"gone"}},"operationId":"deleteProxy","summary":"Delete a proxy"},"parameters":[{"in":"path","name":"proxy_id","required":true,"schema":{"type":"integer"}}],"patch":{"summary":"Change a proxy's name, upstream or mode","requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"upstream":{"type":"string"},"mode":{"enum":["observe","enforce"],"type":"string"},"name":{"type":"string"}},"type":"object"}}}},"responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proxy"}}},"description":"the proxy as it now stands"},"400":{"$ref":"#/components/responses/NotFound"}},"tags":["proxies"],"operationId":"updateProxy"},"get":{"summary":"One proxy","operationId":"getProxy","responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"description":"the proxy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proxy"}}}}},"tags":["proxies"]}},"/proxies/{proxy_id}/coverage":{"parameters":[{"required":true,"schema":{"type":"integer"},"name":"proxy_id","in":"path"}],"get":{"responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Coverage"},"type":"array"}}},"description":"coverage per operation"}},"tags":["drift"],"operationId":"getCoverage","summary":"How much of the traffic was actually weighed"}},"/proxies/{proxy_id}/environments/{name}":{"parameters":[{"required":true,"schema":{"type":"integer"},"name":"proxy_id","in":"path"},{"schema":{"type":"string"},"required":true,"in":"path","name":"name"}],"delete":{"operationId":"deleteEnvironment","responses":{"204":{"description":"gone; gateways fall back to the published version"},"404":{"$ref":"#/components/responses/NotFound"}},"tags":["environments"],"summary":"Remove an environment"}},"/proxies/{proxy_id}/environments":{"parameters":[{"schema":{"type":"integer"},"required":true,"name":"proxy_id","in":"path"}],"get":{"summary":"Named pointers at versions","operationId":"listEnvironments","tags":["environments"],"responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"description":"the environments","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Environment"},"type":"array"}}}}}},"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"pattern":"^[a-z0-9][a-z0-9_-]{0,31}$","type":"string"},"version":{"type":["integer","null"]}}}}},"required":true},"summary":"Point an environment at a version","operationId":"setEnvironment","tags":["environments"],"responses":{"400":{"$ref":"#/components/responses/NotFound"},"200":{"description":"where it now points","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Environment"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/proxies/{proxy_id}/alerts/{alert_id}":{"patch":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}}},"required":true},"summary":"Silence a rule, or wake it up again","tags":["alerts"],"responses":{"200":{"description":"the rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"404":{"$ref":"#/components/responses/NotFound"}},"operationId":"updateAlert"},"parameters":[{"schema":{"type":"integer"},"required":true,"name":"proxy_id","in":"path"},{"schema":{"type":"integer"},"required":true,"in":"path","name":"alert_id"}],"delete":{"operationId":"deleteAlert","tags":["alerts"],"responses":{"204":{"description":"gone"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Remove a rule"}},"/proxies/{proxy_id}/specs/{version_id}":{"get":{"summary":"One version's document, verbatim","operationId":"getSpec","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"the bytes that were uploaded"},"404":{"$ref":"#/components/responses/NotFound"}},"tags":["specs"]},"parameters":[{"required":true,"schema":{"type":"integer"},"name":"proxy_id","in":"path"},{"required":true,"schema":{"type":"integer"},"in":"path","name":"version_id"}]},"/proxies/{proxy_id}/specs":{"post":{"operationId":"createSpec","responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"description":"those bytes were already a version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpecVersion"}}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpecVersion"}}},"description":"the new version"},"400":{"$ref":"#/components/responses/NotFound"}},"tags":["specs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"spec":{"type":"string"}}}}}},"summary":"Add a spec version, from bytes or from a URL"},"get":{"operationId":"listSpecs","responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SpecVersion"}}}},"description":"the versions"}},"tags":["specs"],"summary":"The spec versions of a proxy"},"parameters":[{"required":true,"schema":{"type":"integer"},"in":"path","name":"proxy_id"}]},"/proxies":{"get":{"summary":"Every proxy on the account","tags":["proxies"],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Proxy"}}}},"description":"the proxies"},"401":{"$ref":"#/components/responses/Denied"}},"operationId":"listProxies"},"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"spec":{"type":"string"},"spec_url":{"type":"string"},"name":{"type":"string","minLength":1},"upstream":{"type":"string"}},"type":"object","required":["name"]}}}},"summary":"Create a proxy","operationId":"createProxy","tags":["proxies"],"responses":{"401":{"$ref":"#/components/responses/Denied"},"400":{"$ref":"#/components/responses/NotFound"},"201":{"description":"created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proxy"}}}}}}},"/proxies/{proxy_id}/examples":{"put":{"description":"Upserts on (operation_id, status, name): the same triple replaces its body, a new one is created. The body must be valid JSON and validate against that response's schema, or the request is refused - the mock is never made to serve a body its own validator would reject. Applying the change republishes the proxy, so the live mock returns it within a poll.","summary":"Create or update a mock example","requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"media_type":{"default":"application/json","type":"string"},"status":{"description":"the response status the example is for, e.g. \"200\" or \"default\"","type":"string"},"body":{"type":"string","description":"the example as a JSON string"},"name":{"type":"string","description":"\"\" (the default) is the primary example; a set name is a scenario reached with Prefer: example=<name>"},"operation_id":{"type":"string"}},"required":["operation_id","status","body"],"type":"object"}}}},"operationId":"setExample","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockExample"}}},"description":"the example, created or updated"},"404":{"$ref":"#/components/responses/NotFound"},"400":{"$ref":"#/components/responses/NotFound"}},"tags":["examples"]},"get":{"operationId":"listExamples","tags":["examples"],"responses":{"200":{"description":"the examples","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MockExample"}}}}},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"The mock examples set on a proxy"},"parameters":[{"in":"path","name":"proxy_id","required":true,"schema":{"type":"integer"}}]},"/proxies/{proxy_id}/diff":{"get":{"responses":{"404":{"$ref":"#/components/responses/NotFound"},"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Diff"}}},"description":"the difference"}},"tags":["specs"],"operationId":"getDiff","summary":"What changed between two versions, in contract and in reality","parameters":[{"in":"query","name":"from","schema":{"type":"integer"}},{"name":"to","in":"query","schema":{"type":"integer"}}]},"parameters":[{"name":"proxy_id","in":"path","required":true,"schema":{"type":"integer"}}]},"/proxies/{proxy_id}/examples/{example_id}":{"parameters":[{"in":"path","name":"proxy_id","required":true,"schema":{"type":"integer"}},{"in":"path","name":"example_id","required":true,"schema":{"type":"integer"}}],"delete":{"summary":"Remove a mock example","operationId":"deleteExample","responses":{"204":{"description":"gone"},"404":{"$ref":"#/components/responses/NotFound"}},"tags":["examples"]}}},"openapi":"3.1.0"}