{
  "openapi": "3.0.3",
  "info": {
    "title": "Sidearm API",
    "version": "1.10.0",
    "description": "Protect media against unauthorized AI training, detect AI-generated content, find stolen content, and verify provenance. Run individual algorithms like Nightshade, MetaCloak, SPECTRA, and C2PA directly, or use bundled protection levels. Accepts images (JPEG, PNG, WebP, TIFF), video (MP4, MOV, WebM), audio (MP3, WAV, FLAC, AAC), GIFs, raw text, and PDF.",
    "x-llms-txt": "/llms.txt"
  },
  "servers": [
    {
      "url": "https://api.sdrm.io",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "Algorithms",
      "description": "Browse available algorithms and run them individually on your media. Includes well-known research algorithms (Nightshade, MetaCloak, SPECTRA, C2PA) and proprietary sidearm protections."
    },
    {
      "name": "Media",
      "description": "Ingest, protect, and manage media assets"
    },
    {
      "name": "Presets",
      "description": "Named algorithm combinations for media ingestion"
    },
    {
      "name": "Detect",
      "description": "Fingerprint detection, AI content detection, and membership inference"
    },
    {
      "name": "Search",
      "description": "Tiered similarity search across registered media"
    },
    {
      "name": "Rights",
      "description": "Machine-readable rights discovery for media assets"
    },
    {
      "name": "Jobs",
      "description": "Async job status polling"
    },
    {
      "name": "Accounts",
      "description": "Account management"
    },
    {
      "name": "Tokens",
      "description": "API token management"
    },
    {
      "name": "Billing",
      "description": "Usage events and Stripe billing portal"
    },
    {
      "name": "Shares",
      "description": "Shareable result records with public Open Graph pages"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "Bearer token: Authorization: Bearer sk_live_..."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key header: X-API-Key: sk_live_..."
      }
    },
    "schemas": {
      "RightsResponse": {
        "type": "object",
        "properties": {
          "media_id": {
            "type": "string",
            "format": "uuid"
          },
          "media_type": {
            "type": "string"
          },
          "owner_id": {
            "type": "string",
            "format": "uuid"
          },
          "rights": {
            "type": "object",
            "properties": {
              "ai_training_allowed": {
                "type": "boolean"
              },
              "acquire_license_url": {
                "type": "string",
                "format": "uri"
              },
              "tdm_policy_url": {
                "type": "string",
                "format": "uri"
              },
              "verify_url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "protocols": {
            "type": "object",
            "properties": {
              "c2pa": {
                "type": "object",
                "properties": {
                  "training_mining": {
                    "type": "string"
                  },
                  "constraint_info": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "schema_org": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "acquireLicensePage": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "rsl": {
                "type": "object",
                "properties": {
                  "document_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "olp_token_endpoint": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "tdm": {
                "type": "object",
                "properties": {
                  "policy_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "reservation": {
                    "type": "integer"
                  }
                }
              },
              "iptc": {
                "type": "object",
                "properties": {
                  "licensor_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "web_statement": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Algorithm": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Algorithm identifier used in POST /api/v1/run",
            "example": "nightshade"
          },
          "name": {
            "type": "string",
            "example": "Nightshade 2.0"
          },
          "summary": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "open",
              "proprietary"
            ],
            "description": "open = individual algorithms by real name; proprietary = sidearm-branded bundles that resolve to open algorithms"
          },
          "media_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "image",
                "video",
                "audio",
                "gif",
                "text",
                "pdf"
              ]
            }
          },
          "technique": {
            "type": "string"
          },
          "gpu_required": {
            "type": "boolean"
          },
          "paper_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "runnable": {
            "type": "boolean",
            "description": "Whether this algorithm can be directly invoked via POST /api/v1/run."
          },
          "version": {
            "type": "string",
            "description": "Semantic version of this algorithm implementation (e.g., \"2.0.0\").",
            "example": "1.0.0"
          },
          "embedding_version": {
            "type": "string",
            "nullable": true,
            "description": "Version of the embedding model. Only present for extractable algorithms. Bump when the vector space changes.",
            "example": "1.0.0"
          },
          "embedding_dimension": {
            "type": "integer",
            "nullable": true,
            "description": "Dimension of vectors produced by this algorithm. Only present for extractable algorithms.",
            "example": 768
          },
          "embedding_metric": {
            "type": "string",
            "nullable": true,
            "enum": [
              "COSINE",
              "L2",
              "IP",
              "HAMMING"
            ],
            "description": "Similarity metric used for this algorithm's vectors. Only present for extractable algorithms."
          },
          "active_collection": {
            "type": "string",
            "nullable": true,
            "description": "Zilliz collection name where new vectors are indexed. Format: {slug}_v{major}. Only present for extractable algorithms.",
            "example": "dinov2_vectors_v1"
          },
          "searchable_collections": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "All collection names to query during search (current + legacy). Only present for extractable algorithms."
          }
        }
      },
      "Media": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "media_type": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio",
              "gif",
              "text",
              "pdf"
            ]
          },
          "manifest": {
            "type": "string"
          },
          "storage_url": {
            "type": "string",
            "format": "uri"
          },
          "original_storage_key": {
            "type": "string"
          },
          "preset": {
            "type": "string"
          },
          "algorithms_applied": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "processing"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Deletion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "media_id": {
            "type": "string",
            "format": "uuid"
          },
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "media_type": {
            "type": "string"
          },
          "original_hash": {
            "type": "string"
          },
          "preset": {
            "type": "string"
          },
          "algorithms_applied": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "storage_locations_purged": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "storage_purged": {
            "type": "boolean"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time"
          },
          "deleted_by": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "media_ingest",
              "ai_detect",
              "membership_inference"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "completed",
              "failed"
            ]
          },
          "preset": {
            "type": "string",
            "nullable": true
          },
          "progress": {
            "type": "object",
            "nullable": true,
            "properties": {
              "completed": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            }
          },
          "result": {
            "type": "object",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Preset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "system",
              "custom"
            ]
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "algorithms": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "media_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "stripe_customer_id": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Token": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "last_used_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ProvenanceProtectionStep": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "algorithm": {
            "type": "string",
            "example": "nightshade"
          },
          "algorithm_version": {
            "type": "string",
            "example": "2.0.1"
          },
          "applied_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_ms": {
            "type": "integer",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          }
        }
      },
      "ProvenanceSearchMatch": {
        "type": "object",
        "properties": {
          "search_id": {
            "type": "string",
            "format": "uuid"
          },
          "search_type": {
            "type": "string",
            "example": "quick"
          },
          "score": {
            "type": "number",
            "format": "float"
          },
          "rank": {
            "type": "integer"
          },
          "searched_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ProvenanceResult": {
        "type": "object",
        "properties": {
          "media": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "type": {
                "type": "string"
              },
              "account_id": {
                "type": "string",
                "format": "uuid"
              },
              "tags": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "is_public": {
                "type": "boolean"
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "c2pa_manifest": {
            "type": "string",
            "nullable": true,
            "description": "Raw C2PA manifest string."
          },
          "protection_chain": {
            "type": "array",
            "description": "Ordered list of every protection algorithm applied to this media, from first to most recent.",
            "items": {
              "$ref": "#/components/schemas/ProvenanceProtectionStep"
            }
          },
          "membership_inference": {
            "type": "array",
            "description": "Results of any AI training probes run against this media.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "searches_found_in": {
            "type": "array",
            "description": "Searches where this media appeared as a match.",
            "items": {
              "$ref": "#/components/schemas/ProvenanceSearchMatch"
            }
          }
        }
      },
      "C2paChainEntry": {
        "type": "object",
        "description": "One step in a C2PA provenance chain, ordered from origin to current.",
        "properties": {
          "generator": {
            "type": "string",
            "description": "Tool or device that created this step, e.g. \"Nikon Z7II\" or \"Adobe Photoshop/24.0\"."
          },
          "title": {
            "type": "string",
            "description": "Optional title from the manifest."
          },
          "actions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "C2PA action URIs, e.g. [\"c2pa.captured\"], [\"c2pa.edited\"]."
          }
        },
        "required": [
          "generator",
          "actions"
        ]
      },
      "IdentifyResult": {
        "type": "object",
        "description": "Result of fingerprint identification and C2PA extraction for a media URL.",
        "properties": {
          "media_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sidearm media ID if the asset is registered in the caller's account, otherwise null."
          },
          "c2pa_chain": {
            "type": "array",
            "description": "Ordered C2PA provenance chain embedded in the media, from origin to current. Empty if no C2PA manifest is present.",
            "items": {
              "$ref": "#/components/schemas/C2paChainEntry"
            }
          }
        },
        "required": [
          "media_id",
          "c2pa_chain"
        ]
      },
      "SharedResult": {
        "type": "object",
        "description": "A saved operation result that can optionally be made public via a share page.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique share record ID."
          },
          "action": {
            "type": "string",
            "enum": [
              "detect-ai",
              "search",
              "provenance"
            ],
            "description": "The operation that produced this result."
          },
          "media_url": {
            "type": "string",
            "nullable": true,
            "description": "Hot-linked source URL of the media. Null for locally-dropped files."
          },
          "media_type": {
            "type": "string",
            "nullable": true,
            "description": "Media type: image, video, audio, or text."
          },
          "result": {
            "type": "object",
            "description": "The full operation result payload (varies by action type)."
          },
          "is_public": {
            "type": "boolean",
            "description": "Whether this share record is publicly accessible."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "share_url": {
            "type": "string",
            "description": "Canonical URL for viewing this result (e.g. https://sdrm.io/share/{id})."
          }
        },
        "required": [
          "id",
          "action",
          "is_public",
          "result",
          "created_at",
          "share_url"
        ]
      }
    }
  },
  "paths": {
    "/api/v1/algorithms": {
      "get": {
        "tags": [
          "Algorithms"
        ],
        "summary": "List available algorithms",
        "operationId": "listAlgorithms",
        "security": [],
        "description": "Returns all algorithms available on sidearm. Open algorithms are individual algorithms by their real name (Nightshade, MetaCloak, SPECTRA, etc.). Proprietary algorithms are sidearm-branded bundles (Harmonic Bait, Style Cloaking, etc.) that resolve to open algorithms. Both are runnable via POST /api/v1/run.",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "proprietary"
              ]
            },
            "description": "Filter by category: 'open' for individual algorithms by real name, 'proprietary' for sidearm-branded bundles."
          },
          {
            "name": "media_type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "image",
                "video",
                "audio",
                "gif",
                "text",
                "pdf"
              ]
            },
            "description": "Filter algorithms that support this media type."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Algorithm"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "hint": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/run": {
      "post": {
        "tags": [
          "Algorithms"
        ],
        "summary": "Run specific algorithms on media",
        "operationId": "runAlgorithms",
        "description": "Choose exactly which algorithms to apply to your media. Unlike POST /api/v1/protect (which uses bundled protection levels), this endpoint gives you full control. Algorithms execute sequentially in the order provided. By default, output is wrapped in C2PA provenance signing. Returns 202 with a job ID for polling.\n\nExample: apply Nightshade to an image:\n```json\n{\"algorithms\": [\"nightshade\"], \"media_url\": \"https://example.com/photo.jpg\"}\n```\n\nExample: apply MetaCloak + PAI hardening:\n```json\n{\"algorithms\": [\"metacloak\", \"pai\"], \"media_url\": \"https://example.com/art.png\"}\n```\n\nExample: watermark text with SPECTRA:\n```json\n{\"algorithms\": [\"spectra\"], \"text\": \"My copyrighted article...\"}\n```",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "algorithms"
                ],
                "properties": {
                  "algorithms": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Algorithm IDs to run, in order. See GET /api/v1/algorithms for available IDs.",
                    "example": [
                      "nightshade"
                    ]
                  },
                  "media_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public URL of media to process. Provide one of media_url, media, or text."
                  },
                  "media": {
                    "type": "string",
                    "format": "byte",
                    "description": "Base64-encoded file bytes."
                  },
                  "text": {
                    "type": "string",
                    "description": "Raw text content (for text/PDF algorithms)."
                  },
                  "mime": {
                    "type": "string",
                    "description": "MIME type hint (optional, auto-detected)."
                  },
                  "c2pa_wrap": {
                    "type": "boolean",
                    "default": true,
                    "description": "Wrap output in C2PA provenance signing (pre + post)."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "default": [],
                    "description": "Tags for billing attribution and access control."
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL to POST callback when processing completes."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "example": "queued"
                        },
                        "algorithms": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "status_url": {
                          "type": "string",
                          "example": "/api/v1/jobs/{job_id}"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (unknown algorithm, incompatible media type)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/embed": {
      "post": {
        "tags": [
          "Algorithms"
        ],
        "summary": "Extract raw embedding vectors from media",
        "operationId": "extractEmbeddings",
        "description": "Extract raw feature vectors from media using named embedding and fingerprinting algorithms. Unlike POST /api/v1/run (which transforms media and returns a modified file), this endpoint returns the raw numeric vectors for use in similarity search, clustering, or ML pipelines.\n\nExample: extract DINOv2 + CLIP vectors from an image:\n```json\n{\"algorithms\": [\"dinov2\", \"clip\"], \"media_url\": \"https://example.com/photo.jpg\"}\n```\n\nExample: extract Chromaprint + CLAP vectors from audio:\n```json\n{\"algorithms\": [\"chromaprint\", \"clap\"], \"media_url\": \"https://example.com/song.mp3\"}\n```\n\nThe completed job result contains an `embeddings` array with `{ algorithm, vector, dimension, metric }` entries.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "algorithms"
                ],
                "properties": {
                  "algorithms": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Extractable algorithm IDs (e.g. phash, dinov2, clip, scene-graph, chromaprint, clap, audio-structure, sentence-transformers). See GET /api/v1/algorithms.",
                    "example": [
                      "dinov2",
                      "clip"
                    ]
                  },
                  "media_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public URL of media to process. Provide one of media_url, media, or text."
                  },
                  "media": {
                    "type": "string",
                    "format": "byte",
                    "description": "Base64-encoded file bytes."
                  },
                  "text": {
                    "type": "string",
                    "description": "Raw text content (for sentence-transformers)."
                  },
                  "mime": {
                    "type": "string",
                    "description": "MIME type hint (optional, auto-detected)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted \u2014 job queued for embedding extraction",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "example": "queued"
                        },
                        "algorithms": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "status_url": {
                          "type": "string",
                          "example": "/api/v1/jobs/{job_id}"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (unknown algorithm, non-extractable algorithm, incompatible media type)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/protect": {
      "post": {
        "tags": [
          "Algorithms"
        ],
        "summary": "Bundled media protection",
        "operationId": "protectMedia",
        "description": "Apply a curated pipeline of protection algorithms based on protection level. For full control over which algorithms run, use POST /api/v1/run instead.\n\nStandard (images): C2PA \u2192 HMark \u2192 Nightshade \u2192 IPTC \u2192 C2PA\nMaximum (images): C2PA \u2192 HMark \u2192 Nightshade \u2192 MetaCloak \u2192 PAI \u2192 IPTC \u2192 C2PA",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "media_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "media": {
                    "type": "string",
                    "format": "byte"
                  },
                  "text": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "level": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "maximum"
                    ],
                    "default": "standard"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "default": []
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "status_url": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media": {
      "post": {
        "tags": [
          "Media"
        ],
        "summary": "Ingest & protect media",
        "operationId": "createMedia",
        "description": "Submit media to register, fingerprint, and protect in one call. The preset parameter controls which algorithms run. Returns 202 with a job ID.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "media_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public URL of media. Provide one of media_url, media, or text."
                  },
                  "media": {
                    "type": "string",
                    "format": "byte",
                    "description": "Base64-encoded file bytes. Type is auto-detected."
                  },
                  "text": {
                    "type": "string",
                    "description": "Raw text content."
                  },
                  "preset": {
                    "type": "string",
                    "default": "standard",
                    "enum": [
                      "register",
                      "search_ready",
                      "standard",
                      "maximum"
                    ],
                    "description": "Preset controlling which algorithms are applied."
                  },
                  "mode": {
                    "type": "string",
                    "default": "standard",
                    "enum": [
                      "register",
                      "search_ready",
                      "standard",
                      "maximum"
                    ],
                    "description": "Alias for preset. Controls which algorithms are applied."
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Record and storage permanently deleted at this time. Defaults to 1 year from now."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "default": []
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Arbitrary key-value pairs stored with the record."
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL to receive POST callback when processing completes."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "preset": {
                          "type": "string"
                        },
                        "status_url": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Media"
        ],
        "summary": "List media",
        "operationId": "listMedia",
        "description": "List registered media for the authenticated account. Scope: media:read.",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Media"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "next_cursor": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media/{id}": {
      "get": {
        "tags": [
          "Media"
        ],
        "summary": "Get media",
        "operationId": "getMedia",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Media"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Media"
        ],
        "summary": "Update media",
        "operationId": "updateMedia",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "original_media_url"
                ],
                "properties": {
                  "original_media_url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Media"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Media"
        ],
        "summary": "Delete media",
        "operationId": "deleteMedia",
        "description": "Delete media and all storage. Returns a deletion record ID for compliance.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean"
                        },
                        "deletion_id": {
                          "type": "string"
                        },
                        "media_id": {
                          "type": "string"
                        },
                        "deleted_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media/deletions": {
      "get": {
        "tags": [
          "Media"
        ],
        "summary": "List deletion records",
        "operationId": "listDeletions",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Deletion"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "next_cursor": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media/deletions/{id}": {
      "get": {
        "tags": [
          "Media"
        ],
        "summary": "Get deletion record",
        "operationId": "getDeletion",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Deletion"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media/deletions/{id}/certificate": {
      "get": {
        "tags": [
          "Media"
        ],
        "summary": "Download deletion certificate",
        "operationId": "getDeletionCertificate",
        "description": "Signed legal certificate proving permanent deletion. Available as JWT or PDF.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "jwt",
                "pdf"
              ],
              "default": "jwt"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "deletion_id": {
                          "type": "string"
                        },
                        "format": {
                          "type": "string"
                        },
                        "certificate": {
                          "type": "string"
                        },
                        "verify_url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "issued_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/presets": {
      "get": {
        "tags": [
          "Presets"
        ],
        "summary": "List presets",
        "operationId": "listPresets",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Preset"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Presets"
        ],
        "summary": "Create custom preset",
        "operationId": "createPreset",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "algorithms"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "algorithms": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Algorithm codes (e.g. harmonic-bait-latest, style-cloak-v1)."
                  },
                  "media_types": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "image",
                        "video",
                        "audio",
                        "gif",
                        "text",
                        "pdf"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Preset"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/presets/{id}": {
      "get": {
        "tags": [
          "Presets"
        ],
        "summary": "Get preset",
        "operationId": "getPreset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Preset"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Presets"
        ],
        "summary": "Delete custom preset",
        "operationId": "deletePreset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/detect": {
      "post": {
        "tags": [
          "Detect"
        ],
        "summary": "Detect fingerprinted media",
        "operationId": "detect",
        "description": "Check whether submitted media matches your registered corpus. The tier parameter controls forensic depth.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "media_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "media": {
                    "type": "string",
                    "format": "byte"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "exact",
                      "quick",
                      "perceptual",
                      "compositional",
                      "full"
                    ],
                    "default": "quick"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "has_signal": {
                          "type": "boolean"
                        },
                        "confidence": {
                          "type": "number"
                        },
                        "matched_manifests": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "detection_method": {
                          "type": "string"
                        },
                        "tier": {
                          "type": "string"
                        },
                        "corpus_similarity": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/detect/ai": {
      "post": {
        "tags": [
          "Detect"
        ],
        "summary": "Detect AI-generated content",
        "operationId": "detectAi",
        "description": "Determine whether media was generated by an AI model. Routes to specialized detectors by media type. Returns 202 with a job ID.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "media_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "media": {
                    "type": "string",
                    "format": "byte"
                  },
                  "text": {
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "media_type": {
                          "type": "string"
                        },
                        "status_url": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/detect/membership": {
      "post": {
        "tags": [
          "Detect"
        ],
        "summary": "Membership inference",
        "operationId": "detectMembership",
        "description": "Determine if a suspect model was trained on your protected content. Submit one or many registered media IDs. Returns 202.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "content_ids",
                  "suspect_model"
                ],
                "properties": {
                  "content_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "IDs of registered media to check against."
                  },
                  "suspect_model": {
                    "type": "string",
                    "description": "Model identifier to audit."
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "pattern",
                      "statistical",
                      "combined"
                    ],
                    "default": "combined"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "method": {
                          "type": "string"
                        },
                        "content_ids_count": {
                          "type": "integer"
                        },
                        "suspect_model": {
                          "type": "string"
                        },
                        "status_url": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search": {
      "post": {
        "tags": [
          "Search"
        ],
        "summary": "Search by media",
        "operationId": "createSearch",
        "description": "Find similar registered media. The type parameter controls search tier depth.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "media_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "media": {
                    "type": "string",
                    "format": "byte"
                  },
                  "scope": {
                    "type": "object",
                    "properties": {
                      "tags": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "exact",
                      "quick",
                      "perceptual",
                      "compositional",
                      "full"
                    ],
                    "default": "perceptual"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "search_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "matches": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "media_id": {
                                "type": "string"
                              },
                              "score": {
                                "type": "number"
                              },
                              "storage_url": {
                                "type": "string"
                              },
                              "tags": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Search"
        ],
        "summary": "List searches",
        "operationId": "listSearches",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/search/{id}": {
      "get": {
        "tags": [
          "Search"
        ],
        "summary": "Get search by ID",
        "operationId": "getSearch",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/rights/{mediaId}": {
      "get": {
        "tags": [
          "Rights"
        ],
        "summary": "Get rights info for media",
        "operationId": "getRights",
        "description": "Public rights discovery endpoint. Returns machine-readable licensing information including C2PA, Schema.org, IPTC, TDM, and RSL protocol data. No authentication required. Supports content negotiation: application/json (default), application/ld+json (Schema.org JSON-LD), application/xml (RSL document).",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rights information for the media asset",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/RightsResponse"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Media not found"
          }
        }
      }
    },
    "/api/v1/jobs/{id}": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "Poll job status",
        "operationId": "getJob",
        "description": "Check status and progress of an async job.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Job"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/accounts/{id}": {
      "get": {
        "tags": [
          "Accounts"
        ],
        "summary": "Get account",
        "operationId": "getAccount",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Account"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Accounts"
        ],
        "summary": "Update account",
        "operationId": "updateAccount",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Account"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Accounts"
        ],
        "summary": "Delete account",
        "operationId": "deleteAccount",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/tokens": {
      "post": {
        "tags": [
          "Tokens"
        ],
        "summary": "Create API token",
        "operationId": "createToken",
        "description": "Create a token with specific scopes. The secret is returned only in this response.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "scopes"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "resource:action scopes."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created \u2014 token secret included",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string",
                          "description": "The secret. Shown only once."
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "expires_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Tokens"
        ],
        "summary": "List tokens",
        "operationId": "listTokens",
        "description": "List all API tokens. Secrets are never returned.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Token"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tokens/{id}": {
      "get": {
        "tags": [
          "Tokens"
        ],
        "summary": "Get token",
        "operationId": "getToken",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Token"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Tokens"
        ],
        "summary": "Update token",
        "operationId": "updateToken",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "delete": {
        "tags": [
          "Tokens"
        ],
        "summary": "Revoke token",
        "operationId": "revokeToken",
        "description": "Permanently revoke a token. Requests using it will immediately receive 401.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/billing/{account_id}": {
      "get": {
        "tags": [
          "Billing"
        ],
        "summary": "Get billing summary, storage stats, algorithm breakdown, and events",
        "operationId": "getBilling",
        "parameters": [
          {
            "name": "account_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "start_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filter events from this date (inclusive)."
          },
          {
            "name": "end_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filter events until this date (inclusive)."
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by event type (e.g. protect:harmonic-bait:v1, storage:daily)."
          },
          {
            "name": "tags",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated tag filter."
          },
          {
            "name": "token_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter events to a specific API token."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "object",
                          "properties": {
                            "credit_balance": {
                              "type": "number",
                              "description": "Current credit balance."
                            },
                            "total_credits_used": {
                              "type": "number",
                              "description": "Total credits consumed in the filtered period."
                            },
                            "protection_credits": {
                              "type": "number",
                              "description": "Credits used for protection operations."
                            },
                            "storage_credits": {
                              "type": "number",
                              "description": "Credits used for daily storage charges."
                            }
                          }
                        },
                        "storage": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "total_bytes": {
                              "type": "integer",
                              "description": "Total bytes of active protected media."
                            },
                            "file_count": {
                              "type": "integer",
                              "description": "Number of active protected files."
                            },
                            "daily_cost": {
                              "type": "integer",
                              "description": "Estimated daily storage cost in credits."
                            },
                            "weekly_cost": {
                              "type": "integer",
                              "description": "Estimated weekly storage cost in credits."
                            },
                            "monthly_cost": {
                              "type": "integer",
                              "description": "Estimated monthly storage cost in credits."
                            },
                            "rate_per_mb_per_day": {
                              "type": "number",
                              "description": "Credit rate per MB per day."
                            }
                          }
                        },
                        "by_algorithm": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "algorithm": {
                                "type": "string"
                              },
                              "display_name": {
                                "type": "string"
                              },
                              "operations": {
                                "type": "integer"
                              },
                              "credits": {
                                "type": "number"
                              }
                            }
                          }
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "quantity": {
                                "type": "number"
                              },
                              "unit": {
                                "type": "string"
                              },
                              "tag": {
                                "type": "string",
                                "nullable": true
                              },
                              "api_token_id": {
                                "type": "string",
                                "nullable": true
                              },
                              "metadata": {
                                "type": "object",
                                "nullable": true
                              },
                              "created_at": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "portal_url": {
                          "type": "string",
                          "format": "uri",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media/identify": {
      "post": {
        "tags": [
          "Media",
          "Detect"
        ],
        "summary": "Identify media by fingerprint and C2PA",
        "description": "Reads the Sidearm stegano fingerprint embedded in a media asset and looks it up against your library. Also extracts the full C2PA provenance chain (e.g. Nikon \u2192 Photoshop \u2192 Sidearm) from the file's metadata, regardless of registration status. Use this to answer \"have I seen this before?\" and \"where did this come from?\" in a single call.",
        "operationId": "identifyMedia",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "media_url"
                ],
                "properties": {
                  "media_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Publicly accessible URL of the media to identify."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/IdentifyResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request \u2014 missing or invalid media_url"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden \u2014 token lacks read or detect scope"
          },
          "422": {
            "description": "Unprocessable \u2014 media could not be fetched or parsed"
          }
        },
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/v1/media/{id}/provenance": {
      "get": {
        "tags": [
          "Media"
        ],
        "summary": "Get media provenance",
        "description": "Returns the full provenance chain for a media asset: every protection algorithm applied (with versions, timings, and metadata), C2PA manifest, AI training membership inference results, and every search where this media was found as a match. Use this to audit the complete history of what has been done to any media item.",
        "operationId": "getMediaProvenance",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Media asset ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ProvenanceResult"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden \u2014 token lacks read scope or asset belongs to another account"
          },
          "404": {
            "description": "Media not found"
          }
        },
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/v1/shares": {
      "post": {
        "operationId": "createShare",
        "summary": "Save an operation result as a share record",
        "description": "Persists a detection, search, or provenance result server-side. The record is private by default. Use PATCH /api/v1/shares/{id} to make it public.",
        "tags": [
          "Shares"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "detect-ai",
                      "search",
                      "provenance"
                    ],
                    "description": "The operation type."
                  },
                  "result": {
                    "type": "object",
                    "description": "Full operation result payload."
                  },
                  "media_url": {
                    "type": "string",
                    "description": "Hot-linked source URL of the media (omit for local file drops)."
                  },
                  "media_type": {
                    "type": "string",
                    "description": "Media type: image, video, audio, or text."
                  }
                },
                "required": [
                  "action",
                  "result"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Share record created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SharedResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          }
        ]
      }
    },
    "/api/v1/shares/{id}": {
      "get": {
        "operationId": "getShare",
        "summary": "Get a share record",
        "description": "Returns a share record. Public records require no authentication. Private records require auth and ownership.",
        "tags": [
          "Shares"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Share record ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SharedResult"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized (private record)"
          },
          "403": {
            "description": "Forbidden \u2014 record belongs to another account"
          },
          "404": {
            "description": "Share not found"
          }
        }
      },
      "patch": {
        "operationId": "publishShare",
        "summary": "Make a share record public",
        "description": "Sets is_public to true on the record, enabling the public share page. Auth and ownership are required.",
        "tags": [
          "Shares"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Share record ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "is_public": {
                    "type": "boolean",
                    "enum": [
                      true
                    ],
                    "description": "Must be true \u2014 the only supported operation."
                  }
                },
                "required": [
                  "is_public"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Share record updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SharedResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden \u2014 record belongs to another account"
          },
          "404": {
            "description": "Share not found"
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          }
        ]
      }
    }
  }
}