openapi: 3.0.3 info: title: Coval Agents Review Projects 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: Review Projects description: Project CRUD operations paths: /review-projects: get: operationId: listReviewProjects summary: List review projects description: List review projects for your organization with pagination. tags: - Review Projects security: - ApiKeyAuth: [] parameters: - name: page_size in: query required: false schema: type: integer minimum: 1 maximum: 100 default: 50 description: Maximum number of results per page - name: page_token in: query required: false schema: type: string description: Opaque pagination token from previous response - name: order_by in: query required: false schema: type: string example: -create_time description: 'Sort field and direction. Prefix with `-` for descending. Valid fields: `create_time`, `update_time`, `display_name`. ' responses: '200': description: Projects retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListReviewProjectsResponse' examples: success: $ref: '#/components/examples/ListProjectsSuccess' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalError' post: operationId: createReviewProject summary: Create review project description: 'Create a new review project. Automatically generates annotations for every (simulation, metric, assignee) combination. ' tags: - Review Projects security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateReviewProjectRequest' examples: basic: summary: Create a project value: display_name: Q1 Voice Agent Review assignees: - alice@company.com - bob@company.com linked_simulation_ids: - sim-output-001 - sim-output-002 linked_metric_ids: - metric-accuracy - metric-latency responses: '201': description: Project created successfully content: application/json: schema: $ref: '#/components/schemas/CreateReviewProjectResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalError' /review-projects/{project_id}: get: operationId: getReviewProject summary: Get review project description: Get a single review project by ID. tags: - Review Projects security: - ApiKeyAuth: [] parameters: - name: project_id in: path required: true schema: type: string description: The project ID (ULID) responses: '200': description: Project retrieved successfully content: application/json: schema: $ref: '#/components/schemas/GetReviewProjectResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' patch: operationId: updateReviewProject summary: Update review project description: Partially update a review project. tags: - Review Projects security: - ApiKeyAuth: [] parameters: - name: project_id in: path required: true schema: type: string description: The project ID (ULID) requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateReviewProjectRequest' examples: update_name: summary: Update project name value: display_name: Updated Project Name update_assignees: summary: Update assignees value: assignees: - alice@company.com - charlie@company.com responses: '200': description: Project updated successfully content: application/json: schema: $ref: '#/components/schemas/UpdateReviewProjectResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' delete: operationId: deleteReviewProject summary: Delete review project description: Delete a review project. This permanently removes the project record. tags: - Review Projects security: - ApiKeyAuth: [] parameters: - name: project_id in: path required: true schema: type: string description: The project ID (ULID) responses: '200': description: Project deleted successfully content: application/json: schema: type: object example: {} '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /review-projects/{project_id}/metric-agreement: get: operationId: getReviewProjectMetricAgreement summary: Get project metric agreement description: Machine-vs-human agreement by metric for one review project. The project resolves to its linked simulations and metrics; agreement is computed over that derived scope. tags: - Review Projects security: - ApiKeyAuth: [] parameters: - name: project_id in: path required: true schema: type: string description: The project ID (ULID) responses: '200': description: Agreement computed successfully content: application/json: schema: $ref: '#/components/schemas/GetProjectMetricAgreementResponse' '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' /review-projects/{project_id}/insights: get: operationId: getReviewProjectInsights summary: Get project insights description: Project-level human-review insights (label and metric stats) over a date range. tags: - Review Projects security: - ApiKeyAuth: [] parameters: - name: project_id in: path required: true schema: type: string description: The project ID (ULID) - name: start_date in: query required: true schema: type: string format: date-time description: Start of the insights window (ISO-8601). - name: end_date in: query required: true schema: type: string format: date-time description: End of the insights window (ISO-8601); must be after start_date. - name: label_triage_time_basis in: query required: false schema: type: string enum: - simulation - label default: simulation description: Whether label triage timing is anchored to the simulation or the label. responses: '200': description: Insights computed successfully content: application/json: schema: $ref: '#/components/schemas/GetHumanReviewProjectInsightsResponse' '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' 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 Forbidden: description: Insufficient permissions 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 reviews 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: Authentication failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: UNAUTHENTICATED message: Authentication failed details: - field: X-API-Key description: Invalid or missing API key NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: NOT_FOUND message: Resource not found details: - field: annotation_id description: Annotation not found or not accessible by your organization BadRequest: description: Invalid request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: INVALID_ARGUMENT message: Invalid request body details: - field: simulation_output_id description: simulation_output_id is required schemas: ProjectType: type: string enum: - PROJECT_COLLABORATIVE - PROJECT_INDIVIDUAL default: PROJECT_INDIVIDUAL description: 'Project type: COLLABORATIVE (shared annotations) or INDIVIDUAL (per-assignee annotations)' ReviewProjectResource: type: object description: A single review project resource. required: - name - id - display_name - assignees - linked_simulation_ids - linked_metric_ids - project_type - notifications - create_time - update_time properties: name: type: string description: 'Resource name: review-projects/{id}' example: review-projects/01HXYZ1234567890ABCDEF id: type: string description: Unique project ID (ULID) example: 01HXYZ1234567890ABCDEF display_name: type: string description: Human-readable project name description: type: string nullable: true description: Optional project description assignees: type: array items: type: string description: List of reviewer email addresses linked_simulation_ids: type: array items: type: string description: Simulation output IDs included in this project linked_metric_ids: type: array items: type: string description: Metric IDs included in this project project_type: $ref: '#/components/schemas/ProjectType' notifications: type: boolean description: Whether notifications are enabled project_rules: type: array nullable: true items: $ref: '#/components/schemas/ProjectRule' description: Rules applied to this project (e.g. require notes on disagreement) create_time: type: string format: date-time description: Creation timestamp (ISO 8601) update_time: type: string format: date-time description: Last update timestamp (ISO 8601) ProjectMetricAgreementResource: type: object required: - metric_id - agreements - disagreements - agreement_rate properties: metric_id: type: string agreements: type: integer disagreements: type: integer agreement_rate: type: number CreateReviewProjectResponse: type: object required: - review_project properties: review_project: $ref: '#/components/schemas/ReviewProjectResource' CreateReviewProjectRequest: type: object required: - display_name - assignees - linked_simulation_ids - linked_metric_ids properties: display_name: type: string minLength: 1 maxLength: 200 description: Project name description: type: string nullable: true description: Optional project description assignees: type: array minItems: 1 items: type: string description: Reviewer emails (at least one required) linked_simulation_ids: type: array minItems: 1 items: type: string description: Simulation output IDs (at least one required) linked_metric_ids: type: array minItems: 1 items: type: string description: Metric IDs (at least one required) project_type: $ref: '#/components/schemas/ProjectType' notifications: type: boolean default: true description: Enable notifications for assignees project_rules: type: array nullable: true items: $ref: '#/components/schemas/ProjectRule' description: Rules to apply to this project blind_labeling_shown_metric_ids: type: array nullable: true items: type: string description: Metric IDs whose machine score stays visible during blind labeling ErrorResponse: type: object properties: error: type: object properties: code: type: string description: Error code example: INVALID_ARGUMENT message: type: string description: Human-readable error message example: Invalid request parameter details: type: array description: Detailed error information items: type: object properties: field: type: string nullable: true description: Field that caused the error description: type: string description: Detailed error description UpdateReviewProjectResponse: type: object required: - review_project properties: review_project: $ref: '#/components/schemas/ReviewProjectResource' GetReviewProjectResponse: type: object required: - review_project properties: review_project: $ref: '#/components/schemas/ReviewProjectResource' UpdateReviewProjectRequest: type: object properties: display_name: type: string minLength: 1 maxLength: 200 nullable: true description: Updated project name description: type: string nullable: true description: Updated description assignees: type: array nullable: true items: type: string description: Updated assignee list linked_simulation_ids: type: array nullable: true items: type: string description: Updated simulation IDs add_linked_simulation_ids: type: array nullable: true minItems: 1 items: type: string description: Simulation IDs to add atomically; cannot be combined with other project updates remove_linked_simulation_ids: type: array nullable: true minItems: 1 items: type: string description: Simulation IDs to remove atomically; cannot be combined with other project updates linked_metric_ids: type: array nullable: true items: type: string description: Updated metric IDs notifications: type: boolean nullable: true description: Updated notification setting project_rules: type: array nullable: true items: $ref: '#/components/schemas/ProjectRule' description: Updated project rules blind_labeling_shown_metric_ids: type: array nullable: true items: type: string description: Metric IDs whose machine score stays visible during blind labeling opted_out_assignees: type: array nullable: true items: type: string description: Assignees who opted out of notifications GetHumanReviewProjectInsightsResponse: type: object required: - project - label_overview - label_stats - metric_stats properties: project: type: object properties: ulid: type: string name: type: string linked_metric_ids: type: array items: type: string review_label_options: type: array items: type: string label_overview: type: object description: Aggregate label coverage for the project window. label_stats: type: array items: type: object description: Per-label insight rows. metric_stats: type: array items: type: object description: Per-metric insight rows (counts, agreement rate, simulation output ids). ListReviewProjectsResponse: type: object required: - review_projects properties: review_projects: type: array items: $ref: '#/components/schemas/ReviewProjectResource' next_page_token: type: string nullable: true description: Opaque token for fetching the next page GetProjectMetricAgreementResponse: type: object required: - agreement_by_metric_id properties: agreement_by_metric_id: type: object description: Agreement stats keyed by metric ID. additionalProperties: $ref: '#/components/schemas/ProjectMetricAgreementResource' ProjectRule: type: string enum: - require_disagreement_notes description: 'Project rule: require_disagreement_notes requires reviewer notes when ground truth disagrees with model output' examples: ListProjectsSuccess: summary: Successful project list response value: review_projects: - name: review-projects/01HXYZ1234567890ABCDEF id: 01HXYZ1234567890ABCDEF display_name: Q1 Voice Agent Review description: Review project for Q1 evaluations assignees: - alice@company.com - bob@company.com linked_simulation_ids: - sim-output-001 - sim-output-002 linked_metric_ids: - metric-accuracy - metric-latency project_type: PROJECT_INDIVIDUAL notifications: true create_time: '2026-01-10T08:00:00Z' update_time: '2026-01-15T14:30:00Z' next_page_token: null securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key description: API key for authentication x-visibility: external