{
  "openapi": "3.0.0",
  "info": {
    "title": "IdentifAI API v2",
    "version": "2.0.0",
    "description": "API v2 for batch tampering detection on ticket images. This API allows you to submit multiple tickets for analysis and retrieve results for tampering detection."
  },
  "servers": [
    {
      "url": "https://api.identifai.net"
    }
  ],
  "tags": [
    {
      "name": "Tampering Detection",
      "description": "Batch tampering detection endpoints"
    }
  ],
  "paths": {
    "/api/v2/tampering/tickets/{batch_id}": {
      "get": {
        "summary": "Get tickets analysis results",
        "description": "Retrieve the tampering detection results for the given batch.",
        "tags": [
          "Tampering Detection"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The batch identifier for which to retrieve tampering analysis results"
          }
        ],
        "responses": {
          "200": {
            "description": "Analysis results retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResultsResponse"
                },
                "example": {
                  "identifier": "674a3c9b8e2d4f12b7c9a8d3",
                  "done": false,
                  "total_results": 2,
                  "results": [
                    {
                      "identifier": "674a3c9b8e2d4f12b7c9a8d4",
                      "ref_id": "TICKET-001",
                      "status": "done",
                      "hash": "862bb7de43b131a38b64753269d643443a21069a04ab66a56c9818956f590cb9",
                      "name": "ticket_001.jpg",
                      "verdict": {
                        "confidence": 1,
                        "classification": "tampered"
                      },
                      "verdicts": [
                        {
                          "heuristic": "heuristic_name_1",
                          "description": "Human readable description of the heuristic_name_1",
                          "classification": "tampered"
                        },
                        {
                          "heuristic": "heuristic_name_2",
                          "description": "Human readable description of the heuristic_name_2",
                          "classification": "tampered"
                        },
                        {
                          "heuristic": "heuristic_name_3",
                          "description": "Human readable description of the heuristic_name_3",
                          "classification": "tampered"
                        },
                        {
                          "heuristic": "heuristic_name_4",
                          "description": "Human readable description of the heuristic_name_4",
                          "classification": "authentic"
                        }
                      ],
                      "results": [
                        {
                          "model": "Ellen",
                          "unknown": false,
                          "elapsed_time": 0.1473182961344719,
                          "classification": [
                            {
                              "label": "human",
                              "score": 0.15
                            },
                            {
                              "label": "artificial",
                              "score": 0.85
                            }
                          ],
                          "classification_details": {
                            "confidence": 0.85,
                            "performance": [
                              {
                                "name": "classification",
                                "value": 0.1473182961344719
                              }
                            ]
                          }
                        }
                      ],
                      "c2pa": null
                    },
                    {
                      "identifier": "674a3c9b8e2d4f12b7c9a8d5",
                      "ref_id": "TICKET-002",
                      "status": "inprogress"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request - Invalid identifiers",
            "content": {
              "application/json": {
                "example": {
                  "error": "Invalid request",
                  "message": "identifiers array cannot be empty"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing API key",
            "content": {
              "application/json": {
                "example": {
                  "error": "Unauthorized",
                  "message": "Invalid or missing API key"
                }
              }
            }
          },
          "404": {
            "description": "One or more identifiers not found",
            "content": {
              "application/json": {
                "example": {
                  "error": "Not found",
                  "message": "Batch not found",
                  "batch_id": "674a3c9b8e2d4f12b7c9a8d9"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/tampering/tickets": {
      "post": {
        "summary": "Submit tickets for analysis",
        "description": "Submit a batch of ticket images for **tampering** detection. Each ticket can have an external ID that will be returned in the response for easier tracking.",
        "tags": [
          "Tampering Detection"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "tickets": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "Array of ticket files (images or PDF) to analyze"
                  },
                  "ref_ids": {
                    "type": "string",
                    "description": "String containing a list of comma-separated ref_ids. The number of items must match the length of tickets array if provided.",
                    "example": "Ticket-1, Ticket-2, Ticket-3"
                  },
                  "models": {
                    "type": "string",
                    "description": "Optional string of comma-separated model names to use for tampering detection. If not given, all available models for your tier will be used. If empty, no classification will be performed.",
                    "example": "Model-1, Model-2, Model-3"
                  }
                },
                "required": [
                  "tickets"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch submission successful. Returns the list of analysis identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchSubmissionResponse"
                },
                "example": {
                  "batch_id": "674a3c9b8e2d4f12b7c9a8d3",
                  "total_tickets": 3,
                  "submissions": [
                    {
                      "identifier": "674a3c9b8e2d4f12b7c9a8d4",
                      "ref_id": "Ticket-001"
                    },
                    {
                      "identifier": "674a3c9b8e2d4f12b7c9a8d5",
                      "ref_id": "Ticket-002"
                    },
                    {
                      "identifier": "674a3c9b8e2d4f12b7c9a8d6",
                      "ref_id": "Ticket-003"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request - Invalid input parameters",
            "content": {
              "application/json": {
                "example": {
                  "error": "Invalid request",
                  "message": "The number of ref_ids must match the number of tickets"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing API key",
            "content": {
              "application/json": {
                "example": {
                  "error": "Unauthorized",
                  "message": "Invalid or missing API key"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large - Batch size exceeds limit",
            "content": {
              "application/json": {
                "example": {
                  "error": "Payload too large",
                  "message": "Maximum batch size is 10 tickets"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/submissions/{type}/{identifier}/download": {
      "get": {
        "summary": "Sample download URL",
        "description": "Redirects to a pre-signed URL to download the file associated with the specified submission.",
        "operationId": "downloadSample",
        "parameters": [
          {
            "name": "type",
            "in": "path",
            "required": true,
            "description": "The type of the file, which can be one of the following: audio, video, or image.",
            "schema": {
              "type": "string",
              "enum": [
                "audio",
                "video",
                "image"
              ]
            }
          },
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "description": "The unique identifier of the submission. For video submissions, you can also use a frame/audio track identifier to download a specific frame or audio track.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirects to the pre-signed URL for downloading the file. The URL is valid for 60 minutes.",
            "headers": {
              "Location": {
                "description": "The pre-signed URL to download the file.",
                "schema": {
                  "type": "string",
                  "example": "https://s3.identifai.example.com/bucket/path/to/file.mp4?X-Amz-Signature=12345"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Missing or invalid API key."
          },
          "403": {
            "description": "Forbidden - User does not have the required permissions."
          },
          "404": {
            "description": "Not Found - Submission or file not found."
          },
          "429": {
            "description": "Too Many Requests - Rate Limit exceeded."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    },
    "schemas": {
      "BatchSubmissionResponse": {
        "type": "object",
        "properties": {
          "batch_id": {
            "type": "string",
            "description": "Unique identifier for this batch submission"
          },
          "total_tickets": {
            "type": "integer",
            "description": "Total number of tickets submitted in this batch"
          },
          "submissions": {
            "type": "array",
            "description": "List of image submission identifiers created. The list could be greater than the number of tickets if multiple images have been extracted from a single ticket (e.g. PDF file). In this case, multiple submission will refer to the same ref_id.",
            "items": {
              "$ref": "#/components/schemas/AnalysisIdentifier"
            }
          }
        }
      },
      "AnalysisIdentifier": {
        "type": "object",
        "properties": {
          "identifier": {
            "type": "string",
            "description": "Internal analysis identifier"
          },
          "ref_id": {
            "type": "string",
            "description": "Reference ID provided during submission (if any)"
          }
        }
      },
      "BatchResultsResponse": {
        "type": "object",
        "properties": {
          "identifier": {
            "type": "string",
            "description": "Batch identifier for this analysis"
          },
          "done": {
            "type": "boolean",
            "description": "Indicates if all analyses in the batch are completed"
          },
          "total_results": {
            "type": "integer",
            "description": "Total number of results returned"
          },
          "results": {
            "type": "array",
            "description": "Array of tampering analysis results",
            "items": {
              "$ref": "#/components/schemas/TamperingResult"
            }
          }
        }
      },
      "TamperingResult": {
        "type": "object",
        "properties": {
          "identifier": {
            "type": "string",
            "description": "Internal analysis identifier"
          },
          "ref_id": {
            "type": "string",
            "description": "Reference ID associated with this ticket"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "inprogress",
              "done",
              "errored"
            ],
            "description": "Current status of the analysis"
          },
          "hash": {
            "type": "string",
            "description": "SHA-256 hash of the image (only if completed)"
          },
          "name": {
            "type": "string",
            "description": "Original filename of the ticket (only if completed)"
          },
          "verdict": {
            "$ref": "#/components/schemas/OverallTamperingVerdict",
            "description": "Primary verdict for tampering detection (only if completed)"
          },
          "verdicts": {
            "type": "array",
            "description": "All verdicts from different heuristics (only if completed)",
            "items": {
              "$ref": "#/components/schemas/TamperingVerdict"
            }
          },
          "results": {
            "type": "array",
            "description": "Detailed results from each model (only if completed)",
            "items": {
              "$ref": "#/components/schemas/ModelResult"
            }
          },
          "c2pa": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/C2PA"
              }
            ],
            "description": "Coalition for Content Provenance and Authenticity information that certifies the source and history of media content. Contains manifests, validation results, and signature information. Null if the image doesn't contain C2PA metadata."
          }
        },
        "required": [
          "identifier",
          "status"
        ]
      },
      "C2PA": {
        "type": "object",
        "properties": {
          "manifests": {
            "type": "object",
            "description": "Dictionary of C2PA manifests, keyed by manifest URN. Each manifest contains information about the content's creation and modification history.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "description": "URN identifier for this manifest"
                },
                "title": {
                  "type": "string",
                  "description": "Human-readable title of the manifest"
                },
                "assertions": {
                  "type": "array",
                  "description": "List of cryptographic assertions about the content",
                  "items": {
                    "type": "object",
                    "properties": {
                      "label": {
                        "type": "string",
                        "description": "Type of assertion (e.g., 'c2pa.actions.v2')"
                      },
                      "data": {
                        "type": "object",
                        "description": "Assertion data content"
                      }
                    }
                  }
                },
                "ingredients": {
                  "type": "array",
                  "description": "List of source materials used to create this content",
                  "items": {
                    "type": "object",
                    "properties": {
                      "label": {
                        "type": "string",
                        "description": "Type of ingredient"
                      },
                      "title": {
                        "type": "string",
                        "description": "Name of the ingredient"
                      },
                      "format": {
                        "type": "string",
                        "description": "File format of the ingredient"
                      },
                      "relationship": {
                        "type": "string",
                        "description": "Relationship to the parent content (e.g., 'componentOf')"
                      },
                      "active_manifest": {
                        "type": "string",
                        "description": "URN of the ingredient's active manifest"
                      },
                      "validation_results": {
                        "type": "object",
                        "description": "Validation results for this ingredient"
                      }
                    }
                  }
                },
                "instance_id": {
                  "type": "string",
                  "description": "XMP instance ID"
                },
                "signature_info": {
                  "type": "object",
                  "description": "Information about the cryptographic signature",
                  "properties": {
                    "alg": {
                      "type": "string",
                      "description": "Signature algorithm used (e.g., 'Es256')"
                    },
                    "issuer": {
                      "type": "string",
                      "description": "Certificate issuer"
                    },
                    "common_name": {
                      "type": "string",
                      "description": "Common name from the certificate"
                    },
                    "cert_serial_number": {
                      "type": "string",
                      "description": "Certificate serial number"
                    }
                  }
                },
                "claim_generator_info": {
                  "type": "array",
                  "description": "Information about the software that generated the claim",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "Name of the claim generator software"
                      }
                    }
                  }
                }
              }
            }
          },
          "active_manifest": {
            "type": "string",
            "description": "URN of the currently active manifest"
          },
          "validation_state": {
            "type": "string",
            "enum": [
              "Valid",
              "Invalid",
              "Unknown"
            ],
            "description": "Overall validation state of the C2PA data"
          },
          "validation_status": {
            "type": "array",
            "description": "List of validation status messages",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string",
                  "description": "URN or URL of the validated element"
                },
                "code": {
                  "type": "string",
                  "description": "Validation status code"
                },
                "explanation": {
                  "type": "string",
                  "description": "Human-readable explanation of the validation result"
                }
              }
            }
          },
          "validation_results": {
            "type": "object",
            "description": "Detailed validation results",
            "properties": {
              "activeManifest": {
                "type": "object",
                "properties": {
                  "failure": {
                    "type": "array",
                    "description": "List of validation failures",
                    "items": {
                      "type": "object"
                    }
                  },
                  "success": {
                    "type": "array",
                    "description": "List of successful validations",
                    "items": {
                      "type": "object"
                    }
                  },
                  "informational": {
                    "type": "array",
                    "description": "Informational validation messages",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              },
              "ingredientDeltas": {
                "type": "array",
                "description": "Validation deltas for ingredients",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "OverallTamperingVerdict": {
        "type": "object",
        "properties": {
          "confidence": {
            "type": "number",
            "format": "float",
            "description": "Confidence score between 0 and 1"
          },
          "classification": {
            "type": "string",
            "enum": [
              "authentic",
              "tampered"
            ],
            "description": "Classification result: authentic, or tampered"
          }
        }
      },
      "TamperingVerdict": {
        "type": "object",
        "properties": {
          "heuristic": {
            "type": "string",
            "description": "Name of the heuristic/algorithm used"
          },
          "description": {
            "type": "string",
            "description": "Description of the heuristic/algorithm"
          },
          "classification": {
            "type": "string",
            "enum": [
              "authentic",
              "tampered"
            ],
            "description": "Classification result: authentic or tampered"
          }
        }
      },
      "ModelResult": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "description": "Name of the model used"
          },
          "unknown": {
            "type": "boolean",
            "description": "Whether the result is uncertain"
          },
          "elapsed_time": {
            "type": "number",
            "format": "float",
            "description": "Time taken for classification in seconds"
          },
          "classification": {
            "type": "array",
            "description": "Classification scores for each label",
            "items": {
              "$ref": "#/components/schemas/ClassificationScore"
            }
          },
          "classification_details": {
            "type": "object",
            "description": "Additional classification details",
            "properties": {
              "confidence": {
                "type": "number",
                "format": "float"
              },
              "performance": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "value": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "ClassificationScore": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "description": "Classification label"
          },
          "score": {
            "type": "number",
            "format": "float",
            "description": "Score for this label between 0 and 1"
          }
        }
      }
    }
  }
}