openapi: 3.0.3 info: title: Coval Agents Reports API version: 1.0.0 description: ' Manage configurations for simulations and evaluations. ' contact: name: Coval API Support email: support@coval.dev url: https://docs.coval.ai license: name: Proprietary url: https://coval.dev/terms servers: - url: https://api.coval.dev/v1 description: Production API security: - ApiKeyAuth: [] tags: - name: Reports description: CRUD operations for saved multi-run reports paths: /reports: get: operationId: listReports summary: List reports description: Retrieve a paginated list of saved reports for the authenticated organization. tags: - Reports security: - ApiKeyAuth: [] parameters: - name: cursor in: query required: false schema: type: string pattern: ^\d+$ description: Cursor from the previous page. example: '50' - name: limit in: query required: false schema: type: integer minimum: 1 maximum: 100 default: 50 description: Maximum number of reports to return. example: 50 responses: '200': description: Reports retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListReportsResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '503': $ref: '#/components/responses/ServiceUnavailable' '500': $ref: '#/components/responses/InternalError' post: operationId: createReport summary: Create report description: 'Create a saved report from existing run IDs. All runs must belong to the authenticated organization. Public reports are shareable without login and mark their included runs public. ' tags: - Reports security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateReportRequest' examples: personaComparison: summary: Compare by persona value: name: Accent sweep run_ids: - 8EktrIgaVxn9LfxkIynagX - 9FltuJhbWyoAMgymJzobhY compare_by: persona permissions: PRIVATE metadataComparison: summary: Compare by metadata value value: name: Plan comparison run_ids: - 8EktrIgaVxn9LfxkIynagX - 9FltuJhbWyoAMgymJzobhY compare_by: metadata metadata_key: customer.plan permissions: PUBLIC responses: '201': description: Report created successfully content: application/json: schema: $ref: '#/components/schemas/CreateReportResponse' examples: created: $ref: '#/components/examples/ReportCreated' '400': description: Invalid request body or validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: missingMetadataKey: value: error: code: INVALID_ARGUMENT message: Invalid request body details: - field: metadata_key description: metadata_key is required when compare_by is metadata invalidRuns: value: error: code: INVALID_ARGUMENT message: Validation failed details: - description: Invalid report run ids. '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '503': $ref: '#/components/responses/ServiceUnavailable' '500': $ref: '#/components/responses/InternalError' /reports/{report_id}: get: operationId: getReport summary: Get report description: Retrieve a saved report by ID. tags: - Reports security: - ApiKeyAuth: [] parameters: - $ref: '#/components/parameters/ReportId' responses: '200': description: Report retrieved successfully content: application/json: schema: $ref: '#/components/schemas/GetReportResponse' examples: success: $ref: '#/components/examples/ReportCreated' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '503': $ref: '#/components/responses/ServiceUnavailable' '500': $ref: '#/components/responses/InternalError' patch: operationId: updateReport summary: Update report description: 'Partially update a saved report. To group by metadata, provide both `compare_by: metadata` and `metadata_key`. ' tags: - Reports security: - ApiKeyAuth: [] parameters: - $ref: '#/components/parameters/ReportId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateReportRequest' examples: rename: summary: Rename a report value: name: Q2 plan comparison metadataGrouping: summary: Update metadata grouping and visibility value: compare_by: metadata metadata_key: customer.plan permissions: PUBLIC responses: '200': description: Report updated successfully content: application/json: schema: $ref: '#/components/schemas/UpdateReportResponse' examples: updated: $ref: '#/components/examples/ReportCreated' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '503': $ref: '#/components/responses/ServiceUnavailable' '500': $ref: '#/components/responses/InternalError' delete: operationId: deleteReport summary: Delete report description: 'Soft-delete a saved report. If the report is public, its run visibility is revoked unless another public report still references the same runs. ' tags: - Reports security: - ApiKeyAuth: [] parameters: - $ref: '#/components/parameters/ReportId' responses: '200': description: Report deleted successfully content: application/json: schema: $ref: '#/components/schemas/DeleteReportResponse' examples: deleted: value: message: Report deleted successfully. '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '503': $ref: '#/components/responses/ServiceUnavailable' '500': $ref: '#/components/responses/InternalError' components: responses: InternalError: description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: INTERNAL message: Internal server error details: - description: An unexpected error occurred while processing the report request Forbidden: description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: PERMISSION_DENIED message: Insufficient permissions details: - field: permissions description: The API key does not include the required report permission. ServiceUnavailable: description: Service temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: INTERNAL message: Service temporarily unavailable details: - description: Database routing is temporarily unavailable. Please retry. Unauthorized: description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: UNAUTHENTICATED message: Authentication failed details: - field: x-api-key description: API key is required in the x-api-key header NotFound: description: Not Found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: NOT_FOUND message: Report not found details: - field: report_id description: Report not found or not authorized. BadRequest: description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: INVALID_ARGUMENT message: Invalid request body details: - field: metadata_key description: metadata_key is required when compare_by is metadata schemas: DeleteReportResponse: type: object required: - message properties: message: type: string example: Report deleted successfully. CompareBy: type: string enum: - none - run - agent - mutation - persona - test_case - metadata default: none description: Dimension to group and compare runs by in the report view. example: persona GetReportResponse: type: object required: - report properties: report: $ref: '#/components/schemas/Report' ErrorDetail: type: object properties: field: type: string nullable: true description: Field that caused the error, when available. example: metadata_key description: type: string description: Human-readable detail about the error. example: metadata_key is required when compare_by is metadata Error: type: object required: - code - message properties: code: type: string enum: - INVALID_ARGUMENT - UNAUTHENTICATED - PERMISSION_DENIED - NOT_FOUND - INTERNAL description: Machine-readable error code. example: INVALID_ARGUMENT message: type: string description: Human-readable error message. example: Invalid request body details: type: array maxItems: 100 items: $ref: '#/components/schemas/ErrorDetail' CreateReportResponse: type: object required: - report properties: report: $ref: '#/components/schemas/Report' UpdateReportRequest: type: object additionalProperties: false minProperties: 1 properties: name: type: string minLength: 1 maxLength: 200 description: Display name for the saved report. example: Q2 plan comparison run_ids: type: array minItems: 1 maxItems: 2000 items: type: string description: Replacement run IDs. All must belong to the authenticated organization. example: - 8EktrIgaVxn9LfxkIynagX - 9FltuJhbWyoAMgymJzobhY simulation_output_ids: type: array maxItems: 10000 items: type: string description: 'Replacement simulation IDs pinning the report to a subset of simulations. When set, this is the report''s authoritative scope. ' example: - AGktrIgaVxn9LfxkIynagX source_human_review_project_id: type: string minLength: 26 maxLength: 26 description: 'Human review project the simulations were sourced from; `simulation_output_ids` must belong to it. Omit to leave unchanged — null is rejected, the linkage cannot be cleared via update. ' example: 01JABCDEFGHJKMNPQRSTVWXYZ0 compare_by: $ref: '#/components/schemas/CompareBy' metadata_key: type: string minLength: 1 maxLength: 200 nullable: true description: Required when changing `compare_by` to `metadata`; otherwise omit it. example: customer.plan permissions: $ref: '#/components/schemas/ReportPermission' UpdateReportResponse: type: object required: - report properties: report: $ref: '#/components/schemas/Report' Report: type: object required: - id - name - run_ids - compare_by - metadata_key - permissions properties: id: type: string minLength: 26 maxLength: 26 description: The report's ULID. Open it in the app at //reports/. example: 01JABCDEFGHJKMNPQRSTVWXYZ0 name: type: string description: Display name for the saved report. example: Plan comparison run_ids: type: array maxItems: 2000 items: type: string description: Run IDs included in the saved report. example: - 8EktrIgaVxn9LfxkIynagX - 9FltuJhbWyoAMgymJzobhY simulation_output_ids: type: array maxItems: 10000 items: type: string description: Simulation IDs pinning the saved report to a subset of simulations; empty for run-scoped reports. example: - AGktrIgaVxn9LfxkIynagX source_human_review_project_id: type: string nullable: true description: Human review project the pinned simulations were sourced from; null when not report-linked. example: 01JABCDEFGHJKMNPQRSTVWXYZ0 compare_by: $ref: '#/components/schemas/CompareBy' metadata_key: type: string nullable: true description: Metadata key used for grouping when `compare_by` is `metadata`; null otherwise. example: customer.plan permissions: $ref: '#/components/schemas/ReportPermission' ErrorResponse: type: object required: - error properties: error: $ref: '#/components/schemas/Error' CreateReportRequest: type: object additionalProperties: false required: - name - run_ids properties: name: type: string minLength: 1 maxLength: 200 description: Display name for the saved report. example: Accent sweep run_ids: type: array minItems: 1 maxItems: 2000 items: type: string description: Run IDs to include in the report. All must belong to the authenticated organization. example: - 8EktrIgaVxn9LfxkIynagX - 9FltuJhbWyoAMgymJzobhY simulation_output_ids: type: array maxItems: 10000 items: type: string description: 'Optional simulation IDs pinning the report to a subset of simulations. When set, this is the report''s authoritative scope. All must belong to the authenticated organization. ' example: - AGktrIgaVxn9LfxkIynagX source_human_review_project_id: type: string minLength: 26 maxLength: 26 nullable: true default: null description: Optional human review project the simulations were sourced from; `simulation_output_ids` must belong to it. example: 01JABCDEFGHJKMNPQRSTVWXYZ0 compare_by: $ref: '#/components/schemas/CompareBy' metadata_key: type: string minLength: 1 maxLength: 200 nullable: true default: null description: 'Metadata key to group by. Required when `compare_by` is `metadata`; otherwise omit it. ' example: customer.plan permissions: $ref: '#/components/schemas/ReportPermission' ListReportsResponse: type: object required: - reports properties: reports: type: array maxItems: 100 items: $ref: '#/components/schemas/Report' next_cursor: type: string nullable: true description: Cursor for fetching the next page of results. example: '50' ReportPermission: type: string enum: - PUBLIC - PRIVATE default: PRIVATE description: PUBLIC creates a login-free shareable report; PRIVATE keeps it organization-only. example: PRIVATE examples: ReportCreated: value: report: id: 01JABCDEFGHJKMNPQRSTVWXYZ0 name: Plan comparison run_ids: - 8EktrIgaVxn9LfxkIynagX - 9FltuJhbWyoAMgymJzobhY compare_by: metadata metadata_key: customer.plan permissions: PUBLIC parameters: ReportId: name: report_id in: path required: true schema: type: string minLength: 26 maxLength: 26 description: Saved report ULID. example: 01JABCDEFGHJKMNPQRSTVWXYZ0 securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key description: API key for authentication x-visibility: external