{
  "openapi": "3.1.0",
  "info": {
    "title": "CreatorSense Trace API",
    "summary": "Marked copies, leak checks and usage for your Trace account.",
    "description": "The public Trace API. Use it to connect your own tools to Trace: list and add\nfans, upload a master and request one marked copy per fan, download copies,\nsubmit a leak and read the case, and read your plan and usage.\n\nAuthenticate with an API key from Settings -> API keys in the app, sent as\n`Authorization: Bearer cs_live_...` (or `X-API-Key: cs_live_...`). Keys have\nscopes: `trace:read` and `trace:write`. Each key may make 120 requests a\nminute; every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`\nand `X-RateLimit-Reset`.\n\nMarked copies made through the API count toward your plan exactly like copies\nmade in the app. Leak checks are not counted as copies. There are no webhooks:\nlong-running work returns a job or case id to poll.\n\nA match shows which delivered copy a leaked file came from. It does not prove\nwho shared it. A \"no_mark_found\" result is inconclusive.\n\nGuide: https://www.creatorsenseai.com/api.html\n",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.creatorsenseai.com",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/trace/v1/fans": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "List fans",
        "description": "Every active fan on the account, with the mark ID their copies carry.",
        "operationId": "listFans",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FanListOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      },
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Add a fan",
        "description": "Add one fan. A mark ID is assigned automatically. Plan fan limits apply.",
        "operationId": "createFan",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FanCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FanOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/trace/v1/fans/import": {
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Import fans",
        "description": "Add many fans at once (deduplicated; existing names are skipped, not duplicated).",
        "operationId": "importFans",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FanImportIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FanImportOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/trace/v1/uploads": {
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Get an upload URL",
        "description": "A short-lived URL to PUT a master or leak file to. Use the object_key afterwards.",
        "operationId": "createUpload",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/trace/v1/masters": {
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Prepare a master",
        "description": "Start preparing an uploaded master. Poll the job; request copies once it succeeds.\n\nPreparing a master does not use marked copies; each copy you request does.",
        "operationId": "createMaster",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MasterCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MasterJobOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/trace/v1/masters/{master_id}": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Get a master",
        "operationId": "getMaster",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "master_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Master Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MasterOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trace/v1/masters/{master_id}/copies": {
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Request marked copies",
        "description": "One marked copy per fan, from a ready master. Each copy counts as one marked copy.\n\nFiles are built on first download, so this returns quickly; then GET each\ncopy's ``download_url``.",
        "operationId": "createCopies",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "master_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Master Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopiesCreateIn"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyListOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "List copies of a master",
        "operationId": "listCopies",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "master_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Master Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyListOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trace/v1/copies/{copy_id}/download": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Get a copy's download URL",
        "description": "A short-lived signed URL for the copy's file. The first call builds the file.",
        "operationId": "downloadCopy",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "copy_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Copy Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyDownloadOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trace/v1/jobs/{job_id}": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Poll a job",
        "operationId": "getJob",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trace/v1/leaks": {
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Submit a leak",
        "description": "Check a leak by URL, or by a file uploaded with POST /uploads (purpose ``leak``).\n\nReturns the case to poll. Leak checks do not use marked copies.",
        "operationId": "submitLeak",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeakIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeakOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/trace/v1/leaks/upload": {
      "post": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Submit a leak file",
        "description": "Upload a leaked file directly (multipart). Large files: use POST /uploads then /leaks.",
        "operationId": "uploadLeak",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_uploadLeak"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeakOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/trace/v1/cases": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "List cases",
        "operationId": "listCases",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0,
              "title": "Offset"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseListOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trace/v1/cases/{case_id}": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Get a case",
        "operationId": "getCase",
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "title": "Case Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trace/v1/usage": {
      "get": {
        "tags": [
          "Trace API v1"
        ],
        "summary": "Plan and usage",
        "description": "This month's marked copies: allowance, used, pack balance and overage.",
        "operationId": "getUsage",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks the scope, or resource is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit for this key reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyBearer": []
          },
          {
            "ApiKeyHeader": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "Body_uploadLeak": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The leaked file (small files; use /uploads for large)."
          },
          "master_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Master Id"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_uploadLeak"
      },
      "CaseListOut": {
        "properties": {
          "cases": {
            "items": {
              "$ref": "#/components/schemas/CaseOut"
            },
            "type": "array",
            "title": "Cases"
          },
          "limit": {
            "type": "integer",
            "title": "Limit"
          },
          "offset": {
            "type": "integer",
            "title": "Offset"
          }
        },
        "type": "object",
        "required": [
          "cases",
          "limit",
          "offset"
        ],
        "title": "CaseListOut"
      },
      "CaseOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "status": {
            "type": "string",
            "title": "Status",
            "examples": [
              "done"
            ]
          },
          "verdict": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Verdict",
            "description": "matched | no_mark_found | tampered_inconclusive | ambiguous_multiple, or null while still checking. no_mark_found is inconclusive, not a clearance."
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary"
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url"
          },
          "master_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Master Id"
          },
          "match": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MatchOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "attribution_locked": {
            "type": "boolean",
            "title": "Attribution Locked",
            "description": "True when the plan's monthly match limit holds back the matched copy.",
            "default": false
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "status"
        ],
        "title": "CaseOut"
      },
      "CopiesCreateIn": {
        "properties": {
          "fan_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 1000,
            "minItems": 1,
            "title": "Fan Ids",
            "description": "Fan IDs from GET /fans. One marked copy is made (and counted) per fan."
          }
        },
        "type": "object",
        "required": [
          "fan_ids"
        ],
        "title": "CopiesCreateIn"
      },
      "CopyDownloadOut": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url",
            "description": "Signed URL for the MP4. Short-lived."
          },
          "expires_in": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires In",
            "description": "Seconds until the URL stops working."
          }
        },
        "type": "object",
        "required": [
          "url"
        ],
        "title": "CopyDownloadOut"
      },
      "CopyListOut": {
        "properties": {
          "copies": {
            "items": {
              "$ref": "#/components/schemas/CopyOut"
            },
            "type": "array",
            "title": "Copies"
          },
          "count": {
            "type": "integer",
            "title": "Count"
          }
        },
        "type": "object",
        "required": [
          "copies",
          "count"
        ],
        "title": "CopyListOut"
      },
      "CopyOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "master_id": {
            "type": "string",
            "title": "Master Id"
          },
          "fan_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fan Id"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "ready": {
            "type": "boolean",
            "title": "Ready",
            "description": "False until the file is first built (on first download)."
          },
          "download_url": {
            "type": "string",
            "title": "Download Url",
            "description": "GET this (with your key) for a signed file URL."
          }
        },
        "type": "object",
        "required": [
          "id",
          "master_id",
          "ready",
          "download_url"
        ],
        "title": "CopyOut"
      },
      "CopyUsageOut": {
        "properties": {
          "allowance": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowance",
            "description": "Marked copies included this month. null = not metered."
          },
          "used": {
            "type": "integer",
            "title": "Used",
            "description": "Marked copies made this month (app and API together)."
          },
          "included_left": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Included Left"
          },
          "pack_balance": {
            "type": "integer",
            "title": "Pack Balance",
            "description": "Prepaid copy-pack credits left.",
            "default": 0
          },
          "pack_used_this_month": {
            "type": "integer",
            "title": "Pack Used This Month",
            "default": 0
          },
          "overage_this_month": {
            "type": "integer",
            "title": "Overage This Month",
            "default": 0
          },
          "overage_rate_cents": {
            "type": "integer",
            "title": "Overage Rate Cents",
            "default": 0
          },
          "overage_ceiling": {
            "type": "integer",
            "title": "Overage Ceiling",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "used"
        ],
        "title": "CopyUsageOut"
      },
      "ErrorDetail": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "examples": [
              "API_KEY_REVOKED"
            ]
          },
          "message": {
            "type": "string",
            "title": "Message",
            "examples": [
              "This API key was revoked. Make a new key in Settings."
            ]
          },
          "status": {
            "type": "integer",
            "title": "Status",
            "examples": [
              401
            ]
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "code",
          "message",
          "status"
        ],
        "title": "ErrorDetail"
      },
      "ErrorOut": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "type": "object",
        "required": [
          "error"
        ],
        "title": "ErrorOut"
      },
      "FanCreateIn": {
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "Label",
            "examples": [
              "@bella_fan"
            ]
          },
          "display_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "platform": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "title": "Platform",
            "examples": [
              "onlyfans"
            ]
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          }
        },
        "type": "object",
        "required": [
          "label"
        ],
        "title": "FanCreateIn"
      },
      "FanImportIn": {
        "properties": {
          "labels": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 200,
            "title": "Labels",
            "examples": [
              [
                "@bella_fan",
                "@mike_22"
              ]
            ]
          },
          "text": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100000
              },
              {
                "type": "null"
              }
            ],
            "title": "Text",
            "description": "Or paste names / a CSV of handles, one per line."
          }
        },
        "type": "object",
        "title": "FanImportIn"
      },
      "FanImportOut": {
        "properties": {
          "created": {
            "items": {
              "$ref": "#/components/schemas/FanOut"
            },
            "type": "array",
            "title": "Created"
          },
          "skipped": {
            "items": {
              "$ref": "#/components/schemas/FanImportSkip"
            },
            "type": "array",
            "title": "Skipped"
          },
          "created_count": {
            "type": "integer",
            "title": "Created Count"
          },
          "skipped_count": {
            "type": "integer",
            "title": "Skipped Count"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message"
          }
        },
        "type": "object",
        "required": [
          "created",
          "skipped",
          "created_count",
          "skipped_count"
        ],
        "title": "FanImportOut"
      },
      "FanImportSkip": {
        "properties": {
          "label": {
            "type": "string",
            "title": "Label"
          },
          "reason": {
            "type": "string",
            "title": "Reason"
          }
        },
        "type": "object",
        "required": [
          "label",
          "reason"
        ],
        "title": "FanImportSkip"
      },
      "FanListOut": {
        "properties": {
          "fans": {
            "items": {
              "$ref": "#/components/schemas/FanOut"
            },
            "type": "array",
            "title": "Fans"
          },
          "count": {
            "type": "integer",
            "title": "Count"
          }
        },
        "type": "object",
        "required": [
          "fans",
          "count"
        ],
        "title": "FanListOut"
      },
      "FanOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label",
            "description": "Your name for the fan, e.g. their platform handle."
          },
          "display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "platform": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Platform"
          },
          "watermark_id": {
            "type": "integer",
            "title": "Watermark Id",
            "description": "The mark ID carried by this fan's copies."
          },
          "tier": {
            "type": "string",
            "title": "Tier",
            "default": "standard"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "watermark_id"
        ],
        "title": "FanOut"
      },
      "JobOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "encode | leak_fetch | leak_check"
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "queued | running | succeeded | failed"
          },
          "master_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Master Id"
          },
          "case_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Case Id"
          },
          "next_job_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Job Id",
            "description": "For leak_fetch: the leak_check job it started, once known."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "type",
          "status"
        ],
        "title": "JobOut"
      },
      "LeakIn": {
        "properties": {
          "url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2083,
                "minLength": 1,
                "format": "uri"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "A page or file URL where the leak is posted."
          },
          "object_key": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 512,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Key",
            "description": "Or a file uploaded via POST /uploads."
          },
          "master_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Master Id",
            "description": "Optional: the master you think it came from."
          }
        },
        "type": "object",
        "title": "LeakIn"
      },
      "LeakOut": {
        "properties": {
          "case_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Case Id"
          },
          "job_id": {
            "type": "string",
            "title": "Job Id"
          },
          "status": {
            "type": "string",
            "title": "Status"
          }
        },
        "type": "object",
        "required": [
          "case_id",
          "job_id",
          "status"
        ],
        "title": "LeakOut"
      },
      "MasterCreateIn": {
        "properties": {
          "object_key": {
            "type": "string",
            "maxLength": 512,
            "minLength": 3,
            "title": "Object Key"
          },
          "title": {
            "type": "string",
            "maxLength": 512,
            "title": "Title",
            "default": "",
            "examples": [
              "March drop"
            ]
          }
        },
        "type": "object",
        "required": [
          "object_key"
        ],
        "title": "MasterCreateIn"
      },
      "MasterJobOut": {
        "properties": {
          "master_id": {
            "type": "string",
            "title": "Master Id"
          },
          "job_id": {
            "type": "string",
            "title": "Job Id"
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Master status: pending until the job succeeds, then ready."
          }
        },
        "type": "object",
        "required": [
          "master_id",
          "job_id",
          "status"
        ],
        "title": "MasterJobOut"
      },
      "MasterOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          },
          "status": {
            "type": "string",
            "title": "Status",
            "examples": [
              "ready"
            ]
          },
          "media_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Media Kind"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "status"
        ],
        "title": "MasterOut"
      },
      "MatchOut": {
        "properties": {
          "watermark_id": {
            "type": "integer",
            "title": "Watermark Id"
          },
          "fan_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fan Id"
          },
          "fan_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fan Label"
          },
          "statement": {
            "type": "string",
            "title": "Statement",
            "description": "What the match shows. It shows which copy leaked, not who shared it."
          }
        },
        "type": "object",
        "required": [
          "watermark_id",
          "statement"
        ],
        "title": "MatchOut",
        "description": "Present only when Trace matched the file to one delivered copy."
      },
      "UploadIn": {
        "properties": {
          "purpose": {
            "type": "string",
            "enum": [
              "master",
              "leak"
            ],
            "title": "Purpose",
            "description": "master: a file to make copies from. leak: a file to check.",
            "default": "master"
          },
          "filename": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "title": "Filename",
            "examples": [
              "march-drop.mp4"
            ]
          },
          "content_type": {
            "type": "string",
            "maxLength": 128,
            "title": "Content Type",
            "default": "video/mp4"
          }
        },
        "type": "object",
        "required": [
          "filename"
        ],
        "title": "UploadIn"
      },
      "UploadOut": {
        "properties": {
          "object_key": {
            "type": "string",
            "title": "Object Key",
            "description": "Pass this to POST /masters or POST /leaks."
          },
          "upload_url": {
            "type": "string",
            "title": "Upload Url",
            "description": "PUT the file body here."
          },
          "method": {
            "type": "string",
            "title": "Method",
            "default": "PUT"
          },
          "headers": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Headers",
            "description": "Send these headers on the PUT."
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          },
          "max_size": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Size"
          }
        },
        "type": "object",
        "required": [
          "object_key",
          "upload_url"
        ],
        "title": "UploadOut"
      },
      "UsageOut": {
        "properties": {
          "plan": {
            "type": "string",
            "title": "Plan"
          },
          "tier": {
            "type": "string",
            "title": "Tier"
          },
          "pricing_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pricing Version"
          },
          "band": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Band",
            "description": "Plan on pricing v3: starter | growth | pro | elite. null otherwise."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Metering month, UTC (YYYY-MM)."
          },
          "copies": {
            "$ref": "#/components/schemas/CopyUsageOut"
          },
          "leak_checks": {
            "type": "string",
            "title": "Leak Checks",
            "description": "Leak checks are not counted as copies.",
            "default": "not metered"
          }
        },
        "type": "object",
        "required": [
          "plan",
          "tier",
          "period",
          "copies"
        ],
        "title": "UsageOut"
      }
    },
    "securitySchemes": {
      "ApiKeyBearer": {
        "type": "http",
        "description": "Authorization: Bearer cs_live_... (preferred)",
        "scheme": "bearer"
      },
      "ApiKeyHeader": {
        "type": "apiKey",
        "description": "X-API-Key: cs_live_... (alternative)",
        "in": "header",
        "name": "X-API-Key"
      }
    }
  },
  "tags": [
    {
      "name": "Trace API v1",
      "description": "API-key authenticated. See api.html."
    }
  ],
  "externalDocs": {
    "description": "Trace API guide",
    "url": "https://www.creatorsenseai.com/api.html"
  }
}
