{
  "openapi": "3.1.1",
  "info": {
    "title": "isGenAI public checker API",
    "version": "1.1.0",
    "description": "Importable contract for the public evidence checker, saved-prompt extraction/optional reconstruction, and health endpoint. Other endpoints documented on /api are outside this contract. Evidence checks and image quality measurements do not establish human authorship. Saved records can be edited; reconstructed prompts describe a similar result and are not recovered originals. Response schemas: isgenai.check.v1 and isgenai.prompt.v1.",
    "termsOfService": "https://isgenai.com/terms",
    "contact": {
      "name": "isGenAI",
      "url": "https://isgenai.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://isgenai.com",
      "description": "Public production API"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Checks",
      "description": "AI-origin evidence checks"
    },
    {
      "name": "Health",
      "description": "Service liveness"
    },
    {
      "name": "Prompts",
      "description": "Read supported saved image prompts or request optional reconstruction when available"
    }
  ],
  "externalDocs": {
    "description": "API instructions and interpretation",
    "url": "https://isgenai.com/api"
  },
  "paths": {
    "/v1/check": {
      "post": {
        "operationId": "checkContent",
        "tags": [
          "Checks"
        ],
        "summary": "Check a file, public URL, text or code for available AI-origin evidence",
        "description": "No API key or account is required for this public endpoint. Send JSON for text/code/URLs or multipart/form-data for uploads. Uploaded content is sent to isGenAI and configured applicable providers may run; private means excluded from public result records, not local-only processing. Set privacy=private explicitly for private URL checks. JSON bodies are limited to 131,072 bytes; a file is limited to 20,971,520 bytes and the full multipart body to 21,037,056 bytes. Provider availability and shared service capacity vary; no per-account quota is promised. Retry HTTP 429 only after Retry-After and use a bounded retry policy.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonCheckInput"
              },
              "examples": {
                "privateText": {
                  "summary": "Check caller-supplied text privately",
                  "value": {
                    "text": "This is a sample paragraph submitted for an evidence check.",
                    "privacy": "private",
                    "public_receipt": false
                  }
                },
                "privateCode": {
                  "summary": "Check caller-supplied code privately",
                  "value": {
                    "code": "function add(a, b) { return a + b; }",
                    "language": "JavaScript",
                    "privacy": "private",
                    "public_receipt": false
                  }
                },
                "privateUrl": {
                  "summary": "Check a public fixture URL without publishing a receipt or result",
                  "value": {
                    "url": "https://isgenai.com/examples/saved-details/with-saved-details.png",
                    "privacy": "private",
                    "public_receipt": false
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/MultipartCheckInput"
              },
              "encoding": {
                "file": {
                  "contentType": "application/octet-stream"
                }
              },
              "examples": {
                "privateImageUpload": {
                  "summary": "Bind the file field to local image bytes in your client; @picture.png is curl notation",
                  "description": "Use curl -F file=@picture.png -F privacy=private -F public_receipt=false. The file part is binary, not a filename string in the actual HTTP body.",
                  "value": {
                    "file": "(binary PNG, JPEG, WebP, AVIF or single-page classic TIFF bytes)",
                    "privacy": "private",
                    "public_receipt": "false"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed check; origin can remain unresolved and individual adapters can be unavailable.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckResponse"
                },
                "examples": {
                  "privateText": {
                    "summary": "Actual offline check of the synthetic text request",
                    "description": "Generated locally from this implementation with optional model calls disabled. IDs, timestamps, provider status and results vary in real checks; this is not a detector benchmark.",
                    "value": {
                      "schema": "isgenai.check.v1",
                      "id": "chk_fff33e0f-41b1-4c28-b587-92f8bd19debf",
                      "created_at": "2026-09-23T23:51:21.070Z",
                      "input": {
                        "kind": "text",
                        "privacy": "private",
                        "file_name": "pasted-text.txt"
                      },
                      "content": {
                        "id": "cnt_a48be5fbf8078962f160f3e8",
                        "sha256": "a48be5fbf8078962f160f3e852cae9057727561211eb23d5ccae87abb4e4d0c9",
                        "media_type": "text/plain",
                        "byte_size": 59
                      },
                      "case": {
                        "id": "case_text_a48be5fbf8078962f160f3e8",
                        "url": "https://isgenai.com/case/case_text_a48be5fbf8078962f160f3e8",
                        "headline": "Origin unresolved",
                        "status": "ORIGIN_UNRESOLVED",
                        "copy_relationship": "new_case",
                        "related_copies": 0,
                        "submit_proof_url": "https://isgenai.com/case/case_text_a48be5fbf8078962f160f3e8#submit-proof"
                      },
                      "verdict": {
                        "code": "ORIGIN_UNRESOLVED",
                        "label": "Origin unresolved",
                        "summary": "No reliable origin evidence survived in this copy.",
                        "confidence": "low",
                        "caveats": [
                          "No evidence does not mean human-made. This does not prove it was human-made."
                        ]
                      },
                      "evidence": [],
                      "disclosures": [],
                      "adapter_runs": [
                        {
                          "id": "run_0add5256-6dd1-4e06-a727-fa9c959ab0f1",
                          "check_id": "chk_fff33e0f-41b1-4c28-b587-92f8bd19debf",
                          "adapter": "text_ai_clue_checker",
                          "status": "available",
                          "started_at": "2026-09-23T23:51:21.070Z",
                          "completed_at": "2026-09-23T23:51:21.083Z",
                          "duration_ms": 0,
                          "outcome": "no_ai_clues_found",
                          "details": {
                            "bytes": 59,
                            "disclosure_count": 0,
                            "ai_tool_mentions": 0
                          }
                        },
                        {
                          "id": "run_98b95531-c0c2-42f0-8fc2-c85033413beb",
                          "check_id": "chk_fff33e0f-41b1-4c28-b587-92f8bd19debf",
                          "adapter": "deepseek_text",
                          "status": "not_configured",
                          "started_at": "2026-09-23T23:51:21.082Z",
                          "completed_at": "2026-09-23T23:51:21.082Z",
                          "duration_ms": 0
                        }
                      ],
                      "variants": {
                        "exact_matches": 0,
                        "near_duplicates": 0,
                        "possible_variants": 0,
                        "items": [],
                        "note": "Known copies are matches inside the isGenAI corpus only."
                      },
                      "cache": {
                        "hit": false
                      },
                      "limitations": [
                        "This checks the pasted text or code only. It cannot prove who typed it or what happened before paste.",
                        "AI tool names in text or code are clues from the available copy, not proof of authorship.",
                        "No evidence does not mean human-made. This does not prove it was human-made."
                      ],
                      "public_result": {
                        "headline": "NO AI SIGNAL DETECTED",
                        "basis": "No direct signal",
                        "facts": [
                          "No direct signal"
                        ],
                        "summary": "No signs of AI were found in this copy.",
                        "caveat": "That does not prove it was human-made."
                      }
                    }
                  },
                  "privateImage": {
                    "summary": "Actual private check of a generated 16 x 12 white PNG",
                    "description": "Generated locally from this implementation with optional model calls disabled. IDs, timestamps, provider status and results vary in real checks; this is not a detector benchmark. Pixel statistics describe this uniform synthetic image, not AI-origin probabilities.",
                    "value": {
                      "schema": "isgenai.check.v1",
                      "id": "chk_5f568bd5-7fd5-4772-9a34-b038b5ad4f11",
                      "created_at": "2026-09-23T23:51:21.203Z",
                      "input": {
                        "kind": "file",
                        "privacy": "private",
                        "file_name": "synthetic-white.png"
                      },
                      "content": {
                        "id": "cnt_6ac079fe12a4de8ff05f0007",
                        "sha256": "6ac079fe12a4de8ff05f00072ccc12d147549af0bdb08a491e652122f888c2d6",
                        "media_type": "image/png",
                        "byte_size": 101,
                        "fingerprint": {
                          "algorithm": "isgenai-dhash-v1",
                          "value": "0000000000000000",
                          "width": 16,
                          "height": 12
                        }
                      },
                      "case": {
                        "id": "case_img_0000000000000000_6ac079fe12a4",
                        "url": "https://isgenai.com/case/case_img_0000000000000000_6ac079fe12a4",
                        "headline": "Origin unresolved",
                        "status": "ORIGIN_UNRESOLVED",
                        "copy_relationship": "new_case",
                        "related_copies": 0,
                        "submit_proof_url": "https://isgenai.com/case/case_img_0000000000000000_6ac079fe12a4#submit-proof"
                      },
                      "verdict": {
                        "code": "ORIGIN_UNRESOLVED",
                        "label": "Origin unresolved",
                        "summary": "No reliable origin evidence survived in this copy.",
                        "confidence": "low",
                        "caveats": [
                          "No evidence does not mean human-made. This does not prove it was human-made."
                        ]
                      },
                      "evidence": [],
                      "disclosures": [],
                      "image_diagnostics": {
                        "version": "isgenai.image-diagnostics.v1",
                        "status": "available",
                        "width": 16,
                        "height": 12,
                        "megapixels": 0,
                        "sample_width": 16,
                        "sample_height": 12,
                        "frames": 1,
                        "scope": "first_frame",
                        "visible_pixel_percent": 100,
                        "transparent_pixel_percent": 0,
                        "brightness_mean": 255,
                        "brightness_stddev": 0,
                        "dark_pixel_percent": 0,
                        "light_pixel_percent": 100,
                        "edge_difference_mean": 0
                      },
                      "adapter_runs": [
                        {
                          "id": "run_b60b9476-b7ae-4eeb-b172-7a043b761474",
                          "check_id": "chk_5f568bd5-7fd5-4772-9a34-b038b5ad4f11",
                          "adapter": "local_c2pa",
                          "status": "available",
                          "started_at": "2026-09-23T23:51:21.111Z",
                          "completed_at": "2026-09-23T23:51:21.196Z",
                          "duration_ms": 85,
                          "outcome": "NO_C2PA_MANIFEST",
                          "details": {
                            "detected": false,
                            "trust_validation": "NOT_PRESENT",
                            "cryptographic_validation": "NOT_PRESENT",
                            "manifest_labels": []
                          }
                        },
                        {
                          "id": "run_789e6027-9511-4472-8712-4d48e4861861",
                          "check_id": "chk_5f568bd5-7fd5-4772-9a34-b038b5ad4f11",
                          "adapter": "iptc_xmp_exif",
                          "status": "available",
                          "started_at": "2026-09-23T23:51:21.196Z",
                          "completed_at": "2026-09-23T23:51:21.199Z",
                          "duration_ms": 3,
                          "outcome": "not_detected",
                          "details": {
                            "width": 16,
                            "height": 12,
                            "format": "png",
                            "fields": []
                          }
                        },
                        {
                          "id": "run_ab8d39c0-d126-4dc8-9b3f-036231c57ef1",
                          "check_id": "chk_5f568bd5-7fd5-4772-9a34-b038b5ad4f11",
                          "adapter": "openai_content_provenance",
                          "status": "not_configured",
                          "started_at": "2026-09-23T23:51:21.199Z",
                          "completed_at": "2026-09-23T23:51:21.199Z",
                          "duration_ms": 0,
                          "outcome": "not_configured",
                          "message": "OPENAI_API_KEY is not configured."
                        },
                        {
                          "id": "run_48c14381-f65c-4067-a41d-23dbca46e8ad",
                          "check_id": "chk_5f568bd5-7fd5-4772-9a34-b038b5ad4f11",
                          "adapter": "deepseek_image",
                          "started_at": "2026-09-23T23:51:21.199Z",
                          "completed_at": "2026-09-23T23:51:21.202Z",
                          "duration_ms": 3,
                          "status": "not_configured",
                          "outcome": "disabled",
                          "details": {
                            "observed_at": "2026-09-23T23:51:21.199Z",
                            "policy_version": "disabled"
                          }
                        }
                      ],
                      "variants": {
                        "exact_matches": 0,
                        "near_duplicates": 0,
                        "possible_variants": 0,
                        "items": [],
                        "note": "Known copies are matches inside the isGenAI corpus only."
                      },
                      "cache": {
                        "hit": false
                      },
                      "limitations": [
                        "No evidence does not mean human-made. This does not prove it was human-made.",
                        "Known copies are matches inside the isGenAI corpus only, not all copies online.",
                        "Public URL checks only inspect public pages and files. Authenticated, paywalled or CAPTCHA-protected workflows are not bypassed.",
                        "Provider checks only run where credentials and approved access are configured."
                      ],
                      "public_result": {
                        "headline": "NO AI SIGNAL DETECTED",
                        "basis": "No direct signal",
                        "facts": [
                          "No direct signal"
                        ],
                        "summary": "No signs of AI were found in this copy.",
                        "caveat": "That does not prove it was human-made."
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid content, malformed JSON/multipart, TIFF restrictions, text over 16,000 UTF-16 units, blocked URL or another handled check failure. Branch on error.code together with HTTP status; error.message provides human-readable context. Unexpected exceptions use check_failed without internal details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckError"
                },
                "examples": {
                  "missingInput": {
                    "value": {
                      "schema": "isgenai.error.v1",
                      "error": {
                        "message": "Send a url, text, code, or file to check.",
                        "code": "missing_input"
                      }
                    }
                  },
                  "textTooLong": {
                    "value": {
                      "schema": "isgenai.error.v1",
                      "error": {
                        "message": "Use up to 16,000 characters of text or code.",
                        "code": "text_too_long"
                      }
                    }
                  },
                  "invalidJson": {
                    "value": {
                      "schema": "isgenai.error.v1",
                      "error": {
                        "code": "invalid_json",
                        "message": "Send valid JSON to check."
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "JSON body, file or multipart body exceeds its applicable byte limit; error.code is too_large. The legacy human-readable message mentions 20 MB even when the 128 KiB JSON cap caused rejection; use the documented per-input byte limits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckError"
                },
                "example": {
                  "schema": "isgenai.error.v1",
                  "error": {
                    "message": "This upload is too large. Use a file under 20 MB.",
                    "code": "too_large"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Shared concurrent check capacity is full; error.code is busy. This is not an authenticated account quota. Respect Retry-After and use a bounded retry policy.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before a bounded retry.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 5
                }
              },
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusyError"
                },
                "example": {
                  "error": {
                    "message": "Checks are busy. Please try again shortly.",
                    "code": "busy"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Health"
        ],
        "summary": "Read service liveness and release identifier",
        "responses": {
          "200": {
            "description": "The route is responding; provider readiness is not tested.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "example": {
                  "ok": true,
                  "service": "isgenai",
                  "release": null,
                  "generated_at": "2026-09-24T00:00:00.000Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/prompt": {
      "post": {
        "operationId": "extractOrReconstructPrompt",
        "tags": [
          "Prompts"
        ],
        "summary": "Read saved image prompts or conditionally reconstruct a prompt",
        "description": "Public endpoint; no account or API key required. Set mode=saved_only explicitly for metadata extraction with no model call or reconstruction fallback. The default auto mode can send an image, text or code to a configured model if a saved image prompt is unavailable. Model availability and shared service limits vary; no paid feature, fixed quota or reconstruction availability is promised here. Uploads are sent to isGenAI; this is not browser-local processing. This endpoint returns a prompt directly and does not create a public case or receipt. The /v1/check privacy and public_receipt fields do not apply. Responses may contain private saved text/settings; do not publish them or put them in shared logs. The route may set an HttpOnly session cookie for service-limit handling.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/MultipartPromptInput"
              },
              "encoding": {
                "file": {
                  "contentType": "image/png, image/jpeg, image/webp, image/avif"
                }
              },
              "examples": {
                "savedOnlyImage": {
                  "summary": "Bind file to image bytes; @picture.png is curl syntax, not the HTTP value",
                  "value": {
                    "file": "(binary image bytes)",
                    "mode": "saved_only"
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonPromptInput"
              },
              "examples": {
                "savedOnlyUrl": {
                  "value": {
                    "url": "https://isgenai.com/examples/saved-details/with-saved-details.png",
                    "mode": "saved_only"
                  }
                },
                "optionalTextReconstruction": {
                  "summary": "May return 503 when reconstruction is unavailable",
                  "value": {
                    "text": "A short synthetic example supplied by the caller.",
                    "mode": "auto"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved image prompt, or conditional auto reconstruction. Inspect status; reconstructed is not a recovered original.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptResponse"
                },
                "examples": {
                  "savedShape": {
                    "summary": "Illustrative saved-record response; not a measured extraction",
                    "value": {
                      "schema": "isgenai.prompt.v1",
                      "status": "saved",
                      "prompt": "A demonstration prompt stored in a controlled image record.",
                      "note": "Found in the file. Saved details can be edited."
                    }
                  },
                  "reconstructedShape": {
                    "summary": "Illustrative response shape only; reconstruction availability is not promised",
                    "value": {
                      "schema": "isgenai.prompt.v1",
                      "status": "reconstructed",
                      "prompt": "Create a similar geometric illustration.",
                      "note": "A prompt for a similar result, not the original."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing/invalid input or mode; invalid JSON/multipart; unsupported image or URL; saved_only with text/code (image_required); empty or overlong text/code (invalid_text). Unexpected request-processing failures return invalid_request. Unsupported images use HTTP 400, not 415.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptError"
                }
              }
            }
          },
          "403": {
            "description": "Cross-site request or disallowed Origin; error.code is invalid_origin. Server/CLI clients do not need an API key.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptError"
                }
              }
            }
          },
          "409": {
            "description": "The downloaded image does not match nonempty expected_sha256; error.code is content_changed.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptError"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 131,072 bytes, multipart body exceeds 21,037,056 bytes (too_large), or image bytes exceed 20,971,520 (invalid_size). Use byte limits rather than the legacy human-readable MB wording.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptError"
                }
              }
            }
          },
          "422": {
            "description": "saved_only completed without a supported saved prompt. This is absence of a supported record, not proof that the image was not AI-generated. No model fallback occurs.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NoSavedPromptError"
                },
                "example": {
                  "error": {
                    "code": "no_saved_prompt",
                    "message": "No supported saved prompt was found in this file."
                  }
                }
              }
            }
          },
          "429": {
            "description": "Shared concurrency is full (busy), or optional reconstruction service limits are reached (limit_reached). These are not promised account quotas. Retry-After is supplied by the shared upload limiter, but is not guaranteed on every 429. Stop a batch; do not immediately retry in a loop.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              },
              "Retry-After": {
                "description": "Optional delay in seconds. Present for the shared upload-capacity response; other 429 branches may omit it.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 5
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/PromptError"
                    },
                    {
                      "$ref": "#/components/schemas/BusyError"
                    }
                  ]
                }
              }
            }
          },
          "502": {
            "description": "Optional reconstruction provider failed or returned an unusable result; error.code is provider_unavailable. Saved-only extraction does not call that provider.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptError"
                }
              }
            }
          },
          "503": {
            "description": "Optional reconstruction is unavailable; error.code is not_configured. This can occur in auto mode after an image has no supported saved prompt or for text/code. Use saved_only for image extraction without a model fallback.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "JsonCheckInput": {
        "type": "object",
        "description": "Send one input field. If multiple nonblank fields are supplied, JSON precedence is code, text, then url. Successful checks may have unresolved origin or unavailable adapters.",
        "properties": {
          "text": {
            "type": "string",
            "description": "Nonblank text. The server trims surrounding whitespace, then accepts at most 16,000 UTF-16 code units (some characters occupy two units).",
            "minLength": 1,
            "maxLength": 16000
          },
          "code": {
            "type": "string",
            "description": "Nonblank text. The server trims surrounding whitespace, then accepts at most 16,000 UTF-16 code units (some characters occupy two units).",
            "minLength": 1,
            "maxLength": 16000
          },
          "url": {
            "type": "string",
            "description": "Public HTTP or HTTPS URL. A missing scheme is normalized to HTTPS. Local/private network destinations are blocked. Authentication, paywalls and CAPTCHAs are not bypassed.",
            "minLength": 1
          },
          "kind": {
            "type": "string",
            "description": "Applies to the text field only; defaults to text. The code field always selects code.",
            "enum": [
              "text",
              "code"
            ]
          },
          "language": {
            "type": "string",
            "description": "Optional language hint included with text/code adapter details."
          },
          "privacy": {
            "type": "string",
            "description": "Files, text and code default to private unless public_receipt=true. URL and article checks default to public. Explicit privacy overrides that choice. Use privacy=private to keep the result out of public records, even when checking a URL; public_receipt=false alone does not make a URL check private.",
            "enum": [
              "private",
              "public"
            ]
          },
          "public_receipt": {
            "type": "boolean",
            "description": "Private checks never publish receipts. For public file/text/code checks, a receipt requires public_receipt=true. Public URL/article checks publish receipts unless public_receipt=false. A public result may be stored without a receipt."
          },
          "source_context": {
            "type": "string",
            "description": "Optional caller-supplied context. Do not include information you do not want processed or, for public checks, published."
          },
          "force_refresh": {
            "type": "boolean",
            "default": false,
            "description": "Requests refresh where supported. It does not bypass provider availability, safety limits, budgets or all provider caches."
          },
          "deep": {
            "type": "boolean",
            "description": "Accepted for compatibility. It currently does not select a separate deep-analysis path or guarantee additional checks."
          }
        },
        "anyOf": [
          {
            "required": [
              "text"
            ]
          },
          {
            "required": [
              "code"
            ]
          },
          {
            "required": [
              "url"
            ]
          }
        ]
      },
      "MultipartCheckInput": {
        "type": "object",
        "description": "Send one content field. Multipart precedence is nonempty file, nonblank url, nonblank code, then nonblank text. The full multipart body is limited to 21,037,056 bytes, including boundaries and fields. Multipart kind/language hints are not supported.",
        "properties": {
          "file": {
            "type": "string",
            "description": "One nonempty file, at most 20,971,520 bytes (20 MiB). Supported image diagnostics: PNG, JPEG, WebP, AVIF and single-page classic TIFF. TIFF files must decode within 40 megapixels; invalid TIFF, multipage TIFF, TIFF subimages/pyramids and BigTIFF return HTTP 400. TIFF statistical detection and prompt reconstruction are unsupported. Other media may yield unavailable/unsupported adapters rather than an HTTP rejection. File bytes are uploaded to isGenAI; this is not a browser-local image tool.",
            "format": "binary",
            "contentMediaType": "application/octet-stream",
            "x-maxSizeBytes": 20971520
          },
          "url": {
            "type": "string",
            "description": "Public HTTP or HTTPS URL. A missing scheme is normalized to HTTPS. Local/private network destinations are blocked. Authentication, paywalls and CAPTCHAs are not bypassed.",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Nonblank text. The server trims surrounding whitespace, then accepts at most 16,000 UTF-16 code units (some characters occupy two units).",
            "minLength": 1,
            "maxLength": 16000
          },
          "code": {
            "type": "string",
            "description": "Nonblank text. The server trims surrounding whitespace, then accepts at most 16,000 UTF-16 code units (some characters occupy two units).",
            "minLength": 1,
            "maxLength": 16000
          },
          "privacy": {
            "type": "string",
            "description": "Files, text and code default to private unless public_receipt=true. URL and article checks default to public. Explicit privacy overrides that choice. Use privacy=private to keep the result out of public records, even when checking a URL; public_receipt=false alone does not make a URL check private.",
            "enum": [
              "private",
              "public"
            ]
          },
          "public_receipt": {
            "type": "string",
            "description": "Private checks never publish receipts. For public file/text/code checks, a receipt requires public_receipt=true. Public URL/article checks publish receipts unless public_receipt=false. A public result may be stored without a receipt. Send true or false as a form field. The server also recognizes 1, yes and on (case-insensitive) as true; other strings are false.",
            "enum": [
              "true",
              "false"
            ]
          },
          "source_context": {
            "type": "string",
            "description": "Optional caller-supplied context. Do not include information you do not want processed or, for public checks, published."
          },
          "force_refresh": {
            "type": "string",
            "description": "Requests refresh where supported. It does not bypass provider availability, safety limits, budgets or all provider caches. Send true or false as a form field. The server also recognizes 1, yes and on (case-insensitive) as true; other strings are false.",
            "enum": [
              "true",
              "false"
            ]
          },
          "deep": {
            "type": "string",
            "description": "Accepted for compatibility. It currently does not select a separate deep-analysis path or guarantee additional checks. Send true or false as a form field. The server also recognizes 1, yes and on (case-insensitive) as true; other strings are false.",
            "enum": [
              "true",
              "false"
            ]
          }
        },
        "anyOf": [
          {
            "required": [
              "file"
            ]
          },
          {
            "required": [
              "url"
            ]
          },
          {
            "required": [
              "text"
            ]
          },
          {
            "required": [
              "code"
            ]
          }
        ]
      },
      "VerdictCode": {
        "type": "string",
        "enum": [
          "AI_INVOLVEMENT_VERIFIED",
          "CAMERA_ORIGIN_VERIFIED",
          "ORIGIN_UNRESOLVED"
        ]
      },
      "Verdict": {
        "type": "object",
        "properties": {
          "code": {
            "$ref": "#/components/schemas/VerdictCode"
          },
          "label": {
            "type": "string",
            "enum": [
              "AI involvement verified",
              "Camera origin verified",
              "Origin unresolved"
            ]
          },
          "summary": {
            "type": "string"
          },
          "confidence": {
            "type": "string",
            "description": "Qualitative confidence in the evidence verdict. This is not a calibrated AI-authorship probability or detector accuracy score.",
            "enum": [
              "high",
              "medium",
              "low"
            ]
          },
          "caveats": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "code",
          "label",
          "summary",
          "confidence",
          "caveats"
        ]
      },
      "PublicResult": {
        "type": "object",
        "description": "Preferred user-facing interpretation. Missing AI signals do not establish human authorship; LIKELY AI is an estimate, not verified origin.",
        "properties": {
          "headline": {
            "type": "string",
            "enum": [
              "AI DETECTED",
              "LIKELY AI",
              "AI EDIT DETECTED",
              "NO AI SIGNAL DETECTED",
              "SIGNALS CONFLICT",
              "SCAN FAILED"
            ]
          },
          "basis": {
            "type": "string",
            "enum": [
              "Source record",
              "Instagram label",
              "Known copy",
              "Visual scan",
              "Public label",
              "Tool mention",
              "No direct signal",
              "Conflict",
              "Unavailable"
            ]
          },
          "summary": {
            "type": "string"
          },
          "facts": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "caveat": {
            "type": "string"
          }
        },
        "required": [
          "headline",
          "basis",
          "summary",
          "facts"
        ]
      },
      "Evidence": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "check_id": {
            "type": "string"
          },
          "content_id": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "class": {
            "type": "string",
            "enum": [
              "cryptographic_provenance",
              "provider_watermark",
              "declarative_metadata",
              "explicit_disclosure",
              "probabilistic_detector",
              "historical_match",
              "variant_match"
            ]
          },
          "mechanism": {
            "type": "string"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "detected",
              "not_detected",
              "manifest_present",
              "invalid",
              "match",
              "unavailable"
            ]
          },
          "strength": {
            "type": "string",
            "enum": [
              "strong",
              "moderate",
              "weak",
              "informational"
            ]
          },
          "directness": {
            "type": "string",
            "enum": [
              "direct",
              "declarative",
              "circumstantial"
            ]
          },
          "summary": {
            "type": "string"
          },
          "snippet": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "details": {
            "type": "object",
            "additionalProperties": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "check_id",
          "provider",
          "class",
          "mechanism",
          "outcome",
          "strength",
          "directness",
          "summary",
          "created_at"
        ]
      },
      "Disclosure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "check_id": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "location": {
            "type": "string",
            "enum": [
              "page_text",
              "page_source",
              "metadata",
              "caption",
              "publisher_context",
              "user_context",
              "source_code"
            ]
          },
          "snippet": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "check_id",
          "source",
          "location",
          "snippet",
          "created_at"
        ]
      },
      "AdapterRun": {
        "type": "object",
        "description": "Check status before using optional adapter-specific details. Fields inside details vary by provider; no fixed classifier score is guaranteed.",
        "properties": {
          "id": {
            "type": "string"
          },
          "check_id": {
            "type": "string"
          },
          "adapter": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "available",
              "not_configured",
              "access_required",
              "unavailable",
              "unsupported_media",
              "rate_limited",
              "error"
            ]
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_ms": {
            "type": "number"
          },
          "outcome": {
            "type": "string"
          },
          "error_code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "id",
          "check_id",
          "adapter",
          "status",
          "started_at",
          "completed_at",
          "duration_ms"
        ]
      },
      "Fingerprint": {
        "type": "object",
        "properties": {
          "algorithm": {
            "type": "string",
            "enum": [
              "isgenai-dhash-v1"
            ]
          },
          "value": {
            "type": "string"
          },
          "width": {
            "type": "integer",
            "minimum": 0
          },
          "height": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "algorithm",
          "value"
        ]
      },
      "Content": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "media_type": {
            "type": "string"
          },
          "byte_size": {
            "type": "integer",
            "minimum": 0
          },
          "fingerprint": {
            "$ref": "#/components/schemas/Fingerprint"
          }
        },
        "required": [
          "id",
          "sha256",
          "media_type",
          "byte_size"
        ]
      },
      "Source": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "publisher": {
            "type": "string"
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "check_id": {
            "type": "string"
          }
        },
        "required": [
          "observed_at",
          "check_id"
        ]
      },
      "Case": {
        "type": "object",
        "description": "Case references may be included for private checks. Their presence does not mean the private case is publicly retrievable.",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "headline": {
            "type": "string",
            "enum": [
              "AI involvement verified",
              "Camera origin verified",
              "Origin unresolved"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/VerdictCode"
          },
          "copy_relationship": {
            "type": "string",
            "enum": [
              "new_case",
              "exact",
              "near_duplicate",
              "possible_variant"
            ]
          },
          "earliest_known_source": {
            "$ref": "#/components/schemas/Source"
          },
          "related_copies": {
            "type": "integer",
            "minimum": 0
          },
          "submit_proof_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "id",
          "url",
          "headline",
          "status",
          "copy_relationship",
          "related_copies",
          "submit_proof_url"
        ]
      },
      "Variant": {
        "type": "object",
        "properties": {
          "content_id": {
            "type": "string"
          },
          "check_id": {
            "type": "string"
          },
          "relationship": {
            "type": "string",
            "enum": [
              "exact",
              "near_duplicate",
              "possible_variant"
            ]
          },
          "distance": {
            "type": "number"
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "verdict_code": {
            "$ref": "#/components/schemas/VerdictCode"
          }
        },
        "required": [
          "content_id",
          "relationship"
        ]
      },
      "Variants": {
        "type": "object",
        "description": "Known-copy matches are limited to the isGenAI corpus, not the entire web.",
        "properties": {
          "exact_matches": {
            "type": "integer",
            "minimum": 0
          },
          "near_duplicates": {
            "type": "integer",
            "minimum": 0
          },
          "possible_variants": {
            "type": "integer",
            "minimum": 0
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Variant"
            }
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "exact_matches",
          "near_duplicates",
          "possible_variants",
          "items",
          "note"
        ]
      },
      "Receipt": {
        "type": "object",
        "description": "Present only when a public receipt was issued. A signed receipt records this check; it does not make every source claim true.",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "hash": {
            "type": "string"
          },
          "signature": {
            "type": "string"
          },
          "key_id": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "hash",
          "signature",
          "key_id"
        ]
      },
      "ImageDiagnosticsAvailable": {
        "type": "object",
        "description": "EXIF-oriented dimensions and descriptive first-frame measurements. Decoding is bounded to 40 million input pixels, and sampling fits inside 512 x 512 without enlargement. Numeric measurements are rounded to two decimal places. No AI-origin score, blur verdict or authorship inference is produced.",
        "properties": {
          "version": {
            "type": "string",
            "enum": [
              "isgenai.image-diagnostics.v1"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "available"
            ]
          },
          "width": {
            "type": "integer",
            "minimum": 1
          },
          "height": {
            "type": "integer",
            "minimum": 1
          },
          "megapixels": {
            "type": "number",
            "minimum": 0
          },
          "sample_width": {
            "type": "integer",
            "minimum": 1,
            "maximum": 512
          },
          "sample_height": {
            "type": "integer",
            "minimum": 1,
            "maximum": 512
          },
          "frames": {
            "type": "integer",
            "minimum": 1
          },
          "scope": {
            "type": "string",
            "enum": [
              "first_frame"
            ]
          },
          "visible_pixel_percent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Percentage of sampled pixels with alpha greater than zero."
          },
          "transparent_pixel_percent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Percentage of sampled pixels with alpha less than one. Partially transparent pixels count in both visible and transparent percentages, so these are not complements."
          },
          "brightness_mean": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 255,
            "description": "Alpha-weighted mean of 0.2126R + 0.7152G + 0.0722B using decoded 8-bit sRGB values; null when no visible sample exists."
          },
          "brightness_stddev": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 127.5,
            "description": "Alpha-weighted standard deviation of the same brightness values; null when no visible sample exists."
          },
          "dark_pixel_percent": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Alpha-weighted percentage with brightness <= 8; null when no visible sample exists."
          },
          "light_pixel_percent": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Alpha-weighted percentage with brightness >= 247; null when no visible sample exists."
          },
          "edge_difference_mean": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 255,
            "description": "Mean absolute brightness difference across horizontal and vertical adjacent samples, weighted by the smaller alpha. Null when no measurable neighbor pair exists, including a one-pixel image."
          }
        },
        "required": [
          "version",
          "status",
          "width",
          "height",
          "megapixels",
          "sample_width",
          "sample_height",
          "frames",
          "scope",
          "visible_pixel_percent",
          "transparent_pixel_percent",
          "brightness_mean",
          "brightness_stddev",
          "dark_pixel_percent",
          "light_pixel_percent",
          "edge_difference_mean"
        ]
      },
      "ImageDiagnosticsUnavailable": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string",
            "enum": [
              "isgenai.image-diagnostics.v1"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "unavailable"
            ]
          },
          "reason": {
            "type": "string",
            "enum": [
              "unsupported_format",
              "decode_failed_or_limit_exceeded"
            ]
          }
        },
        "required": [
          "version",
          "status",
          "reason"
        ],
        "examples": [
          {
            "version": "isgenai.image-diagnostics.v1",
            "status": "unavailable",
            "reason": "decode_failed_or_limit_exceeded"
          }
        ]
      },
      "ImageDiagnostics": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ImageDiagnosticsAvailable"
          },
          {
            "$ref": "#/components/schemas/ImageDiagnosticsUnavailable"
          }
        ],
        "discriminator": {
          "propertyName": "status",
          "mapping": {
            "available": "#/components/schemas/ImageDiagnosticsAvailable",
            "unavailable": "#/components/schemas/ImageDiagnosticsUnavailable"
          }
        }
      },
      "CheckResponse": {
        "type": "object",
        "description": "Fields may be added. Inspect public_result, evidence, adapter_runs and limitations together; an HTTP 200 does not guarantee an available detector or resolved origin. Image diagnostics are optional and do not change the origin verdict.",
        "properties": {
          "schema": {
            "type": "string",
            "enum": [
              "isgenai.check.v1"
            ]
          },
          "id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "input": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "file",
                  "url",
                  "article",
                  "text",
                  "code"
                ]
              },
              "privacy": {
                "type": "string",
                "enum": [
                  "private",
                  "public"
                ]
              },
              "url": {
                "type": "string"
              },
              "final_url": {
                "type": "string",
                "format": "uri"
              },
              "file_name": {
                "type": "string"
              },
              "source_context": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "privacy"
            ]
          },
          "content": {
            "$ref": "#/components/schemas/Content"
          },
          "image_diagnostics": {
            "$ref": "#/components/schemas/ImageDiagnostics"
          },
          "article": {
            "type": "object",
            "properties": {
              "canonical_url": {
                "type": "string",
                "format": "uri"
              },
              "title": {
                "type": "string"
              },
              "publisher": {
                "type": "string"
              },
              "published_at": {
                "type": "string"
              },
              "selected_image_url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "case": {
            "$ref": "#/components/schemas/Case"
          },
          "verdict": {
            "$ref": "#/components/schemas/Verdict"
          },
          "public_result": {
            "$ref": "#/components/schemas/PublicResult"
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Evidence"
            }
          },
          "disclosures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Disclosure"
            }
          },
          "adapter_runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AdapterRun"
            }
          },
          "variants": {
            "$ref": "#/components/schemas/Variants"
          },
          "receipt": {
            "$ref": "#/components/schemas/Receipt"
          },
          "cache": {
            "type": "object",
            "properties": {
              "hit": {
                "type": "boolean"
              },
              "matched_check_id": {
                "type": "string"
              }
            },
            "required": [
              "hit"
            ]
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "feedback": {
            "type": "object",
            "description": "Optional same-origin browser feedback ticket. Ordinary API calls work without this ticket or cookies.",
            "properties": {
              "ticket": {
                "type": "string"
              }
            },
            "required": [
              "ticket"
            ]
          }
        },
        "required": [
          "schema",
          "id",
          "created_at",
          "input",
          "case",
          "verdict",
          "evidence",
          "disclosures",
          "adapter_runs",
          "variants",
          "cache",
          "limitations"
        ]
      },
      "CheckError": {
        "type": "object",
        "properties": {
          "schema": {
            "type": "string",
            "enum": [
              "isgenai.error.v1"
            ]
          },
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "$ref": "#/components/schemas/CheckErrorCode"
              }
            },
            "required": [
              "message"
            ]
          }
        },
        "required": [
          "schema",
          "error"
        ],
        "description": "Handled check failure. The optional code field is additive for compatibility with historical message-only responses; current responses always include it. Known message text remains human-readable context, not a parsing contract. Unexpected failures are sanitized."
      },
      "BusyError": {
        "type": "object",
        "description": "Shared concurrency limiter response, without a schema field. Current responses include code=busy; code remains optional for compatibility with historical message-only responses.",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "enum": [
                  "busy"
                ]
              }
            },
            "required": [
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Health": {
        "type": "object",
        "description": "Liveness response only. This does not verify optional provider readiness or guarantee capacity for a check.",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "service": {
            "type": "string",
            "enum": [
              "isgenai"
            ]
          },
          "release": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-f0-9]{40}$",
            "description": "Deployment commit when a valid release identifier is configured; otherwise null."
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "ok",
          "service",
          "release",
          "generated_at"
        ]
      },
      "CheckErrorCode": {
        "type": "string",
        "description": "Stable machine-readable failure reason. Current responses include a code; tolerate absent codes in historical responses and use a generic failure fallback for unfamiliar future codes. A failure code is not an image-origin verdict.",
        "enum": [
          "missing_input",
          "invalid_json",
          "invalid_multipart",
          "invalid_request",
          "too_large",
          "text_too_long",
          "invalid_url",
          "blocked_url",
          "response_too_large",
          "redirect_failed",
          "url_uncheckable",
          "network_error",
          "busy",
          "tiff_invalid",
          "tiff_bigtiff",
          "tiff_directory",
          "tiff_multipage",
          "tiff_subimages",
          "tiff_decode",
          "check_failed"
        ]
      },
      "MultipartPromptInput": {
        "type": "object",
        "required": [
          "file"
        ],
        "description": "Upload one nonempty still image. Only file and mode are read from multipart requests; JSON-only URL/text/code inputs are not multipart alternatives. Full multipart body cap is 21,037,056 bytes including boundaries and fields.",
        "x-maxBodyBytes": 21037056,
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "minLength": 1,
            "x-maxSizeBytes": 20971520,
            "description": "Still PNG, JPEG, WebP or AVIF bytes; nonempty, at most 20,971,520 bytes (20 MiB), at most 40,000,000 decoded pixels, one page/frame. Invalid, unsupported or multipage images return HTTP 400 unsupported_image. File bytes are uploaded to isGenAI, not processed only in the browser."
          },
          "mode": {
            "type": "string",
            "enum": [
              "auto",
              "saved_only"
            ],
            "default": "auto",
            "description": "saved_only reads supported saved image records without a model call; no record returns HTTP 422. auto first reads image records, then may reconstruct a prompt when configured and within service limits. Reconstruction availability is not guaranteed."
          }
        }
      },
      "JsonPromptInput": {
        "type": "object",
        "description": "Send one image URL, text or code field. When several fields are strings, URL takes precedence, then code, then text. kind=code also marks a text-field input as code. JSON body cap: 131,072 bytes (128 KiB). saved_only requires an image URL; text/code require auto. An explicit null mode is treated as omitted/auto.",
        "x-maxBodyBytes": 131072,
        "anyOf": [
          {
            "required": [
              "url"
            ]
          },
          {
            "required": [
              "text"
            ]
          },
          {
            "required": [
              "code"
            ]
          }
        ],
        "properties": {
          "url": {
            "type": "string",
            "minLength": 1,
            "description": "Direct public HTTP(S) image URL. The fetched resource must have a successful image response and satisfy the same 20 MiB/still-image limits. Private network targets and unsafe requests are rejected; authentication, paywalls and CAPTCHAs are not bypassed."
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16000,
            "description": "Nonblank input, at most 16,000 UTF-16 code units including surrounding whitespace. Some Unicode characters use two units. Text/code support auto reconstruction only; saved_only returns HTTP 400 image_required."
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16000,
            "description": "Nonblank input, at most 16,000 UTF-16 code units including surrounding whitespace. Some Unicode characters use two units. Text/code support auto reconstruction only; saved_only returns HTTP 400 image_required."
          },
          "kind": {
            "type": "string",
            "enum": [
              "text",
              "code"
            ],
            "default": "text",
            "description": "Optional text/code hint. A string code field always selects code."
          },
          "expected_sha256": {
            "type": "string",
            "description": "Optional exact SHA-256 fingerprint for the downloaded URL image bytes. A nonempty value that does not match produces HTTP 409 content_changed. Applies only to JSON URL input; not read from multipart fields."
          },
          "mode": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "auto",
              "saved_only",
              null
            ],
            "default": "auto",
            "description": "saved_only reads supported saved image records without a model call; no record returns HTTP 422. auto first reads image records, then may reconstruct a prompt when configured and within service limits. Reconstruction availability is not guaranteed."
          }
        }
      },
      "SavedPromptSettings": {
        "type": "object",
        "additionalProperties": false,
        "description": "Only settings explicitly recovered from supported saved records. Absent values are omitted, not inferred. Seed is a string to preserve integer precision.",
        "properties": {
          "seed": {
            "type": "string",
            "pattern": "^-?\\d{1,20}$"
          },
          "steps": {
            "type": "integer",
            "minimum": 1
          },
          "sampler": {
            "type": "string",
            "maxLength": 200
          },
          "scheduler": {
            "type": "string",
            "maxLength": 200
          },
          "cfg_scale": {
            "type": "number"
          },
          "width": {
            "type": "integer",
            "minimum": 1
          },
          "height": {
            "type": "integer",
            "minimum": 1
          },
          "denoise": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        }
      },
      "SavedPromptResponse": {
        "type": "object",
        "required": [
          "schema",
          "status",
          "prompt",
          "note"
        ],
        "description": "Supported saved image records were found. No model reconstruction was called. Saved prompts, model labels and settings can be edited and do not authenticate origin. Keep returned content out of shared logs.",
        "properties": {
          "schema": {
            "type": "string",
            "const": "isgenai.prompt.v1"
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16000,
            "description": "Nonblank prompt text, at most 16,000 UTF-16 code units; not an AI-origin verdict."
          },
          "note": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "saved"
          },
          "negative_prompt": {
            "type": "string"
          },
          "recorded_model": {
            "type": "string",
            "description": "A model label found in the image record, not a verified model attribution."
          },
          "settings": {
            "$ref": "#/components/schemas/SavedPromptSettings"
          }
        },
        "additionalProperties": false
      },
      "ReconstructedPromptResponse": {
        "type": "object",
        "required": [
          "schema",
          "status",
          "prompt",
          "note"
        ],
        "description": "Conditional auto-mode result from a configured model. Describes a similar result, not the original prompt, creator, model, hidden settings or seed. Never returned for saved_only.",
        "properties": {
          "schema": {
            "type": "string",
            "const": "isgenai.prompt.v1"
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16000,
            "description": "Nonblank prompt text, at most 16,000 UTF-16 code units; not an AI-origin verdict."
          },
          "note": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "reconstructed"
          }
        },
        "additionalProperties": false
      },
      "PromptResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/SavedPromptResponse"
          },
          {
            "$ref": "#/components/schemas/ReconstructedPromptResponse"
          }
        ],
        "discriminator": {
          "propertyName": "status",
          "mapping": {
            "saved": "#/components/schemas/SavedPromptResponse",
            "reconstructed": "#/components/schemas/ReconstructedPromptResponse"
          }
        }
      },
      "PromptError": {
        "type": "object",
        "required": [
          "error"
        ],
        "description": "Prompt-route errors have no top-level schema field. Branch on HTTP status and error.code; error.message is human-readable context.",
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        },
        "additionalProperties": false
      },
      "NoSavedPromptError": {
        "type": "object",
        "required": [
          "error"
        ],
        "description": "Normal saved-only absence result. The endpoint returns an HTTP 422 error envelope, not a successful not_found status. The batch CLI translates this into its own not_found row.",
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "const": "no_saved_prompt"
              },
              "message": {
                "type": "string"
              }
            }
          }
        },
        "additionalProperties": false
      }
    }
  }
}
