{"ok":true,"product":"OpenAPI Contract Audit + Safe Pytest Scaffold","generatedAt":"2026-08-01T18:37:36.308Z","source":{"origin":"https://example.com","path":"/sample-openapi.json","queryPresent":false},"specSha256":"32646380f41dd3832343ad7c263490c5983bdf15c1fd3156ea6658ccc220931b","document":{"title":"Sample Tasks API","version":"1.0.0","openapi":"3.1.0"},"analysis":{"score":93,"grade":"A","counts":{"high":0,"medium":1,"low":1},"truncated":false,"totalFindings":2,"findings":[{"severity":"medium","code":"OPERATION_ID_MISSING","location":"paths./tasks/{id}.get","message":"GET /tasks/{id} has no operationId.","recommendation":"Add a stable, unique operationId for SDKs and agent callers."},{"severity":"low","code":"SERVER_ERROR_RESPONSE_MISSING","location":"paths./tasks/{id}.get","message":"GET /tasks/{id} does not document a 5xx or default error.","recommendation":"Document a reusable server-error response."}],"inventory":{"paths":1,"operations":1,"methods":{"GET":1},"schemas":1,"securitySchemes":0,"servers":1}},"scaffold":{"filename":"test_openapi_contract.py","language":"python","safeMethodsOnly":true,"generatedTests":1,"skippedMutating":0,"truncated":false,"code":"import os\n\nimport pytest\n\nrequests = pytest.importorskip(\"requests\")\nBASE_URL = os.getenv(\"OPENAPI_TEST_BASE_URL\", \"https://api.example.com\").rstrip(\"/\")\n\ndef test_get_tasks_id_1():\n    url = BASE_URL + \"/tasks/00000000-0000-4000-8000-000000000000\"\n    response = requests.request(\"GET\", url, timeout=20)\n    assert response.status_code in [200, 404]\n"},"safety":{"publicHttpsOnly":true,"redirectsFollowed":false,"maxSpecBytes":1500000,"resolvedAddress":{"address":"93.184.216.34","family":4},"apiOperationsCalled":0,"mutatingTestsGenerated":0,"credentialsUsed":false},"reportMarkdown":"# OpenAPI Contract Audit: Sample Tasks API\n\nGenerated: 2026-08-01T18:37:36.308Z\nSource: https://example.com/sample-openapi.json\nSpec SHA-256: 32646380f41dd3832343ad7c263490c5983bdf15c1fd3156ea6658ccc220931b\nScore: 93/100 (A)\nOperations: 1\nFindings: 0 high, 1 medium, 1 low\n\n## Findings\n\n| Severity | Code | Location | Finding | Recommendation |\n| --- | --- | --- | --- | --- |\n| medium | OPERATION_ID_MISSING | paths./tasks/{id}.get | GET /tasks/{id} has no operationId. | Add a stable, unique operationId for SDKs and agent callers. |\n| low | SERVER_ERROR_RESPONSE_MISSING | paths./tasks/{id}.get | GET /tasks/{id} does not document a 5xx or default error. | Document a reusable server-error response. |\n\n## Safe Pytest Scaffold\n\nThe generated scaffold exercises only GET, HEAD, and OPTIONS operations. Review it and set `OPENAPI_TEST_BASE_URL` to an authorized target before running.\n\n```python\nimport os\n\nimport pytest\n\nrequests = pytest.importorskip(\"requests\")\nBASE_URL = os.getenv(\"OPENAPI_TEST_BASE_URL\", \"https://api.example.com\").rstrip(\"/\")\n\ndef test_get_tasks_id_1():\n    url = BASE_URL + \"/tasks/00000000-0000-4000-8000-000000000000\"\n    response = requests.request(\"GET\", url, timeout=20)\n    assert response.status_code in [200, 404]\n```\n\n## Safety\n\n- The service fetched one public HTTPS OpenAPI document with redirects disabled and a strict size cap.\n- DNS was validated and the outbound connection was pinned to the validated public address.\n- No API operations were called, no credentials were requested, and no mutating tests were generated.\n","sample":true,"price":"$15","currency":"USDC","network":"eip155:8453","payTo":"0xd3CE8223E6b0F446a887953aF623B9c72233Ba39"}